Skip to content

Commit

Permalink
Showing 5 changed files with 29 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -29,25 +29,25 @@
public class TaintResultNode extends RubyNode {

private final boolean taintFromSelf;
private final int[] taintFromParameters;
private final int taintFromParameter;
private final ConditionProfile taintProfile = ConditionProfile.createBinaryProfile();

@Child private RubyNode method;
@Child private IsTaintedNode isTaintedNode;
@Child private TaintNode taintNode;

public TaintResultNode(boolean taintFromSelf, int[] taintFromParameters, RubyNode method) {
public TaintResultNode(boolean taintFromSelf, int taintFromParameter, RubyNode method) {
super(method.getContext(), method.getEncapsulatingSourceSection());
this.taintFromSelf = taintFromSelf;
this.taintFromParameters = taintFromParameters;
this.taintFromParameter = taintFromParameter;
this.method = method;
this.isTaintedNode = IsTaintedNodeFactory.create(getContext(), getSourceSection(), null);
}

public TaintResultNode(RubyContext context, SourceSection sourceSection, boolean taintFromSelf, int[] taintFromParameters) {
public TaintResultNode(RubyContext context, SourceSection sourceSection, boolean taintFromSelf, int taintFromParameter) {
super(context, sourceSection);
this.taintFromSelf = taintFromSelf;
this.taintFromParameters = taintFromParameters;
this.taintFromParameter = taintFromParameter;
this.isTaintedNode = IsTaintedNodeFactory.create(getContext(), getSourceSection(), null);
}

@@ -64,7 +64,6 @@ public Object maybeTaint(RubyBasicObject source, RubyBasicObject result) {
return result;
}

@ExplodeLoop
@Override
public Object execute(VirtualFrame frame) {
final RubyBasicObject result;
@@ -82,18 +81,15 @@ public Object execute(VirtualFrame frame) {
maybeTaint((RubyBasicObject) RubyArguments.getSelf(frame.getArguments()), result);
}

// TODO (nirvdrum 05-Mar-15) If we never pass more than one value in practice, we should change the annotation to be int rather than int[].
for (int i = 0; i < taintFromParameters.length; i++) {
// It's possible the taintFromParamaters value was misconfigured by the user, but the far more likely
// scenario is that the argument at that position is an UndefinedPlaceholder, which doesn't take up
// a space in the frame.
if (taintFromParameters[i] < RubyArguments.getUserArgumentsCount(frame.getArguments())) {
final Object argument = RubyArguments.getUserArgument(frame.getArguments(), taintFromParameters[i]);

if (argument instanceof RubyBasicObject) {
final RubyBasicObject taintSource = (RubyBasicObject) argument;
maybeTaint(taintSource, result);
}
// It's possible the taintFromParameter value was misconfigured by the user, but the far more likely
// scenario is that the argument at that position is an UndefinedPlaceholder, which doesn't take up
// a space in the frame.
if (taintFromParameter < RubyArguments.getUserArgumentsCount(frame.getArguments())) {
final Object argument = RubyArguments.getUserArgument(frame.getArguments(), taintFromParameter);

if (argument instanceof RubyBasicObject) {
final RubyBasicObject taintSource = (RubyBasicObject) argument;
maybeTaint(taintSource, result);
}
}
}
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@

boolean taintFromSelf() default false;

int[] taintFromParameters() default {};
int taintFromParameter() default -1;

boolean raiseIfFrozenSelf() default false;

Original file line number Diff line number Diff line change
@@ -209,9 +209,9 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
sequence = new ReturnEnumeratorIfNoBlockNode(methodDetails.getMethodAnnotation().names()[0], sequence);
}

if (methodDetails.getMethodAnnotation().taintFromSelf() || methodDetails.getMethodAnnotation().taintFromParameters().length > 0) {
if (methodDetails.getMethodAnnotation().taintFromSelf() || methodDetails.getMethodAnnotation().taintFromParameter() != -1) {
sequence = new TaintResultNode(methodDetails.getMethodAnnotation().taintFromSelf(),
methodDetails.getMethodAnnotation().taintFromParameters(),
methodDetails.getMethodAnnotation().taintFromParameter(),
sequence);
}

Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ public RubyString add(RubyString string, RubyString other) {

if (taintResultNode == null) {
CompilerDirectives.transferToInterpreter();
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), false, new int[]{}));
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), false, -1));
}

ret.getByteList().setEncoding(enc);
@@ -308,7 +308,7 @@ public Object compare(VirtualFrame frame, RubyString a, Object b) {
}
}

