Skip to content

Instantly share code, notes, and snippets.

@headius
Last active February 19, 2016 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/99779f55add2d007ca42 to your computer and use it in GitHub Desktop.
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
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