Skip to content

Commit

Permalink
Align our strConvEncOpts with MRI's.
Browse files Browse the repository at this point in the history
When there's an error from encoding, MRI's version of this
function just returns the incoming bytes as its result. Ours used
a path that always raises an error when transcoding fails. The new
version uses a path more in line with MRI that requires an out
buffer and returns a result, so we can handle it appropriately.

Fixes #2419.
headius committed Jan 4, 2015
1 parent c74647f commit ff54579
Showing 2 changed files with 28 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -235,7 +235,21 @@ public RubyCoderResult transcode(ThreadContext context, ByteList value, ByteList

return transcode(context, value, dest, fromEncoding, false, true);
}


public RubyCoderResult econvConvert(ThreadContext context, ByteList inBuffer, ByteList outBuffer) {
Encoding fromEncoding = this.inEncoding != null ? this.inEncoding : inBuffer.getEncoding();

primitiveConvert(context, inBuffer.shallowDup(), outBuffer, 0, -1, fromEncoding, false, actions.ecflags);

if (lastResult != null) {
createLastError();
} else {
outBuffer.append(finish(inBuffer.getEncoding()));
}

return lastResult;
}

public ByteList transcode(ThreadContext context, ByteList value) {
ByteList dest = new ByteList();

19 changes: 13 additions & 6 deletions core/src/main/java/org/jruby/util/encoding/Transcoder.java
Original file line number Diff line number Diff line change
@@ -149,12 +149,17 @@ public static ByteList strConvEncOpts(ThreadContext context, ByteList value, Enc

Transcoder ec = EncodingUtils.econvOpenOpts(context, fromEncoding.getName(), toEncoding.getName(), ecflags, ecopts);
if (ec == null) return value;

ByteList ret = ec.convert(context, value, false);

ret.setEncoding(toEncoding);

return ret;

ByteList newStr = new ByteList();
RubyCoderResult ret = ec.econvConvert(context, value, newStr);

if (ret == null || ret.stringResult.equals("finished")) {
newStr.setEncoding(toEncoding);
return newStr;
} else {
// error result, failover to original
return value;
}
}

// rb_str_conv_enc
@@ -187,6 +192,8 @@ public static ByteList transcode(ThreadContext context, ByteList value, Encoding

// rb_econv_convert
public abstract RubyCoderResult transcode(ThreadContext context, ByteList value, ByteList dest);

public abstract RubyCoderResult econvConvert(ThreadContext context, ByteList value, ByteList dest);

public abstract ByteList transcode(ThreadContext context, ByteList value);

0 comments on commit ff54579

Please sign in to comment.