Permalink
Browse files

Encode Symbols as US-ASCII to match Ruby 1.9.3

This adjusts the behavior of symbols under JRuby to match that of C
Ruby 1.9.3, where :foo and :foo.to_s should both have an encoding of
US-ASCII. Prior to this change symbols under JRuby had an encoding of
ASCII-8BIT which was causing problems because Psych interprets
ASCII-8BIT strings as binary data.
  • Loading branch information...
1 parent 8a0b6cd commit a8680ab876d114d5c636be8103fdbaa1a76655d9 @bbrowning bbrowning committed with enebo May 10, 2012
Showing with 24 additions and 2 deletions.
  1. +13 −0 spec/regression/symbol_encoding_spec.rb
  2. +11 −2 src/org/jruby/RubySymbol.java
@@ -0,0 +1,13 @@
+require 'rspec'
+
+if RUBY_VERSION >= "1.9.2"
+ describe "symbol encoding" do
+ it "should be US-ASCII" do
+ :foo.encoding.name.should == "US-ASCII"
+ end
+
+ it "should be US-ASCII after converting to string" do
+ :foo.to_s.encoding.name.should == "US-ASCII"
+ end
+ end
+end
@@ -45,6 +45,7 @@
import java.util.concurrent.locks.ReentrantLock;
import org.jcodings.Encoding;
+import org.jcodings.specific.USASCIIEncoding;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.ast.util.ArgsUtil;
@@ -100,7 +101,7 @@ private RubySymbol(Ruby runtime, String internedSymbol, ByteList symbolBytes) {
}
private RubySymbol(Ruby runtime, String internedSymbol) {
- this(runtime, internedSymbol, ByteList.create(internedSymbol));
+ this(runtime, internedSymbol, symbolBytesFromString(runtime, internedSymbol));
}
public static RubyClass createSymbolClass(Ruby runtime) {
@@ -619,6 +620,14 @@ public Object toJava(Class target) {
return super.toJava(target);
}
+ private static ByteList symbolBytesFromString(Ruby runtime, String internedSymbol) {
+ if (runtime.is1_9()) {
+ return new ByteList(ByteList.plain(internedSymbol), USASCIIEncoding.INSTANCE, false);
+ } else {
+ return ByteList.create(internedSymbol);
+ }
+ }
+
public static final class SymbolTable {
static final int DEFAULT_INITIAL_CAPACITY = 2048; // *must* be power of 2!
static final int MAXIMUM_CAPACITY = 1 << 30;
@@ -663,7 +672,7 @@ public RubySymbol getSymbol(String name) {
if (isSymbolMatch(name, hash, e)) return e.symbol;
}
- return createSymbol(name, ByteList.create(name), hash, table);
+ return createSymbol(name, symbolBytesFromString(runtime, name), hash, table);
}
public RubySymbol getSymbol(ByteList bytes) {

0 comments on commit a8680ab

Please sign in to comment.