Skip to content

Commit 5512c59

Browse files
committed
Encoding fixes for JRUBY-6033:
* String#% was not setting base encoding of new string to same as format string, as in MRI * Array#to_s and Array#inspect did not use encoding-aware methods for building the string * Hash#inspect ditto
1 parent 1ffea67 commit 5512c59

File tree

4 files changed

+31
-21
lines changed

4 files changed

+31
-21
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,5 @@ dev_null
6363
.idea/workspace.xml
6464
shared.iml
6565
build_graph.png
66-
/.idea/
66+
/.idea/
67+
/.rbx/

src/org/jruby/RubyArray.java

+15-9
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
import java.util.Iterator;
4949
import java.util.List;
5050
import java.util.ListIterator;
51+
import org.jcodings.Encoding;
52+
import org.jcodings.specific.USASCIIEncoding;
5153

5254
import org.jruby.anno.JRubyClass;
5355
import org.jruby.anno.JRubyMethod;
@@ -87,6 +89,7 @@
8789
*/
8890
@JRubyClass(name="Array")
8991
public class RubyArray extends RubyObject implements List {
92+
public static final int DEFAULT_INSPECT_STR_SIZE = 10;
9093

9194
public static RubyClass createArrayClass(Ruby runtime) {
9295
RubyClass arrayc = runtime.defineClass("Array", runtime.getObject(), ARRAY_ALLOCATOR);
@@ -1466,22 +1469,25 @@ public RubyArray concat19(IRubyObject obj) {
14661469
*
14671470
*/
14681471
private IRubyObject inspectAry(ThreadContext context) {
1469-
ByteList buffer = new ByteList();
1470-
buffer.append('[');
1472+
Encoding encoding = context.runtime.getDefaultInternalEncoding();
1473+
if (encoding == null) encoding = USASCIIEncoding.INSTANCE;
1474+
RubyString str = RubyString.newStringLight(context.runtime, DEFAULT_INSPECT_STR_SIZE, encoding);
1475+
str.cat((byte)'[');
14711476
boolean tainted = isTaint();
14721477
boolean untrust = isUntrusted();
14731478

14741479
for (int i = 0; i < realLength; i++) {
1475-
if (i > 0) buffer.append(',').append(' ');
1480+
if (i > 0) str.cat((byte)',').cat((byte)' ');
14761481

1477-
RubyString str = inspect(context, safeArrayRef(values, begin + i));
1478-
if (str.isTaint()) tainted = true;
1479-
if (str.isUntrusted()) untrust = true;
1480-
buffer.append(str.getByteList());
1482+
RubyString str2 = inspect(context, safeArrayRef(values, begin + i));
1483+
if (str2.isTaint()) tainted = true;
1484+
if (str2.isUntrusted()) untrust = true;
1485+
1486+
// safe for both 1.9 and 1.8
1487+
str.cat19(str2);
14811488
}
1482-
buffer.append(']');
1489+
str.cat((byte)']');
14831490

1484-
RubyString str = getRuntime().newString(buffer);
14851491
if (tainted) str.setTaint(true);
14861492
if (untrust) str.setUntrusted(true);
14871493

src/org/jruby/RubyHash.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
import org.jruby.runtime.builtin.IRubyObject;
6666
import org.jruby.runtime.marshal.MarshalStream;
6767
import org.jruby.runtime.marshal.UnmarshalStream;
68-
import org.jruby.util.ByteList;
6968
import org.jruby.util.TypeConverter;
7069
import org.jruby.util.RecursiveComparator;
7170

@@ -111,6 +110,7 @@
111110
*/
112111
@JRubyClass(name = "Hash", include="Enumerable")
113112
public class RubyHash extends RubyObject implements Map {
113+
public static final int DEFAULT_INSPECT_STR_SIZE = 20;
114114

115115
public static RubyClass createHashClass(Ruby runtime) {
116116
RubyClass hashc = runtime.defineClass("Hash", runtime.getObject(), HASH_ALLOCATOR);
@@ -713,23 +713,23 @@ public void modify() {
713713
*
714714
*/
715715
private IRubyObject inspectHash(final ThreadContext context) {
716-
final ByteList buffer = new ByteList();
717-
buffer.append('{');
716+
final RubyString str = RubyString.newStringLight(context.runtime, DEFAULT_INSPECT_STR_SIZE);
717+
str.cat((byte)'{');
718718
final boolean[] firstEntry = new boolean[1];
719719

720720
firstEntry[0] = true;
721721
visitAll(new Visitor() {
722722
public void visit(IRubyObject key, IRubyObject value) {
723-
if (!firstEntry[0]) buffer.append(',').append(' ');
723+
if (!firstEntry[0]) str.cat((byte)',').cat((byte)' ');
724724

725-
buffer.append(inspect(context, key).getByteList());
726-
buffer.append('=').append('>');
727-
buffer.append(inspect(context, value).getByteList());
725+
str.cat19(inspect(context, key));
726+
str.cat((byte)'=').cat((byte)'>');
727+
str.cat19(inspect(context, value));
728728
firstEntry[0] = false;
729729
}
730730
});
731-
buffer.append('}');
732-
return getRuntime().newString(buffer);
731+
str.cat((byte)'}');
732+
return str;
733733
}
734734

735735
/** rb_hash_inspect

src/org/jruby/RubyString.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -1101,10 +1101,13 @@ private IRubyObject opFormatCommon(ThreadContext context, IRubyObject arg, Compa
11011101
IRubyObject tmp = arg.checkArrayType();
11021102
if (tmp.isNil()) tmp = arg;
11031103

1104-
// FIXME: Should we make this work with platform's locale,
1105-
// or continue hardcoding US?
11061104
ByteList out = new ByteList(value.getRealSize());
1105+
out.setEncoding(value.getEncoding());
1106+
11071107
boolean tainted;
1108+
1109+
// FIXME: Should we make this work with platform's locale,
1110+
// or continue hardcoding US?
11081111
switch (compat) {
11091112
case RUBY1_8:
11101113
tainted = Sprintf.sprintf(out, Locale.US, value, tmp);

0 commit comments

Comments
 (0)