Skip to content

Commit

Permalink
[Truffle] Fix String#valid_encoding? concat invalid string
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Fish committed Dec 9, 2016
1 parent 9a9e7d5 commit 59e593a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/valid_encoding_tags.txt

This file was deleted.

26 changes: 25 additions & 1 deletion truffle/src/main/java/org/jruby/truffle/core/rope/RopeNodes.java
Expand Up @@ -41,6 +41,7 @@

import static org.jruby.truffle.core.rope.CodeRange.CR_7BIT;
import static org.jruby.truffle.core.rope.CodeRange.CR_BROKEN;
import static org.jruby.truffle.core.rope.CodeRange.CR_UNKNOWN;
import static org.jruby.truffle.core.rope.CodeRange.CR_VALID;

public abstract class RopeNodes {
Expand Down Expand Up @@ -257,7 +258,7 @@ public Rope concatMutableRope(RopeBuffer left, Rope right, Encoding encoding,
return left;
}

@Specialization(guards = { "!isMutableRope(left)" })
@Specialization(guards = { "!isMutableRope(left)", "!isCodeRangeBroken(left, right)" })
public Rope concat(Rope left, Rope right, Encoding encoding,
@Cached("createBinaryProfile()") ConditionProfile sameCodeRangeProfile,
@Cached("createBinaryProfile()") ConditionProfile brokenCodeRangeProfile,
Expand All @@ -279,6 +280,25 @@ public Rope concat(Rope left, Rope right, Encoding encoding,
depth);
}

@Specialization(guards = {"!isMutableRope(left)", "isCodeRangeBroken(left, right)"})
public Rope concatCrBroken(Rope left, Rope right, Encoding encoding,
@Cached("create()") MakeLeafRopeNode makeLeafRopeNode) {
// This specialization was added to a special case where broken code range(s),
// may concat to form a valid code range.
try {
Math.addExact(left.byteLength(), right.byteLength());
} catch (ArithmeticException e) {
throw new RaiseException(getContext().getCoreExceptions().argumentError("Result of string concatenation exceeds the system maximum string length", this));
}

final byte[] leftBytes = left.getBytes();
final byte[] rightBytes = right.getBytes();
final byte[] bytes = new byte[leftBytes.length + rightBytes.length];
System.arraycopy(leftBytes, 0, bytes, 0, leftBytes.length);
System.arraycopy(rightBytes, 0, bytes, leftBytes.length, rightBytes.length);
return makeLeafRopeNode.executeMake(bytes, encoding, CR_UNKNOWN, NotProvided.INSTANCE);
}

public static CodeRange commonCodeRange(CodeRange first, CodeRange second,
ConditionProfile sameCodeRangeProfile,
ConditionProfile brokenCodeRangeProfile) {
Expand Down Expand Up @@ -309,6 +329,10 @@ private int depth(Rope left, Rope right) {
protected static boolean isMutableRope(Rope rope) {
return rope instanceof RopeBuffer;
}

protected static boolean isCodeRangeBroken(Rope first, Rope second) {
return first.getCodeRange() == CR_BROKEN || second.getCodeRange() == CR_BROKEN;
}
}


Expand Down

0 comments on commit 59e593a

Please sign in to comment.