Skip to content

Commit 375d19b

Browse files
committed
Handle ImmutableString in String#scrub
1 parent 5010005 commit 375d19b

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

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)