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: ab8c9e41365c
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e79aed476661
Choose a head ref
  • 7 commits
  • 9 files changed
  • 1 contributor

Commits on Mar 3, 2015

  1. Copy the full SHA
    9132b54 View commit details
  2. Copy the full SHA
    e6fdfbc View commit details
  3. Copy the full SHA
    594b08e View commit details
  4. Copy the full SHA
    09648c9 View commit details
  5. Copy the full SHA
    6111fc8 View commit details
  6. Copy the full SHA
    f273f91 View commit details
  7. Copy the full SHA
    e79aed4 View commit details
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/string/append_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
fails:String#<< taints self if other is tainted
fails:String#<< untrusts self if other is untrusted
fails:String#<< with Integer concatencates the argument interpreted as a codepoint
fails:String#<< with Integer returns a ASCII-8BIT string if self is US-ASCII and the argument is between 128-255 (inclusive)
fails:String#<< with Integer raises RangeError if the argument is an invalid codepoint for self's encoding
1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/b_tags.txt

This file was deleted.

9 changes: 0 additions & 9 deletions spec/truffle/tags/core/string/byteslice_tags.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
fails:String#byteslice returns the character code of the character at the given index
fails:String#byteslice returns nil if index is outside of self
fails:String#byteslice calls to_int on the given index
fails:String#byteslice with index, length always taints resulting strings when self is tainted
fails:String#byteslice with index, length returns nil if the offset falls outside of self
fails:String#byteslice with index, length returns nil if the length is negative
fails:String#byteslice with index, length calls to_int on the given index and the given length
fails:String#byteslice with index, length returns subclass instances
fails:String#byteslice with index, length handles repeated application
fails:String#byteslice with Range returns the substring given by the offsets of the range
fails:String#byteslice with Range returns nil if the beginning of the range falls outside of self
fails:String#byteslice with Range returns an empty string if range.begin is inside self and > real end
fails:String#byteslice with Range always taints resulting strings when self is tainted
fails:String#byteslice with Range returns subclass instances
fails:String#byteslice with Range calls to_int on range arguments
fails:String#byteslice with Range works with Range subclasses
fails:String#byteslice with Range handles repeated application
fails:String#byteslice on on non ASCII strings returns byteslice of unicode strings
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/string/concat_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
fails:String#concat taints self if other is tainted
fails:String#concat untrusts self if other is untrusted
fails:String#concat with Integer concatencates the argument interpreted as a codepoint
fails:String#concat with Integer returns a ASCII-8BIT string if self is US-ASCII and the argument is between 128-255 (inclusive)
fails:String#concat with Integer raises RangeError if the argument is an invalid codepoint for self's encoding
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/string/split_tags.txt
Original file line number Diff line number Diff line change
@@ -10,17 +10,14 @@ fails:String#split with String splits between characters when its argument is an
fails:String#split with String tries converting its pattern argument to a string via to_str
fails:String#split with String tries converting limit to an integer via to_int
fails:String#split with String returns subclass instances based on self
fails:String#split with String does not call constructor on created subclass instances
fails:String#split with String taints the resulting strings if self is tainted
fails:String#split with Regexp defaults to $; when regexp isn't given or nil
fails:String#split with Regexp includes all captures in the result array
fails:String#split with Regexp does not include non-matching captures in the result array
fails:String#split with Regexp tries converting limit to an integer via to_int
fails:String#split with Regexp returns subclass instances based on self
fails:String#split with Regexp does not call constructor on created subclass instances
fails:String#split with Regexp taints the resulting strings if self is tainted
fails:String#split with Regexp taints an empty string if self is tainted
fails:String#split with Regexp retains the encoding of the source string
fails:String#split with Regexp splits a string on each character for a multibyte encoding and empty split
fails:String#split with Regexp returns an ArgumentError if an invalid UTF-8 string is supplied
fails:String#split with Regexp doesn't taints the resulting strings if the Regexp is tainted
Original file line number Diff line number Diff line change
@@ -52,6 +52,19 @@ public TaintResultNode(TaintResultNode prev) {
isTaintedNode = prev.isTaintedNode;
}

public Object maybeTaint(RubyBasicObject source, RubyBasicObject result) {
if (taintProfile.profile(isTaintedNode.isTainted(source))) {
if (taintNode == null) {
CompilerDirectives.transferToInterpreter();
taintNode = insert(TaintNodeFactory.create(getContext(), getSourceSection(), null));
}

taintNode.taint(result);
}

return result;
}

@Override
public Object execute(VirtualFrame frame) {
final RubyBasicObject result;
@@ -72,14 +85,7 @@ public Object execute(VirtualFrame frame) {
taintSource = (RubyBasicObject) RubyArguments.getUserArgument(frame.getArguments(), adjustedIndex);
}

if (taintProfile.profile(isTaintedNode.isTainted(taintSource))) {
if (taintNode == null) {
CompilerDirectives.transferToInterpreter();
taintNode = insert(TaintNodeFactory.create(getContext(), getSourceSection(), null));
}

taintNode.taint(result);
}
maybeTaint(taintSource, result);
}

