Skip to content

Commit

Permalink
Fix jruby encoding in new thread (#12919)
Browse files Browse the repository at this point in the history
In jruby `runtime.evalScriptlet('Encoding::UTF_8')` can be broken under a newly created thread, which can cause protobuf encoding to fail. For example: https://github.com/ntkme/sass-embedded-host-ruby/actions/runs/5108602231/jobs/9182569583#step:5:544

It real issue seems to be in jruby itself. A bug report with minimal reproduction has been filed at jruby/jruby#7820

This PR fixes the problem by effectively replacing `runtime.evalScriptlet('Encoding::UTF_8')` with `runtime.getEncodingService().convertEncodingToRubyEncoding(org.jcodings.specific.UTF8Encoding.INSTANCE)`, which works on all threads.

Closes #12919

COPYBARA_INTEGRATE_REVIEW=#12919 from ntkme:fix-jruby-encoding 345680e
PiperOrigin-RevId: 536498846
  • Loading branch information
ntkme authored and copybara-github committed May 30, 2023
1 parent 79f0575 commit 6609bea
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 56 deletions.
4 changes: 2 additions & 2 deletions objectivec/GPBAny.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions objectivec/GPBApi.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions objectivec/GPBDuration.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions objectivec/GPBEmpty.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions objectivec/GPBFieldMask.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions objectivec/GPBSourceContext.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions objectivec/GPBStruct.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions objectivec/GPBTimestamp.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions objectivec/GPBType.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 18 additions & 18 deletions objectivec/GPBWrappers.pbobjc.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions ruby/src/main/java/com/google/protobuf/jruby/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
import com.google.protobuf.Descriptors.FieldDescriptor;
import java.math.BigInteger;
import org.jcodings.Encoding;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.*;
import org.jruby.exceptions.RaiseException;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
Expand Down Expand Up @@ -141,12 +143,12 @@ public static IRubyObject checkType(
throw createInvalidTypeError(context, "boolean", fieldName, value);
break;
case BYTES:
value = validateAndEncodeString(context, "bytes", fieldName, value, "Encoding::ASCII_8BIT");
value = validateAndEncodeString(context, "bytes", fieldName, value, ASCIIEncoding.INSTANCE);
break;
case STRING:
value =
validateAndEncodeString(
context, "string", fieldName, symToString(value), "Encoding::UTF_8");
context, "string", fieldName, symToString(value), UTF8Encoding.INSTANCE);
break;
case MESSAGE:
if (value.getMetaClass() != typeClass) {
Expand Down Expand Up @@ -383,11 +385,15 @@ private static IRubyObject validateAndEncodeString(
String fieldType,
String fieldName,
IRubyObject value,
String encoding) {
Encoding encoding) {
if (!(value instanceof RubyString))
throw createInvalidTypeError(context, fieldType, fieldName, value);

value = ((RubyString) value).encode(context, context.runtime.evalScriptlet(encoding));
value =
((RubyString) value)
.encode(
context,
context.runtime.getEncodingService().convertEncodingToRubyEncoding(encoding));
value.setFrozen(true);
return value;
}
Expand Down

0 comments on commit 6609bea

Please sign in to comment.