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.
  • Loading branch information
headius committed Jan 4, 2015
1 parent c74647f commit ff54579
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
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
Expand Up @@ -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
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit ff54579

Please sign in to comment.