Skip to content

Commit 04e9433

Browse files
committed
Fix String#unpack w* format issue
1 parent 0402549 commit 04e9433

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Bug fixes:
99
* Fix error message when the method name is not a Symbol or String for `Kernel#respond_to?` (#2132, @ssnickolay)
1010
* Fixed setting of special variables in enumerators and enumerables (#1484).
1111
* Fixed return value of `Enumerable#count` and `Enumerable#uniq` with multiple yielded arguments (#2145, @LillianZ).
12+
* Fixed `String#unpack` for `w*` format (#2143).
1213

1314
Compatibility:
1415

spec/ruby/core/string/unpack/w_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,13 @@
2323
"\x01\x02\x03".unpack("w w").should == [1, 2]
2424
end
2525
end
26+
27+
describe "String#unpack with directive 'w*'" do
28+
29+
it "decodes BER-compressed integers" do
30+
"\x01\x02\x03\x04".unpack("w*").should == [1, 2, 3, 4]
31+
"\x00\xCE\x0F\x84\x80\x80\x80\x80\x80\x80\x80\x80\x00\x01\x00".unpack("w*").should == [0, 9999, 2**65, 1, 0]
32+
"\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00\x90\x80\x80\x80\x80\x80\x80\x80\x03\x01\x02".unpack("w*").should == [2**63, (2**60 + 3), 1, 2]
33+
end
34+
35+
end

src/main/java/org/truffleruby/core/format/read/bytes/ReadBERNode.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,23 @@ public abstract class ReadBERNode extends FormatNode {
7070

7171
@Specialization
7272
protected Object encode(VirtualFrame frame, byte[] source) {
73-
final int position = getSourcePosition(frame);
74-
7573
final ByteBuffer encode = wrapByteBuffer(frame, source);
76-
int pos = encode.position();
74+
int position = encode.position();
7775

78-
final long ul = encode.get(pos) & 0x7f;
76+
final long ul = encode.get(position) & 0x7f;
7977

80-
if (simpleProfile.profile((encode.get(pos++) & 0x80) == 0)) {
81-
setSourcePosition(frame, position + pos);
78+
if (simpleProfile.profile((encode.get(position) & 0x80) == 0)) {
79+
position++;
80+
setSourcePosition(frame, position);
8281
return ul;
83-
}
82+
} else {
83+
position++;
84+
assert (ul & UL_MASK) == 0;
85+
final BigIntegerAndPos bigIntegerAndPos = runLoop(encode, ul, position);
8486

85-
assert (ul & UL_MASK) == 0;
86-
final BigIntegerAndPos bigIntegerAndPos = runLoop(encode, ul, pos);
87-
88-
setSourcePosition(frame, position + bigIntegerAndPos.getPos());
89-
return fixnumOrBignumNode.fixnumOrBignum(bigIntegerAndPos.getBigInteger());
87+
setSourcePosition(frame, bigIntegerAndPos.getPos());
88+
return fixnumOrBignumNode.fixnumOrBignum(bigIntegerAndPos.getBigInteger());
89+
}
9090
}
9191

9292
@TruffleBoundary

0 commit comments

Comments
 (0)