Last active
February 19, 2016 15:04
-
-
Save headius/99779f55add2d007ca42 to your computer and use it in GitHub Desktop.
Attempted patch to fix marshaling of symbolic names we store as java.lang.String
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/src/main/java/org/jruby/runtime/marshal/MarshalStream.java b/core/src/main/java/org/jruby/runtime/marshal/MarshalStream.java | |
index 4b14a54..b1b7a9a 100644 | |
--- a/core/src/main/java/org/jruby/runtime/marshal/MarshalStream.java | |
+++ b/core/src/main/java/org/jruby/runtime/marshal/MarshalStream.java | |
@@ -46,6 +46,7 @@ import org.jruby.RubyArray; | |
import org.jruby.RubyBignum; | |
import org.jruby.RubyBoolean; | |
import org.jruby.RubyClass; | |
+import org.jruby.RubyEncoding; | |
import org.jruby.RubyFixnum; | |
import org.jruby.RubyFloat; | |
import org.jruby.RubyHash; | |
@@ -136,6 +137,11 @@ public class MarshalStream extends FilterOutputStream { | |
return fixnum.getLongValue() <= RubyFixnum.MAX_MARSHAL_FIXNUM && fixnum.getLongValue() >= RubyFixnum.MIN_MARSHAL_FIXNUM; | |
} | |
+ private void dumpName(String name) throws IOException { | |
+ // forcing this always to UTF-8 is not right, but we don't have original source's encoding at this point | |
+ dumpObject(runtime.newSymbol(name, UTF8Encoding.INSTANCE)); | |
+ } | |
+ | |
private void writeAndRegisterSymbol(String sym) throws IOException { | |
if (cache.isSymbolRegistered(sym)) { | |
cache.writeSymbolLink(this, sym); | |
@@ -330,7 +336,7 @@ public class MarshalStream extends FilterOutputStream { | |
registerLinkTarget(value); | |
write(TYPE_USRMARSHAL); | |
RubyClass metaclass = value.getMetaClass().getRealClass(); | |
- writeAndRegisterSymbol(metaclass.getName()); | |
+ dumpName(metaclass.getName()); | |
IRubyObject marshaled; | |
if (method != null) { | |
@@ -372,7 +378,7 @@ public class MarshalStream extends FilterOutputStream { | |
write(TYPE_USERDEF); | |
RubyClass metaclass = value.getMetaClass().getRealClass(); | |
- writeAndRegisterSymbol(metaclass.getName()); | |
+ dumpName(metaclass.getName()); | |
writeString(marshaled.getByteList()); | |
@@ -392,7 +398,7 @@ public class MarshalStream extends FilterOutputStream { | |
} | |
// w_symbol | |
- writeAndRegisterSymbol(type.getName()); | |
+ dumpName(type.getName()); | |
} | |
public void dumpVariablesWithEncoding(List<Variable<Object>> vars, IRubyObject obj) throws IOException { | |
@@ -414,7 +420,7 @@ public class MarshalStream extends FilterOutputStream { | |
private void dumpVariablesShared(List<Variable<Object>> vars) throws IOException { | |
for (Variable<Object> var : vars) { | |
if (var.getValue() instanceof IRubyObject) { | |
- writeAndRegisterSymbol(var.getName()); | |
+ dumpName(var.getName()); | |
dumpObject((IRubyObject)var.getValue()); | |
} | |
} | |
@@ -473,9 +479,9 @@ public class MarshalStream extends FilterOutputStream { | |
} | |
public void writeString(String value) throws IOException { | |
- writeInt(value.length()); | |
- // FIXME: should preserve unicode? | |
- out.write(RubyString.stringToBytes(value)); | |
+ byte[] bytes = value.getBytes(RubyEncoding.UTF8); | |
+ writeInt(bytes.length); | |
+ out.write(bytes); | |
} | |
public void writeString(ByteList value) throws IOException { | |
diff --git a/core/src/main/java/org/jruby/runtime/marshal/UnmarshalStream.java b/core/src/main/java/org/jruby/runtime/marshal/UnmarshalStream.java | |
index d731ac7..ba715ca 100644 | |
--- a/core/src/main/java/org/jruby/runtime/marshal/UnmarshalStream.java | |
+++ b/core/src/main/java/org/jruby/runtime/marshal/UnmarshalStream.java | |
@@ -320,6 +320,23 @@ public class UnmarshalStream extends InputStream { | |
return new ByteList(buffer,false); | |
} | |
+ public String unmarshalSymbol() throws IOException { | |
+ int length = unmarshalInt(); | |
+ byte[] buffer = new byte[length]; | |
+ | |
+ int readLength = 0; | |
+ while (readLength < length) { | |
+ int read = inputStream.read(buffer, readLength, length - readLength); | |
+ | |
+ if (read == -1) { | |
+ throw getRuntime().newArgumentError("marshal data too short"); | |
+ } | |
+ readLength += read; | |
+ } | |
+ | |
+ return new String(buffer, RubyEncoding.UTF8); | |
+ } | |
+ | |
public int unmarshalInt() throws IOException { | |
int c = readSignedByte(); | |
if (c == 0) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment