Skip to content

Commit cbb22de

Browse files
committed
[GR-17457] Handle ImmutableString in String#scrub
PullRequest: truffleruby/2309
2 parents 5010005 + eb520d8 commit cbb22de

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

ci.jsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ local part_definitions = {
4444
},
4545

4646
packages+: {
47-
'mx': '5.279.2',
47+
'mx': '5.280.5',
4848
"pip:ninja_syntax": "==1.7.2", # Required by NFI and mx
4949
},
5050

spec/ruby/core/string/scrub_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
"abc\u3042#{x81}".scrub("*").should == "abc\u3042*"
4040
end
4141

42+
it "replaces invalid byte sequences in frozen strings" do
43+
x81 = [0x81].pack('C').force_encoding('utf-8')
44+
(-"abc\u3042#{x81}").scrub("*").should == "abc\u3042*"
45+
utf16_str = ("abc".encode('UTF-16LE').bytes + [0x81]).pack('c*').force_encoding('UTF-16LE')
46+
(-(utf16_str)).scrub("*".encode('UTF-16LE')).should == "abc*".encode('UTF-16LE')
47+
end
48+
4249
it "replaces an incomplete character at the end with a single replacement" do
4350
xE3x80 = [0xE3, 0x80].pack('CC').force_encoding 'utf-8'
4451
xE3x80.scrub("*").should == "*"

src/main/java/org/truffleruby/core/string/StringNodes.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,9 +1803,13 @@ public abstract static class ScrubNode extends PrimitiveArrayArgumentsNode {
18031803
.create();
18041804
@Child private RopeNodes.BytesNode bytesNode = RopeNodes.BytesNode.create();
18051805

1806-
@Specialization(guards = { "isBrokenCodeRange(string.rope, codeRangeNode)", "isAsciiCompatible(string)" })
1807-
protected RubyString scrubAsciiCompat(RubyString string, RubyProc block) {
1808-
final Rope rope = string.rope;
1806+
@Specialization(
1807+
guards = {
1808+
"isBrokenCodeRange(rope, codeRangeNode)",
1809+
"isAsciiCompatible(rope)" })
1810+
protected RubyString scrubAsciiCompat(Object string, RubyProc block,
1811+
@CachedLibrary(limit = "2") RubyStringLibrary strings,
1812+
@Bind("strings.getRope(string)") Rope rope) {
18091813
final Encoding enc = rope.getEncoding();
18101814
final CodeRange cr = codeRangeNode.execute(rope);
18111815
Rope buf = RopeConstants.EMPTY_ASCII_8BIT_ROPE;
@@ -1874,10 +1878,14 @@ protected RubyString scrubAsciiCompat(RubyString string, RubyProc block) {
18741878
return makeStringNode.fromRope(buf);
18751879
}
18761880

1877-
@Specialization(guards = { "isBrokenCodeRange(string.rope, codeRangeNode)", "!isAsciiCompatible(string)" })
1878-
protected RubyString scrubAsciiIncompatible(RubyString string, RubyProc block,
1881+
@Specialization(
1882+
guards = {
1883+
"isBrokenCodeRange(rope, codeRangeNode)",
1884+
"!isAsciiCompatible(rope)" })
1885+
protected RubyString scrubAsciiIncompatible(Object string, RubyProc block,
1886+
@CachedLibrary(limit = "2") RubyStringLibrary strings,
1887+
@Bind("strings.getRope(string)") Rope rope,
18791888
@Cached RopeNodes.CalculateCharacterLengthNode calculateCharacterLengthNode) {
1880-
final Rope rope = string.rope;
18811889
final Encoding enc = rope.getEncoding();
18821890
final CodeRange cr = codeRangeNode.execute(rope);
18831891
Rope buf = RopeConstants.EMPTY_ASCII_8BIT_ROPE;

0 commit comments

Comments
 (0)