Skip to content

Commit d343a83

Browse files
committed
Prevent flattening LazyIntRope from modifying its bytes
1 parent 68754c6 commit d343a83

File tree

4 files changed

+28
-44
lines changed

4 files changed

+28
-44
lines changed

src/main/java/org/truffleruby/core/rope/LazyIntRope.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
package org.truffleruby.core.rope;
1111

1212

13+
import com.oracle.truffle.api.CompilerDirectives;
1314
import org.jcodings.Encoding;
1415
import org.jcodings.specific.USASCIIEncoding;
1516

16-
import com.oracle.truffle.api.CompilerDirectives;
17+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
1718

18-
public class LazyIntRope extends LazyRope {
19+
public class LazyIntRope extends ManagedRope {
1920

2021
final int value;
2122

@@ -24,7 +25,7 @@ public LazyIntRope(int value) {
2425
}
2526

2627
protected LazyIntRope(int value, Encoding encoding, int length) {
27-
super(encoding, length, length);
28+
super(encoding, CodeRange.CR_7BIT, length, length, 1, null);
2829
this.value = value;
2930
assert Integer.toString(value).length() == length;
3031
}
@@ -63,16 +64,24 @@ Rope withBinaryEncoding() {
6364
throw new UnsupportedOperationException("Must only be called for CR_VALID Strings");
6465
}
6566

67+
6668
@Override
67-
public byte[] fulfill() {
68-
if (bytes == null) {
69-
bytes = RopeOperations.encodeAsciiBytes(Integer.toString(value));
70-
}
69+
protected byte[] getBytesSlow() {
70+
return RopeOperations.encodeAsciiBytes(valueToString(value));
71+
}
7172

72-
return bytes;
73+
@TruffleBoundary
74+
private String valueToString(int value) {
75+
return Integer.toString(value);
7376
}
7477

7578
public int getValue() {
7679
return value;
7780
}
81+
82+
@Override
83+
protected byte getByteSlow(int index) {
84+
return getBytes()[index];
85+
}
86+
7887
}

src/main/java/org/truffleruby/core/rope/LazyRope.java

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/main/java/org/truffleruby/core/rope/RopeNodes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ private Rope substringRepeatingRopeWithEncoding(Encoding encoding, RepeatingRope
154154
}
155155

156156
@Specialization(guards = { "byteLength > 1", "!sameAsBase(base, byteLength)" })
157-
protected Rope substringLazyRope(LazyRope base, int byteOffset, int byteLength,
157+
protected Rope substringLazyRope(LazyIntRope base, int byteOffset, int byteLength,
158158
@Cached MakeSubstringRopeNode makeSubstringRopeNode) {
159159
return makeSubstringRopeNode.executeMake(base.getEncoding(), base, byteOffset, byteLength);
160160
}
@@ -1142,7 +1142,7 @@ protected int getByte(NativeRope rope, int index) {
11421142
}
11431143

11441144
@Specialization(guards = "rope.getRawBytes() == null")
1145-
protected int getByte(LazyRope rope, int index) {
1145+
protected int getByte(LazyIntRope rope, int index) {
11461146
return rope.getBytes()[index] & 0xff;
11471147
}
11481148

src/main/java/org/truffleruby/core/rope/RopeOperations.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,17 @@ public static byte[] flattenBytes(Rope rope) {
327327
continue;
328328
}
329329

330-
// Force lazy ropes
331-
if (current instanceof LazyRope) {
332-
((LazyRope) current).fulfill();
330+
final byte[] rawBytes;
331+
if (current instanceof LazyIntRope) {
332+
rawBytes = current.getBytesSlow();
333+
} else {
334+
rawBytes = current.getRawBytes();
333335
}
334336

335-
if (current.getRawBytes() != null) {
337+
if (rawBytes != null) {
336338
// In the absence of any SubstringRopes, we always take the full contents of the current rope.
337339
if (substringLengths.isEmpty()) {
338-
System.arraycopy(current.getRawBytes(), byteOffset, buffer, bufferPosition, current.byteLength());
340+
System.arraycopy(rawBytes, byteOffset, buffer, bufferPosition, current.byteLength());
339341
bufferPosition += current.byteLength();
340342
} else {
341343
int bytesToCopy = substringLengths.pop();
@@ -350,7 +352,7 @@ public static byte[] flattenBytes(Rope rope) {
350352
currentBytesToCopy = bytesToCopy;
351353
}
352354

353-
System.arraycopy(current.getRawBytes(), byteOffset, buffer, bufferPosition, currentBytesToCopy);
355+
System.arraycopy(rawBytes, byteOffset, buffer, bufferPosition, currentBytesToCopy);
354356
bufferPosition += currentBytesToCopy;
355357
bytesToCopy -= currentBytesToCopy;
356358

@@ -559,7 +561,7 @@ public static int hashForRange(Rope rope, int startingHashCode, int offset, int
559561
}
560562

561563
return hash;
562-
} else if (rope instanceof LazyRope) {
564+
} else if (rope instanceof LazyIntRope) {
563565
return Hashing.stringHash(rope.getBytes(), startingHashCode, offset, length);
564566
} else if (rope instanceof NativeRope) {
565567
return Hashing.stringHash(rope.getBytes(), startingHashCode, offset, length);

0 commit comments

Comments
 (0)