Skip to content
Permalink
Browse files
Align our strConvEncOpts with MRI's.
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 ff54579a785c82ebde91f724881652f16fb08b41
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
@@ -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();

@@ -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.