Skip to content

Commit c4a418b

Browse files
committed
[GR-17457] Prevent flattening LazyIntRope from modifying its bytes.
PullRequest: truffleruby/1762
2 parents 5bd684f + d343a83 commit c4a418b

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
@@ -329,15 +329,17 @@ public static byte[] flattenBytes(Rope rope) {
329329
continue;
330330
}
331331

332-
// Force lazy ropes
333-
if (current instanceof LazyRope) {
334-
((LazyRope) current).fulfill();
332+
final byte[] rawBytes;
333+
if (current instanceof LazyIntRope) {
334+
rawBytes = current.getBytesSlow();
335+
} else {
336+
rawBytes = current.getRawBytes();
335337
}
336338

337-
if (current.getRawBytes() != null) {
339+
if (rawBytes != null) {
338340
// In the absence of any SubstringRopes, we always take the full contents of the current rope.
339341
if (substringLengths.isEmpty()) {
340-
System.arraycopy(current.getRawBytes(), byteOffset, buffer, bufferPosition, current.byteLength());
342+
System.arraycopy(rawBytes, byteOffset, buffer, bufferPosition, current.byteLength());
341343
bufferPosition += current.byteLength();
342344
} else {
343345
int bytesToCopy = substringLengths.pop();
@@ -352,7 +354,7 @@ public static byte[] flattenBytes(Rope rope) {
352354
currentBytesToCopy = bytesToCopy;
353355
}
354356

355-
System.arraycopy(current.getRawBytes(), byteOffset, buffer, bufferPosition, currentBytesToCopy);
357+
System.arraycopy(rawBytes, byteOffset, buffer, bufferPosition, currentBytesToCopy);
356358
bufferPosition += currentBytesToCopy;
357359
bytesToCopy -= currentBytesToCopy;
358360

@@ -561,7 +563,7 @@ public static int hashForRange(Rope rope, int startingHashCode, int offset, int
561563
}
562564

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

0 commit comments

Comments
 (0)