return result;
Original file line number Diff line number Diff line change
@@ -200,7 +200,7 @@ public Object compare(VirtualFrame frame, RubyString a, Object b) {
}
}

@CoreMethod(names = { "<<", "concat" }, required = 1)
@CoreMethod(names = { "<<", "concat" }, required = 1, taintFrom = 1)
@NodeChildren({
@NodeChild(value = "string"),
@NodeChild(value = "other")
@@ -576,7 +576,7 @@ public boolean asciiOnly(RubyString string) {
}
}

@CoreMethod(names = "b")
@CoreMethod(names = "b", taintFrom = 0)
public abstract static class BNode extends CoreMethodNode {

public BNode(RubyContext context, SourceSection sourceSection) {
@@ -640,44 +640,6 @@ public int byteSize(RubyString string) {

}

@CoreMethod(names = "byteslice", required = 1, optional = 1)
public abstract static class ByteSliceNode extends CoreMethodNode {

public ByteSliceNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public ByteSliceNode(ByteSliceNode prev) {
super(prev);
}

@Specialization
public Object byteSlice(RubyString string, int index, UndefinedPlaceholder undefined) {
return byteSlice(string, index, 1);
}

@Specialization
public Object byteSlice(RubyString string, int index, int length) {
final ByteList bytes = string.getBytes();

final int normalizedIndex = string.normalizeIndex(index);

if (normalizedIndex > bytes.length()) {
return getContext().getCoreLibrary().getNilObject();
}

int rangeEnd = normalizedIndex + length;
if (rangeEnd > bytes.getRealSize()) {
rangeEnd = bytes.getRealSize();
}

final byte[] copiedBytes = Arrays.copyOfRange(bytes.getUnsafeBytes(), normalizedIndex, rangeEnd);

return new RubyString(getContext().getCoreLibrary().getStringClass(), new ByteList(copiedBytes, string.getBytes().getEncoding()));
}

}

@CoreMethod(names = "chomp!", optional = 1)
public abstract static class ChompBangNode extends CoreMethodNode {

Original file line number Diff line number Diff line change
@@ -17,15 +17,20 @@
import org.jcodings.exception.EncodingException;
import org.jcodings.specific.ASCIIEncoding;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.TaintResultNode;
import org.jruby.truffle.nodes.core.StringNodes;
import org.jruby.truffle.nodes.core.StringNodesFactory;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import java.util.Arrays;

/**
* Rubinius primitives associated with the Ruby {@code String} class.
*/
@@ -34,21 +39,47 @@ public abstract class StringPrimitiveNodes {
@RubiniusPrimitive(name = "string_byte_substring")
public static abstract class StringByteSubstringPrimitiveNode extends RubiniusPrimitiveNode {

@Child private StringNodes.ByteSliceNode byteSliceNode;
@Child private TaintResultNode taintResultNode;

public StringByteSubstringPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
byteSliceNode = StringNodesFactory.ByteSliceNodeFactory.create(context, sourceSection, new RubyNode[] {});
taintResultNode = new TaintResultNode(context, sourceSection, true, 0, null);
}

public StringByteSubstringPrimitiveNode(StringByteSubstringPrimitiveNode prev) {
super(prev);
byteSliceNode = prev.byteSliceNode;
taintResultNode = prev.taintResultNode;
}

@Specialization
public Object stringByteSubstring(RubyString string, int index, UndefinedPlaceholder length) {
return stringByteSubstring(string, index, 1);
}

@Specialization
public Object stringByteSubstring(RubyString string, int index, int length) {
final ByteList bytes = string.getBytes();

final int normalizedIndex = string.normalizeIndex(index);

if (normalizedIndex > bytes.length()) {
return getContext().getCoreLibrary().getNilObject();
}

int rangeEnd = normalizedIndex + length;
if (rangeEnd > bytes.getRealSize()) {
rangeEnd = bytes.getRealSize();
}

final byte[] copiedBytes = Arrays.copyOfRange(bytes.getUnsafeBytes(), normalizedIndex, rangeEnd);
final RubyString result = new RubyString(getContext().getCoreLibrary().getStringClass(), new ByteList(copiedBytes, string.getBytes().getEncoding()));

return taintResultNode.maybeTaint(string, result);
}

@Specialization
public Object stringByteSubstring(VirtualFrame frame, RubyString string, int index, int length) {
return byteSliceNode.byteSlice(string, index, length);
public Object stringByteSubstring(RubyString string, RubyRange range, UndefinedPlaceholder unused) {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -1560,7 +1560,9 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/string.rb")) {
if (sourceSection.getSource().getPath().equals("core:/core/rubinius/bootstrap/string.rb") ||
sourceSection.getSource().getPath().equals("core:/core/rubinius/common/string.rb")) {

if (nameWithoutSigil.equals("@num_bytes")) {
return new RubyCallNode(context, sourceSection,
"bytesize",