@CoreMethod(names = { "<<", "concat" }, required = 1, taintFromParameters = 0, raiseIfFrozenSelf = true)
@CoreMethod(names = { "<<", "concat" }, required = 1, taintFromParameter = 0, raiseIfFrozenSelf = true)
@NodeChildren({
@NodeChild(value = "string"),
@NodeChild(value = "other")
@@ -886,7 +886,7 @@ private int countSlow(VirtualFrame frame, RubyString string, Object[] args) {
}
}

@CoreMethod(names = "crypt", required = 1, taintFromSelf = true, taintFromParameters = 0)
@CoreMethod(names = "crypt", required = 1, taintFromSelf = true, taintFromParameter = 0)
@NodeChildren({
@NodeChild(value = "string"),
@NodeChild(value = "salt")
@@ -1172,7 +1172,7 @@ private Object substr(RubyString string, int beg, int len) {

if (taintResultNode == null) {
CompilerDirectives.transferToInterpreter();
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), true, new int[]{}));
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), true, -1));
}

final RubyString ret = getContext().makeString(string.getLogicalClass(), substringBytes);
@@ -1325,7 +1325,7 @@ public RubyString inspect(RubyString string) {
}
}

@CoreMethod(names = "initialize", optional = 1, taintFromParameters = 0)
@CoreMethod(names = "initialize", optional = 1, taintFromParameter = 0)
public abstract static class InitializeNode extends CoreMethodNode {

@Child private IsFrozenNode isFrozenNode;
@@ -1417,7 +1417,7 @@ public abstract static class InsertNode extends RubyNode {
public InsertNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
concatNode = DispatchHeadNodeFactory.createMethodCall(context);
taintResultNode = new TaintResultNode(context, sourceSection, false, new int[] {});
taintResultNode = new TaintResultNode(context, sourceSection, false, -1);
}

public InsertNode(InsertNode prev) {
@@ -1605,7 +1605,7 @@ public int ord(RubyString string) {
}
}

@CoreMethod(names = "replace", required = 1, raiseIfFrozenSelf = true, taintFromParameters = 0)
@CoreMethod(names = "replace", required = 1, raiseIfFrozenSelf = true, taintFromParameter = 0)
@NodeChildren({
@NodeChild(value = "string"),
@NodeChild(value = "other")
@@ -1820,7 +1820,7 @@ private ByteList dumpCommon(RubyString string) {
}
}

@CoreMethod(names = "scan", required = 1, needsBlock = true, taintFromParameters = 0)
@CoreMethod(names = "scan", required = 1, needsBlock = true, taintFromParameter = 0)
public abstract static class ScanNode extends YieldingCoreMethodNode {

public ScanNode(RubyContext context, SourceSection sourceSection) {
Original file line number Diff line number Diff line change
@@ -119,7 +119,7 @@ public static abstract class StringAwkSplitPrimitiveNode extends RubiniusPrimiti

public StringAwkSplitPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
taintResultNode = new TaintResultNode(context, sourceSection, true, new int[]{});
taintResultNode = new TaintResultNode(context, sourceSection, true, -1);
}

public StringAwkSplitPrimitiveNode(StringAwkSplitPrimitiveNode prev) {
@@ -203,7 +203,7 @@ public static abstract class StringByteSubstringPrimitiveNode extends RubiniusPr

public StringByteSubstringPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
taintResultNode = new TaintResultNode(context, sourceSection, true, new int[]{});
taintResultNode = new TaintResultNode(context, sourceSection, true, -1);
}

public StringByteSubstringPrimitiveNode(StringByteSubstringPrimitiveNode prev) {
@@ -530,7 +530,7 @@ public Object stringFindCharacter(RubyString string, int offset) {
private TaintResultNode getTaintResultNode() {
if (taintResultNode == null) {
CompilerDirectives.transferToInterpreter();
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), true, new int[]{}));
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), true, -1));
}

return taintResultNode;
@@ -1313,7 +1313,7 @@ public Object stringSubstring(RubyString string, int beg, int len) {
private RubyString makeSubstring(RubyString string, int beg, int len) {
if (taintResultNode == null) {
CompilerDirectives.transferToInterpreter();
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), true, new int[]{}));
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection(), true, -1));
}

final RubyString ret = getContext().makeString(string.getLogicalClass(), new ByteList(string.getByteList(), beg, len));

0 comments on commit bdb27a1

Please sign in to comment.