Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c19dd704aeba
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 707142995357
Choose a head ref
  • 3 commits
  • 2 files changed
  • 1 contributor

Commits on Jan 10, 2017

  1. [Truffle] Move str_compat_and_valid inside #scrub as it seems specifi…

    …c to it.
    
    * Also allows to add the taint check inside.
    eregon committed Jan 10, 2017
    Copy the full SHA
    f5a3dc1 View commit details
  2. Copy the full SHA
    e6bdda7 View commit details
  3. Copy the full SHA
    7071429 View commit details
Showing with 23 additions and 25 deletions.
  1. +7 −6 truffle/src/main/java/org/jruby/truffle/core/string/StringNodes.java
  2. +16 −19 truffle/src/main/ruby/core/string.rb
Original file line number Diff line number Diff line change
@@ -1366,8 +1366,9 @@ public abstract static class ScrubNode extends PrimitiveArrayArgumentsNode {

@Child private YieldNode yieldNode = new YieldNode();
@Child private RopeNodes.MakeConcatNode makeConcatNode = RopeNodesFactory.MakeConcatNodeGen.create(null, null, null);
@Child private RopeNodes.MakeSubstringNode makeSubstringNode = RopeNodesFactory.MakeSubstringNodeGen.create(null, null, null);

@Specialization(guards = { "!is7Bit(string)", "!isValidCodeRange(string)", "isAsciiCompatible(string)" })
@Specialization(guards = { "isBrokenCodeRange(string)", "isAsciiCompatible(string)" })
public DynamicObject scrubAsciiCompat(VirtualFrame frame, DynamicObject string, DynamicObject block) {
final Rope rope = rope(string);
final Encoding enc = rope.getEncoding();
@@ -1394,7 +1395,7 @@ public DynamicObject scrubAsciiCompat(VirtualFrame frame, DynamicObject string,
// p ~e: invalid bytes + unknown bytes
int clen = enc.maxLength();
if (p1 < p) {
buf = makeConcatNode.executeMake(buf, RopeOperations.create(ArrayUtils.extractRange(pBytes, p1, p), enc, CodeRange.CR_VALID), enc);
buf = makeConcatNode.executeMake(buf, makeSubstringNode.executeMake(rope, p1, p - p1), enc);
}

if (e - p < clen) {
@@ -1427,7 +1428,7 @@ public DynamicObject scrubAsciiCompat(VirtualFrame frame, DynamicObject string,
}
}
if (p1 < p) {
buf = makeConcatNode.executeMake(buf, RopeOperations.create(ArrayUtils.extractRange(pBytes, p1, p), enc, CodeRange.CR_VALID), enc);
buf = makeConcatNode.executeMake(buf, makeSubstringNode.executeMake(rope, p1, p - p1), enc);
}
if (p < e) {
Rope invalid = RopeOperations.create(ArrayUtils.extractRange(pBytes, p, e), enc, CodeRange.CR_BROKEN);
@@ -1438,7 +1439,7 @@ public DynamicObject scrubAsciiCompat(VirtualFrame frame, DynamicObject string,
return createString(buf);
}

@Specialization(guards = { "!is7Bit(string)", "!isValidCodeRange(string)", "!isAsciiCompatible(string)" })
@Specialization(guards = { "isBrokenCodeRange(string)", "!isAsciiCompatible(string)" })
public DynamicObject scrubAscciIncompatible(VirtualFrame frame, DynamicObject string, DynamicObject block) {
final Rope rope = rope(string);
final Encoding enc = rope.getEncoding();
@@ -1462,7 +1463,7 @@ public DynamicObject scrubAscciIncompatible(VirtualFrame frame, DynamicObject st
int clen = enc.maxLength();

if (p1 < p) {
buf = makeConcatNode.executeMake(buf, RopeOperations.create(ArrayUtils.extractRange(pBytes, p1, p), enc, CodeRange.CR_VALID), enc);
buf = makeConcatNode.executeMake(buf, makeSubstringNode.executeMake(rope, p1, p - p1), enc);
}

if (e - p < clen) {
@@ -1490,7 +1491,7 @@ public DynamicObject scrubAscciIncompatible(VirtualFrame frame, DynamicObject st
}
}
if (p1 < p) {
buf = makeConcatNode.executeMake(buf, RopeOperations.create(ArrayUtils.extractRange(pBytes, p1, p), enc, CodeRange.CR_VALID), enc);
buf = makeConcatNode.executeMake(buf, makeSubstringNode.executeMake(rope, p1, p - p1), enc);
}
if (p < e) {
Rope invalid = RopeOperations.create(ArrayUtils.extractRange(pBytes, p, e), enc, CodeRange.CR_BROKEN);
35 changes: 16 additions & 19 deletions truffle/src/main/ruby/core/string.rb
Original file line number Diff line number Diff line change
@@ -1208,16 +1208,26 @@ def scrub(replace = nil, &block)
end

taint = tainted?

validate = -> str {
str = StringValue(str)
unless str.valid_encoding?
raise ArgumentError, "replacement must be valid byte sequence"
end
# Special encoding check for #scrub
if str.ascii_only? ? !encoding.ascii_compatible? : encoding != str.encoding
raise Encoding::CompatibilityError, "incompatible character encodings"
end
taint = true if str.tainted?
str
}

replace_block = if replace
replace = str_compat_and_valid(replace, encoding)
taint = true if replace.tainted?
replace = validate.call(replace)
Proc.new { |broken| replace }
else
Proc.new { |broken|
replacement = block.call(broken)
replacement = str_compat_and_valid(replacement, encoding)
taint = true if replacement.tainted?
replacement
validate.call(block.call(broken))
}
end

@@ -1231,19 +1241,6 @@ def scrub!(replace = nil, &block)
return self
end

def str_compat_and_valid(str, enc)
res = StringValue(str)
if !res.valid_encoding?
raise ArgumentError, "replacement must be valid byte sequence"
else
if res.ascii_only? ? !enc.ascii_compatible? : enc != res.encoding
raise Encoding::CompatibilityError, "incompatible character encodings"
end
end
res
end
private :str_compat_and_valid

def []=(index, count_or_replacement, replacement=undefined)
Truffle.check_frozen