From a7845ae0e1653371f2d91554aa3dec7c0f0dca6a Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 2 Aug 2019 14:35:23 +0100 Subject: [PATCH] Python taint-tracking: Remove old implementation. --- .../semmle/python/dataflow/Implementation.qll | 86 +- .../src/semmle/python/security/TaintTest.qll | 2 +- .../semmle/python/security/TaintTracking.qll | 1070 +---------------- python/ql/src/semmle/python/web/Http.qll | 4 +- .../taint/config/RockPaperScissors.expected | 265 +++- .../taint/config/Simple.expected | 315 +++-- .../taint/config/TaintedArgument.expected | 23 +- .../taint/config/TestNode.expected | 278 +++++ .../taint/config/TestSink.expected | 10 +- .../taint/config/TestSource.expected | 8 +- .../taint/config/TestStep.expected | 187 +++ .../taint/dataflow/Dataflow.expected | 16 - .../taint/dataflow/TestNode.expected | 74 +- .../library-tests/taint/general/TaintLib.qll | 2 - .../library-tests/taint/general/TestDefn.ql | 4 +- .../library-tests/taint/general/TestStep.ql | 4 +- .../strings/DistinctStringKinds.expected | 20 +- .../taint/strings/DistinctStringKinds.ql | 3 +- .../library-tests/taint/strings/Taint.qll | 9 +- .../library-tests/taint/strings/TestNode.ql | 2 +- .../library-tests/taint/strings/TestStep.ql | 4 +- 21 files changed, 1105 insertions(+), 1281 deletions(-) diff --git a/python/ql/src/semmle/python/dataflow/Implementation.qll b/python/ql/src/semmle/python/dataflow/Implementation.qll index 2795791d167..ad063ae67b6 100644 --- a/python/ql/src/semmle/python/dataflow/Implementation.qll +++ b/python/ql/src/semmle/python/dataflow/Implementation.qll @@ -13,7 +13,7 @@ newtype TTaintTrackingContext = class TaintTrackingContext extends TTaintTrackingContext { string toString() { - this = TNoParam() and result = "No context" + this = TNoParam() and result = "" or exists(TaintKind param, AttributePath path, int n | this = TParamContext(param, path, n) and @@ -38,6 +38,10 @@ class TaintTrackingContext extends TTaintTrackingContext { ) } + predicate isTop() { + this = TNoParam() + } + } @@ -142,7 +146,16 @@ class TaintTrackingNode extends TTaintTrackingNode { /** Holds if this node should be presented to the user as part of a path */ predicate isVisible() { - exists(this.getNode().asCfgNode()) + exists(this.getCfgNode()) + } + + ControlFlowNode getCfgNode() { + result = this.getNode().asCfgNode() + } + + /** Get the AST node for this node. */ + AstNode getAstNode() { + result = this.getCfgNode().getNode() } } @@ -217,23 +230,6 @@ class TaintTrackingImplementation extends string { sanitizer.sanitizingEdge(kind, node.asVariable().getDefinition()) or sanitizer.sanitizingSingleEdge(kind, node.asVariable().getDefinition()) - or - exists(PyEdgeRefinement test | - test = node.asVariable().getDefinition() - | - exists(ControlFlowNode c, ClassValue cls | - Filters::isinstance(test.getTest(), c, test.getInput().getSourceVariable().getAUse()) and - c.pointsTo(cls) - | - test.getSense() = true and not exists(kind.getClass()) - or - test.getSense() = true and kind.getType().getASuperType() = cls - or - test.getSense() = false and not kind.getType().getASuperType() = cls - ) - or - test.getSense() = test_evaluates(test.getTest(), test.getInput().getSourceVariable().getAUse(), kind) - ) ) } @@ -246,6 +242,11 @@ class TaintTrackingImplementation extends string { test = use and result = kind.booleanValue() or result = test_evaluates(not_operand(test), use, kind).booleanNot() + or + exists(ControlFlowNode const | + Filters::equality_test(test, use, result.booleanNot(), const) and + const.getNode() instanceof ImmutableLiteral + ) } /** Gets the operand of a unary `not` expression. */ @@ -297,8 +298,6 @@ class TaintTrackingImplementation extends string { or this.yieldStep(src, node, context, path, kind) or - this.subscriptStep(src, node, context, path, kind) - or this.parameterStep(src, node, context, path, kind) or this.ifExpStep(src, node, context, path, kind) @@ -458,15 +457,6 @@ class TaintTrackingImplementation extends string { ) } - pragma [noinline] - predicate subscriptStep(TaintTrackingNode src, DataFlow::Node node, TaintTrackingContext context, AttributePath path, TaintKind kind) { - exists(DataFlow::Node srcnode, SequenceKind seqkind | - src = TTaintTrackingNode_(srcnode, context, path, seqkind, this) and - srcnode.asCfgNode() = node.asCfgNode().(SubscriptNode).getObject() and - kind = seqkind.getItem() - ) - } - pragma [noinline] predicate ifExpStep(TaintTrackingNode src, DataFlow::Node node, TaintTrackingContext context, AttributePath path, TaintKind kind) { exists(DataFlow::Node srcnode | @@ -512,6 +502,8 @@ class TaintTrackingImplementation extends string { this.taintedUniEdge(src, defn, context, path, kind) or this.taintedPiNode(src, defn, context, path, kind) + or + this.taintedArgument(src, defn, context, path, kind) } pragma [noinline] @@ -585,10 +577,44 @@ class TaintTrackingImplementation extends string { src = TTaintTrackingNode_(srcnode, context, path, kind, this) and srcnode.asVariable() = defn.getInput() and not this.(TaintTracking::Configuration).isBarrierTest(defn.getTest(), defn.getSense()) + | + exists(ControlFlowNode c, ClassValue cls | + Filters::isinstance(defn.getTest(), c, defn.getInput().getSourceVariable().getAUse()) and + c.pointsTo(cls) + | + defn.getSense() = true and kind.getType().getASuperType() = cls + or + defn.getSense() = false and not kind.getType().getASuperType() = cls + ) + or + defn.getSense() = test_evaluates(defn.getTest(), defn.getInput().getSourceVariable().getAUse(), kind) + ) + } + + pragma [noinline] + predicate taintedArgument(TaintTrackingNode src, ArgumentRefinement defn, TaintTrackingContext context, AttributePath path, TaintKind kind) { + exists(DataFlow::Node srcnode | + src = TTaintTrackingNode_(srcnode, context, path, kind, this) and + defn.getInput() = srcnode.asVariable() ) } } +module Implementation { + /* A call that returns a copy (or similar) of the argument */ + predicate copyCall(ControlFlowNode fromnode, CallNode tonode) { + tonode.getFunction().(AttrNode).getObject("copy") = fromnode + or + exists(ModuleObject copy, string name | + name = "copy" or name = "deepcopy" | + copy.attr(name).(FunctionObject).getACall() = tonode and + tonode.getArg(0) = fromnode + ) + or + tonode.getFunction().pointsTo(ObjectInternal::builtin("reversed")) and + tonode.getArg(0) = fromnode + } +} diff --git a/python/ql/src/semmle/python/security/TaintTest.qll b/python/ql/src/semmle/python/security/TaintTest.qll index fa656de6eba..82f59f9b4a3 100644 --- a/python/ql/src/semmle/python/security/TaintTest.qll +++ b/python/ql/src/semmle/python/security/TaintTest.qll @@ -4,4 +4,4 @@ import python -import TaintTracking::TaintFlowImplementation as TaintFlowTest +import semmle.python.dataflow.Implementation as TaintFlowTest diff --git a/python/ql/src/semmle/python/security/TaintTracking.qll b/python/ql/src/semmle/python/security/TaintTracking.qll index 6d37c011dcc..291ef08b17f 100755 --- a/python/ql/src/semmle/python/security/TaintTracking.qll +++ b/python/ql/src/semmle/python/security/TaintTracking.qll @@ -134,7 +134,7 @@ abstract class TaintKind extends string { */ final predicate taints(ControlFlowNode expr) { exists(TaintedNode n | - n.getTaintKind() = this and n.getNode() = expr + n.getTaintKind() = this and n.getCfgNode() = expr ) } @@ -247,15 +247,15 @@ module SequenceKind { predicate flowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { tonode.(BinaryExprNode).getAnOperand() = fromnode or - TaintFlowImplementation::copyCall(fromnode, tonode) + Implementation::copyCall(fromnode, tonode) or sequence_call(fromnode, tonode) or - sequence_subscript_slice(fromnode, tonode) + subscript_slice(fromnode, tonode) } predicate itemFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - sequence_subscript_index(fromnode, tonode) + subscript_index(fromnode, tonode) } } @@ -263,14 +263,14 @@ module SequenceKind { /* Helper for sequence flow steps */ pragma [noinline] -private predicate sequence_subscript_index(ControlFlowNode obj, SubscriptNode sub) { +private predicate subscript_index(ControlFlowNode obj, SubscriptNode sub) { sub.isLoad() and sub.getValue() = obj and not sub.getNode().getIndex() instanceof Slice } pragma [noinline] -private predicate sequence_subscript_slice(ControlFlowNode obj, SubscriptNode sub) { +private predicate subscript_slice(ControlFlowNode obj, SubscriptNode sub) { sub.isLoad() and sub.getValue() = obj and sub.getNode().getIndex() instanceof Slice @@ -305,27 +305,18 @@ class DictKind extends CollectionKind { } override predicate isResultOfStep(TaintKind fromkind, ControlFlowNode fromnode, ControlFlowNode tonode) { - DictKind::flowStep(fromnode, tonode) and this = fromkind + Implementation::copyCall(fromnode, tonode) and this = fromkind + or + tonode.(CallNode).getFunction().pointsTo(ObjectInternal::builtin("dict")) and + tonode.(CallNode).getArg(0) = fromnode or dict_construct(fromnode, tonode) and this.getValue() = fromkind } -} - - -module DictKind { - - predicate flowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - TaintFlowImplementation::copyCall(fromnode, tonode) + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + subscript_index(fromnode, tonode) and result = this.getValue() or - tonode.(CallNode).getFunction().pointsTo(ObjectInternal::builtin("dict")) and - tonode.(CallNode).getArg(0) = fromnode - } - - predicate valueFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - tonode.(SubscriptNode).getValue() = fromnode and tonode.isLoad() - or - tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode + subscript_slice(fromnode, tonode) and result = this } } @@ -358,16 +349,6 @@ abstract class Sanitizer extends string { } -/** Hold if `sanitizer` is valid. A sanitizer is valid if there is - * a `TaintTracking::Configuration` that declares `sanitizer` or - * there are no `TaintTracking::Configuration`s. - */ -private predicate valid_sanitizer(Sanitizer sanitizer) { - not exists(TaintTracking::Configuration c) - or - exists(TaintTracking::Configuration c | c.isSanitizer(sanitizer)) -} - /** DEPRECATED -- Use DataFlowExtension instead. * An extension to taint-flow. For adding library or framework specific flows. * Examples include flow from a request to untrusted part of that request or @@ -418,8 +399,8 @@ abstract class TaintSource extends @py_flow_node { * * The smaller this predicate is, the faster `Taint.flowsTo()` will converge. */ - predicate isSourceOf(TaintKind kind, CallContext context) { - context.appliesTo(this) and this.isSourceOf(kind) + predicate isSourceOf(TaintKind kind, TaintTrackingContext context) { + context.isTop() and this.isSourceOf(kind) } Location getLocation() { @@ -432,28 +413,26 @@ abstract class TaintSource extends @py_flow_node { /** Gets a TaintedNode for this taint source */ TaintedNode getATaintNode() { - exists(TaintFlowImplementation::TrackedTaint taint, CallContext context | - this.isSourceOf(taint.getKind(), context) and - result = TTaintedNode_(taint, context, this) - ) + result.getCfgNode() = this and + this.isSourceOf(result.getTaintKind(), result.getContext()) and + result.getPath().noAttribute() } /** Holds if taint can flow from this source to sink `sink` */ final predicate flowsToSink(TaintKind srckind, TaintSink sink) { - exists(TaintedNode t | - t = this.getATaintNode() and - t.getTaintKind() = srckind and - t.flowsToSink(sink) + exists(TaintedNode src, TaintedNode tsink | + src = this.getATaintNode() and + src.getASuccessor*() = tsink and + this.isSourceOf(srckind, _) and + sink = tsink.getCfgNode() and + sink.sinks(tsink.getTaintKind()) and + tsink.getPath().noAttribute() ) } /** Holds if taint can flow from this source to taint sink `sink` */ final predicate flowsToSink(TaintSink sink) { this.flowsToSink(_, sink) - or - this instanceof ValidatingTaintSource and - sink instanceof ValidatingTaintSink and - exists(error()) } } @@ -480,8 +459,8 @@ abstract class TaintedDefinition extends EssaNodeDefinition { * * The smaller this predicate is, the faster `Taint.flowsTo()` will converge. */ - predicate isSourceOf(TaintKind kind, CallContext context) { - context.appliesToScope(this.getScope()) and this.isSourceOf(kind) + predicate isSourceOf(TaintKind kind, TaintTrackingContext context) { + context.isTop() and this.isSourceOf(kind) } } @@ -627,146 +606,6 @@ module DataFlowExtension { } } -private newtype TTaintedNode = - TTaintedNode_(TaintFlowImplementation::TrackedValue taint, CallContext context, ControlFlowNode n) { - exists(TaintKind kind | - taint = TaintFlowImplementation::TTrackedTaint(kind) | - n.(TaintSource).isSourceOf(kind, context) - ) - or - exists(DataFlow::Configuration config, TaintKind kind | - taint = TaintFlowImplementation::TTrackedTaint(kind) and - config.isSource(n) and context.getDepth() = 0 and - kind instanceof DataFlowType - ) - or - TaintFlowImplementation::step(_, taint, context, n) and - exists(TaintKind kind | - kind = taint.(TaintFlowImplementation::TrackedTaint).getKind() - or - kind = taint.(TaintFlowImplementation::TrackedAttribute).getKind(_) | - not exists(Sanitizer sanitizer | - valid_sanitizer(sanitizer) and - sanitizer.sanitizingNode(kind, n) - ) - ) - or - user_tainted_def(_, taint, context, n) - } - -private predicate user_tainted_def(TaintedDefinition def, TaintFlowImplementation::TTrackedTaint taint, CallContext context, ControlFlowNode n) { - exists(TaintKind kind | - taint = TaintFlowImplementation::TTrackedTaint(kind) and - def.isSourceOf(kind, context) and - n = def.getDefiningNode() - ) -} - -/** A tainted data flow graph node. - * This is a triple of `(CFG node, data-flow context, taint)` - */ -class TaintedNode extends TTaintedNode { - - string toString() { result = this.getTrackedValue().repr() } - - string debug() { result = this.getTrackedValue().toString() + " at " + this.getNode().getLocation() } - - TaintedNode getASuccessor() { - exists(TaintFlowImplementation::TrackedValue tokind, CallContext tocontext, ControlFlowNode tonode | - result = TTaintedNode_(tokind, tocontext, tonode) and - TaintFlowImplementation::step(this, tokind, tocontext, tonode) - ) - } - - /** Gets the taint for this node. */ - TaintFlowImplementation::TrackedValue getTrackedValue() { - this = TTaintedNode_(result, _, _) - } - - /** Gets the CFG node for this node. */ - ControlFlowNode getNode() { - this = TTaintedNode_(_, _, result) - } - - /** Get the AST node for this node. */ - AstNode getAstNode() { - result = this.getNode().getNode() - } - - /** Gets the CFG node for this node. */ - ControlFlowNode getCfgNode() { - this = TTaintedNode_(_, _, result) - } - - /** Gets the Dataflow node for this node. */ - DataFlow::Node getDataFlowNode() { - /* FIX ME! -- Needs to handle ESSA nodes as well */ - exists(ControlFlowNode cfgnode | - this = TTaintedNode_(_, _, cfgnode) and - result.asCfgNode() = cfgnode - ) - } - - /** Gets the data-flow context for this node. */ - CallContext getContext() { - this = TTaintedNode_(_, result, _) - } - - Location getLocation() { - result = this.getNode().getLocation() - } - - /** Holds if this node is a source of taint */ - predicate isSource() { - exists(TaintFlowImplementation::TrackedTaint taint, CallContext context, TaintSource node | - this = TTaintedNode_(taint, context, node) and - node.isSourceOf(taint.getKind(), context) - ) - } - - /** Gets the kind of taint that node is tainted with. - * Doesn't apply if an attribute or item is tainted, only if this node directly tainted - * */ - TaintKind getTaintKind() { - this.getTrackedValue().(TaintFlowImplementation::TrackedTaint).getKind() = result - } - - /** Holds if taint flows from this node to the sink `sink` and - * reaches with a taint that `sink` is a sink of. - */ - predicate flowsToSink(TaintSink sink) { - exists(TaintedNode node | - this.getASuccessor*() = node and - node.getNode() = sink and - sink.sinks(node.getTaintKind()) - ) - } - - /** Holds if the underlying CFG node for this node is a vulnerable node - * and is vulnerable to this node's taint. - */ - predicate isSink() { - exists(TaintedNode src, TaintSink vuln | - src.isSource() and - src.getASuccessor*() = this and - vuln = this.getNode() and - vuln.sinks(this.getTaintKind()) - ) - } - - /** DEPRECATED -- Use `TaintedNode.isSink()` instead - * Sinks are not necessarily vulnerable - * For removal 2020-07-01 */ - deprecated predicate isVulnerableSink() { - this.isSink() - } - - TaintFlowImplementation::TrackedTaint fromAttribute(string name) { - result = this.getTrackedValue().(TaintFlowImplementation::TrackedAttribute).fromAttribute(name) - } - -} - class TaintedPathSource extends TaintTrackingNode { TaintedPathSource() { @@ -796,839 +635,13 @@ class TaintedPathSink extends TaintTrackingNode { } -/** This module contains the implementation of taint-flow. - * It is recommended that users use the `TaintedNode` class, rather than using this module directly - * as the interface of this module may change without warning. - */ -library module TaintFlowImplementation { - - import semmle.python.pointsto.PointsTo - import DataFlowExtension - - newtype TTrackedValue = - TTrackedTaint(TaintKind kind) - or - TTrackedAttribute(string name, TaintKind kind) { - exists(AttributeAssignment def, TaintedNode origin | - def.getName() = name and - def.getValue() = origin.getNode() and - origin.getTaintKind() = kind - ) - or - exists(TaintedNode origin | - import_flow(origin, _, _, name) and - origin.getTaintKind() = kind - ) - or - exists(TaintKind src | - kind = src.getTaintOfAttribute(name) - ) - or - exists(TaintedNode origin, AttrNode lhs, ControlFlowNode rhs | - lhs.getName() = name and rhs = lhs.(DefinitionNode).getValue() | - origin.getNode() = rhs and - kind = origin.getTaintKind() - ) - } - - /** The "taint" tracked internal by the TaintFlow module. - * This is not the taint kind specified by the user, but describes both the kind of taint - * and how that taint relates to any object referred to by a data-flow graph node or edge. - */ - class TrackedValue extends TTrackedValue { - - abstract string toString(); - - abstract string repr(); - - abstract TrackedValue toKind(TaintKind kind); - - } - - class TrackedTaint extends TrackedValue, TTrackedTaint { - - override string repr() { - result = this.getKind().repr() - } - - override string toString() { - result = "Taint " + this.getKind() - } - - TaintKind getKind() { - this = TTrackedTaint(result) - } - - override TrackedValue toKind(TaintKind kind) { - result = TTrackedTaint(kind) - } - - } - - class TrackedAttribute extends TrackedValue, TTrackedAttribute { - - override string repr() { - exists(string name, TaintKind kind | - this = TTrackedAttribute(name, kind) and - result = "." + name + "=" + kind.repr() - ) - } - - override string toString() { - exists(string name, TaintKind kind | - this = TTrackedAttribute(name, kind) and - result = "Attribute '" + name + "' taint " + kind - ) - } - - TaintKind getKind(string name) { - this = TTrackedAttribute(name, result) - } - - TrackedValue fromAttribute(string name) { - exists(TaintKind kind | - this = TTrackedAttribute(name, kind) and - result = TTrackedTaint(kind) - ) - } - - string getName() { - this = TTrackedAttribute(result, _) - } - - override TrackedValue toKind(TaintKind kind) { - result = TTrackedAttribute(this.getName(), kind) - } - - } - - predicate step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, ControlFlowNode tonode) { - unpruned_step(fromnode, totaint, tocontext, tonode) and - tonode.getBasicBlock().likelyReachable() - } - - predicate unpruned_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, ControlFlowNode tonode) { - import_step(fromnode, totaint, tocontext, tonode) - or - from_import_step(fromnode, totaint, tocontext, tonode) - or - attribute_load_step(fromnode, totaint, tocontext, tonode) - or - attribute_store_step(fromnode, totaint, tocontext, tonode) - or - getattr_step(fromnode, totaint, tocontext, tonode) - or - use_step(fromnode, totaint, tocontext, tonode) - or - call_taint_step(fromnode, totaint, tocontext, tonode) - or - iteration_step(fromnode, totaint, tocontext, tonode) - or - yield_step(fromnode, totaint, tocontext, tonode) - or - exists(DataFlowNode fromnodenode | - fromnodenode = fromnode.getNode() and - ( - not exists(TaintTracking::Configuration c) - or - exists(TaintTracking::Configuration c | c.isExtension(fromnodenode)) - ) - | - fromnodenode.getASuccessorNode() = tonode and - fromnode.getContext() = tocontext and - totaint = fromnode.getTrackedValue() - or - exists(CallNode call | - fromnodenode.getAReturnSuccessorNode(call) = tonode and - fromnode.getContext() = tocontext.getCallee(call) and - totaint = fromnode.getTrackedValue() - ) - or - exists(CallNode call | - fromnodenode.getACalleeSuccessorNode(call) = tonode and - fromnode.getContext().getCallee(call) = tocontext and - totaint = fromnode.getTrackedValue() - ) - or - exists(TaintKind tokind | - fromnodenode.getASuccessorNode(fromnode.getTaintKind(), tokind) = tonode and - totaint = fromnode.getTrackedValue().toKind(tokind) and - tocontext = fromnode.getContext() - ) - ) - or - exists(TaintKind tokind | - tokind = fromnode.getTaintKind().getTaintForFlowStep(fromnode.getNode(), tonode) and - totaint = fromnode.getTrackedValue().toKind(tokind) and - tocontext = fromnode.getContext() - ) - or - exists(SequenceKind fromkind | - fromkind = fromnode.getTaintKind() and - tocontext = fromnode.getContext() | - totaint = fromnode.getTrackedValue() and SequenceKind::flowStep(fromnode.getNode(), tonode) - or - totaint = fromnode.getTrackedValue().toKind(fromkind.getItem()) and SequenceKind::itemFlowStep(fromnode.getNode(), tonode) - ) - or - exists(DictKind fromkind | - fromkind = fromnode.getTaintKind() and - tocontext = fromnode.getContext() | - totaint = fromnode.getTrackedValue() and DictKind::flowStep(fromnode.getNode(), tonode) - or - totaint = fromnode.getTrackedValue().toKind(fromkind.getValue()) and DictKind::valueFlowStep(fromnode.getNode(), tonode) - ) - or - exists(TaintFlow flow, TaintKind tokind | - flow.additionalFlowStep(fromnode.getNode(), fromnode.getTaintKind(), tonode, tokind) and - totaint = fromnode.getTrackedValue().toKind(tokind) and - tocontext = fromnode.getContext() - ) - or - data_flow_step(fromnode.getContext(), fromnode.getNode(), tocontext, tonode) and - totaint = fromnode.getTrackedValue() - or - exists(DataFlowVariable var | - tainted_var(var, tocontext, fromnode) and - var.getASuccessorNode() = tonode and - totaint = fromnode.getTrackedValue() - ) - or - exists(TaintKind tokind | - totaint = fromnode.getTrackedValue().toKind(tokind) and - tocontext = fromnode.getContext() - | - tokind.(DictKind).getValue() = fromnode.getTaintKind() and - dict_construct(fromnode.getNode(), tonode) - or - tokind.(SequenceKind).getItem() = fromnode.getTaintKind() and - sequence_construct(fromnode.getNode(), tonode) - ) - } - - pragma [noinline] - predicate import_step(TaintedNode fromnode, TrackedAttribute totaint, CallContext tocontext, ImportExprNode tonode) { - exists(string name | - import_flow(fromnode, tonode, tocontext, name) and - totaint.fromAttribute(name) = fromnode.getTrackedValue() - ) - } - - pragma [noinline] - private predicate import_flow(TaintedNode fromnode, ImportExprNode tonode, CallContext tocontext, string name) { - exists(ModuleValue mod | - tonode.pointsTo(mod) and - module_attribute_tainted(mod, name, fromnode) and - tocontext.appliesTo(tonode) - ) - } - - pragma [noinline] - predicate data_flow_step(CallContext fromcontext, ControlFlowNode fromnode, CallContext tocontext, ControlFlowNode tonode) { - if_exp_step(fromcontext, fromnode, tocontext, tonode) - or - call_flow_step(fromcontext, fromnode, tocontext, tonode) - or - parameter_step(fromcontext, fromnode, tocontext, tonode) - } - - pragma [noinline] - predicate from_import_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, ControlFlowNode tonode) { - exists(string name, ImportExprNode fmod, ModuleValue mod | - fmod = tonode.(ImportMemberNode).getModule(name) and - fmod.pointsTo(mod) and - tocontext.appliesTo(tonode) and - module_attribute_tainted(mod, name, fromnode) and - totaint = fromnode.getTrackedValue() - ) - } - - pragma [noinline] - predicate getattr_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, CallNode tonode) { - exists(ControlFlowNode arg, string name | - tonode.getFunction().pointsTo(ObjectInternal::builtin("getattr")) and - arg = tonode.getArg(0) and - name = tonode.getArg(1).getNode().(StrConst).getText() and - arg = fromnode.getNode() and - totaint = fromnode.fromAttribute(name) and - tocontext = fromnode.getContext() - ) - } - - pragma [noinline] - predicate attribute_load_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, AttrNode tonode) { - tonode.isLoad() and - exists(string name, ControlFlowNode f | - f = tonode.getObject(name) and - tocontext = fromnode.getContext() and - f = fromnode.getNode() and - ( - totaint = TTrackedTaint(fromnode.getTaintKind().getTaintOfAttribute(name)) - or - totaint = fromnode.fromAttribute(name) - ) - ) - } - - pragma [noinline] - predicate attribute_store_step(TaintedNode fromnode, TrackedAttribute totaint, CallContext tocontext, ControlFlowNode tonode) { - exists(string name | - attribute_store_flow(fromnode.getNode(), tonode, name) and - totaint.fromAttribute(name) = fromnode.getTrackedValue() - ) and - tocontext = fromnode.getContext() - } - - pragma [noinline] - private predicate attribute_store_flow(ControlFlowNode fromnode, ControlFlowNode tonode, string name) { - exists(AttrNode lhs | - tonode = lhs.getObject(name) and fromnode = lhs.(DefinitionNode).getValue() - ) - } - - predicate module_attribute_tainted(ModuleValue m, string name, TaintedNode origin) { - exists(EssaVariable var, CallContext c | - var.getName() = name and - BaseFlow::reaches_exit(var) and - var.getScope() = m.getScope() and - tainted_var(var, c, origin) and - c = TTop() - ) - } - - predicate use_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, ControlFlowNode tonode) { - exists(EssaVariable var | - var.getASourceUse() = tonode and - tainted_var(var, tocontext, fromnode) and - totaint = fromnode.getTrackedValue() - ) - } - - pragma [noinline] - predicate call_flow_step(CallContext callee, ControlFlowNode fromnode, CallContext caller, ControlFlowNode call) { - exists(PyFunctionObject func | - callee.appliesToScope(func.getFunction()) and - func.getACall() = call and - func.getAReturnedNode() = fromnode | - callee = caller.getCallee(call) - or - caller = callee and caller = TTop() - ) - } - - predicate yield_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, CallNode call) { - exists(PyFunctionObject func | - func.getFunction().isGenerator() and - func.getACall() = call and - ( - fromnode.getContext() = tocontext.getCallee(call) - or - fromnode.getContext() = tocontext and tocontext = TTop() - ) and - exists(Yield yield | - yield.getScope() = func.getFunction() and - yield.getValue() = fromnode.getNode().getNode() - ) and - exists(SequenceKind seq | - seq.getItem() = fromnode.getTaintKind() and - totaint = fromnode.getTrackedValue().toKind(seq) - ) - ) - } - - predicate call_taint_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, CallNode call) { - exists(string name | - call.getFunction().(AttrNode).getObject(name) = fromnode.getNode() and - totaint = TTrackedTaint(fromnode.getTaintKind().getTaintOfMethodResult(name)) and - tocontext = fromnode.getContext() - ) - or - exists(EssaVariable self, CallContext callee | - self_init_end_transfer(self, callee, call, tocontext) and - tainted_var(self, callee, fromnode) and - totaint = fromnode.getTrackedValue() - ) - } - - /** Holds if `v` is defined by a `for` statement, the definition being `defn` */ - cached predicate iteration_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, ForNode for) { - for.iterates(_, fromnode.getNode()) and - totaint = TTrackedTaint(fromnode.getTaintKind().getTaintForIteration()) and - tocontext = fromnode.getContext() - } - - predicate self_init_end_transfer(EssaVariable self, CallContext callee, CallNode call, CallContext caller) { - exists(ClassValue cls, Function init | - call.getFunction().pointsTo(cls) and - init = cls.lookup("__init__").(CallableValue).getScope() and - self.getSourceVariable().(Variable).isSelf() and self.getScope() = init - | - callee = caller.getCallee(call) - or - caller = callee and caller = TTop() - ) - } - - predicate tainted_var(EssaVariable var, CallContext context, TaintedNode origin) { - tainted_def(var.getDefinition(), context, origin) - or - exists(EssaVariable prev | - tainted_var(prev, context, origin) and - prev.(DataFlowVariable).getASuccessorVariable() = var - ) - or - exists(DataFlowNode originnode | - originnode = origin.getNode() and - ( - not exists(TaintTracking::Configuration c) - or - exists(TaintTracking::Configuration c | c.isExtension(originnode)) - ) and - originnode.getASuccessorVariable() = var and - context = origin.getContext() - ) - or - exists(TrackedTaint taint, EssaVariable prev | - tainted_var(prev, context, origin) and - origin.getTrackedValue() = taint and - taint.getKind().additionalFlowStepVar(prev, var) - ) - or - exists(TaintFlow flow, TrackedTaint taint, EssaVariable prev | - tainted_var(prev, context, origin) and - origin.getTrackedValue() = taint and - flow.additionalFlowStepVar(prev, var, taint.getKind()) - ) - } - - predicate tainted_def(EssaDefinition def, CallContext context, TaintedNode origin) { - unsanitized_tainted_def(def, context, origin) and - ( - origin.getTrackedValue() instanceof TrackedAttribute - or - exists(TaintKind kind | - kind = origin.getTaintKind() and - not exists(Sanitizer san | - valid_sanitizer(san) | - san.sanitizingDefinition(kind, def) - or - san.sanitizingNode(kind, def.(EssaNodeDefinition).getDefiningNode()) - or - san.sanitizingNode(kind, def.(EssaNodeRefinement).getDefiningNode()) - ) - ) - ) - } - - predicate unsanitized_tainted_def(EssaDefinition def, CallContext context, TaintedNode origin) { - exists(TrackedValue val, ControlFlowNode node | - user_tainted_def(def, val, context, node) and - origin = TTaintedNode_(val, context, node) - ) - or - tainted_phi(def, context, origin) - or - tainted_assignment(def, context, origin) - or - tainted_attribute_assignment(def, context, origin) - or - tainted_parameter_def(def, context, origin) - or - tainted_callsite(def, context, origin) - or - tainted_method_callsite(def, context, origin) - or - tainted_edge(def, context, origin) - or - tainted_argument(def, context, origin) - or - tainted_import_star(def, context, origin) - or - tainted_uni_edge(def, context, origin) - or - tainted_scope_entry(def, context, origin) - or - tainted_with(def, context, origin) - or - tainted_exception_capture(def, context, origin) - } - - predicate tainted_scope_entry(ScopeEntryDefinition def, CallContext context, TaintedNode origin) { - exists(EssaVariable var | - BaseFlow::scope_entry_value_transfer_from_earlier(var, _, def, _) and - tainted_var(var, context, origin) - ) - } - - pragma [noinline] - predicate tainted_phi(PhiFunction phi, CallContext context, TaintedNode origin) { - exists(BasicBlock pred, EssaVariable predvar | - predvar = phi.getInput(pred) and - tainted_var(predvar, context, origin) and - not pred.unlikelySuccessor(phi.getBasicBlock()) and - not predvar.(DataFlowExtension::DataFlowVariable).prunedSuccessor(phi.getVariable()) - ) - } - - pragma [noinline] - predicate tainted_assignment(AssignmentDefinition def, CallContext context, TaintedNode origin) { - origin.getNode() = def.getValue() and - context = origin.getContext() - } - - pragma [noinline] - predicate tainted_attribute_assignment(AttributeAssignment def, CallContext context, TaintedNode origin) { - context = origin.getContext() and - origin.getNode() = def.getDefiningNode().(AttrNode).getObject() - } - - pragma [noinline] - predicate tainted_callsite(CallsiteRefinement call, CallContext context, TaintedNode origin) { - /* In the interest of simplicity and performance we assume that tainted escaping variables remain tainted across calls. - * In the cases were this assumption is false, it is easy enough to add an additional sanitizer. - */ - tainted_var(call.getInput(), context, origin) - } - - pragma [noinline] - predicate parameter_step(CallContext caller, ControlFlowNode argument, CallContext callee, NameNode param) { - exists(ParameterDefinition def | - def.getDefiningNode() = param and - exists(CallableValue func, CallNode call | - callee = caller.getCallee(call) | - exists(int n | param = func.getParameter(n) and argument = func.getArgumentForCall(call, n)) - or - exists(string name | param = func.getParameterByName(name) and argument = func.getNamedArgumentForCall(call, name)) - or - class_initializer_argument(call, func, argument, param) - ) - ) - } - - /* Helper for parameter_step */ - pragma [noinline] - private predicate class_initializer_argument(CallNode call, CallableValue func, ControlFlowNode argument, NameNode param) { - exists(ClassValue cls | - cls.getACall() = call and - cls.lookup("__init__") = func - ) and - exists(int n | - call.getArg(n) = argument and - param.getNode() = func.getScope().getArg(n+1) - ) - } - - pragma [noinline] - predicate tainted_parameter_def(ParameterDefinition def, CallContext context, TaintedNode fromnode) { - fromnode.getNode() = def.getDefiningNode() and - context = fromnode.getContext() - } - - pragma [noinline] - predicate if_exp_step(CallContext fromcontext, ControlFlowNode operand, CallContext tocontext, IfExprNode ifexp) { - fromcontext = tocontext and fromcontext.appliesTo(operand) and - ifexp.getAnOperand() = operand - } - - pragma [noinline] - predicate tainted_method_callsite(MethodCallsiteRefinement call, CallContext context, TaintedNode origin) { - tainted_var(call.getInput(), context, origin) and - exists(TaintKind kind | - kind = origin.getTaintKind() | - not exists(FunctionObject callee, Sanitizer sanitizer | - valid_sanitizer(sanitizer) and - callee.getACall() = call.getCall() and - sanitizer.sanitizingCall(kind, callee) - ) - ) - } - - pragma [noinline] - predicate tainted_edge(PyEdgeRefinement test, CallContext context, TaintedNode origin) { - exists(EssaVariable var, TaintKind kind | - kind = origin.getTaintKind() and - var = test.getInput() and - tainted_var(var, context, origin) and - not exists(Sanitizer sanitizer | - valid_sanitizer(sanitizer) and - sanitizer.sanitizingEdge(kind, test) - ) - | - not Filters::isinstance(test.getTest(), _, var.getSourceVariable().getAUse()) and - not boolean_filter(test.getTest(), var.getSourceVariable().getAUse()) - or - exists(ControlFlowNode c, ClassValue cls | - Filters::isinstance(test.getTest(), c, var.getSourceVariable().getAUse()) - and c.pointsTo(cls) - | - test.getSense() = true and not exists(kind.getClass()) - or - test.getSense() = true and kind.getType().getASuperType() = cls - or - test.getSense() = false and not kind.getType().getASuperType() = cls - ) - or - test.getSense() = test_evaluates(test.getTest(), var.getSourceVariable().getAUse(), kind) - ) - } - - /** Gets the operand of a unary `not` expression. */ - private ControlFlowNode not_operand(ControlFlowNode expr) { - expr.(UnaryExprNode).getNode().getOp() instanceof Not and - result = expr.(UnaryExprNode).getOperand() - } - - /** Holds if `test` is the test in a branch and `use` is that test - * with all the `not` prefixes removed. - */ - private predicate boolean_filter(ControlFlowNode test, ControlFlowNode use) { - any(PyEdgeRefinement ref).getTest() = test and - ( - use = test - or - exists(ControlFlowNode notuse | - boolean_filter(test, notuse) and - use = not_operand(notuse) - ) - ) - } - - /** Gets the boolean value that `test` evaluates to when `use` is tainted with `kind` - * and `test` and `use` are part of a test in a branch. - */ - private boolean test_evaluates(ControlFlowNode test, ControlFlowNode use, TaintKind kind) { - boolean_filter(_, use) and - kind.taints(use) and - test = use and result = kind.booleanValue() - or - result = test_evaluates(not_operand(test), use, kind).booleanNot() - } - - pragma [noinline] - predicate tainted_argument(ArgumentRefinement def, CallContext context, TaintedNode origin) { - tainted_var(def.getInput(), context, origin) - } - - pragma [noinline] - predicate tainted_import_star(ImportStarRefinement def, CallContext context, TaintedNode origin) { - exists(ModuleValue mod, string name | - PointsTo::pointsTo(def.getDefiningNode().(ImportStarNode).getModule(), _, mod, _) and - name = def.getSourceVariable().getName() | - if mod.exports(name) then ( - /* Attribute from imported module */ - module_attribute_tainted(mod, name, origin) and - context.appliesTo(def.getDefiningNode()) - ) else ( - /* Retain value held before import */ - exists(EssaVariable var | - var = def.getInput() and - tainted_var(var, context, origin) - ) - ) - ) - } - - pragma [noinline] - predicate tainted_uni_edge(SingleSuccessorGuard uniphi, CallContext context, TaintedNode origin) { - exists(EssaVariable var, TaintKind kind | - kind = origin.getTaintKind() and - var = uniphi.getInput() and - tainted_var(var, context, origin) and - not exists(Sanitizer sanitizer | - valid_sanitizer(sanitizer) and - sanitizer.sanitizingSingleEdge(kind, uniphi) - ) - ) - } - - pragma [noinline] - predicate tainted_with(WithDefinition def, CallContext context, TaintedNode origin) { - with_flow(_, origin.getNode(),def.getDefiningNode()) and - context = origin.getContext() - } - - pragma [noinline] - predicate tainted_exception_capture(ExceptionCapture def, CallContext context, TaintedNode fromnode) { - fromnode.getNode() = def.getDefiningNode() and - context = fromnode.getContext() - } - - - /* A call that returns a copy (or similar) of the argument */ - predicate copyCall(ControlFlowNode fromnode, CallNode tonode) { - tonode.getFunction().(AttrNode).getObject("copy") = fromnode - or - exists(ModuleObject copy, string name | - name = "copy" or name = "deepcopy" | - copy.attr(name).(FunctionObject).getACall() = tonode and - tonode.getArg(0) = fromnode - ) - or - tonode.getFunction().pointsTo(ObjectInternal::builtin("reversed")) and - tonode.getArg(0) = fromnode - } - -} - -/* Helper predicate for tainted_with */ -private predicate with_flow(With with, ControlFlowNode contextManager, ControlFlowNode var) { - with.getContextExpr() = contextManager.getNode() and - with.getOptionalVars() = var.getNode() and - contextManager.strictlyDominates(var) -} - -/* "Magic" sources and sinks which only have `toString()`s when - * no sources are defined or no sinks are defined or no kinds are present. - * In those cases, these classes make sure that an informative error - * message is presented to the user. - */ - -library class ValidatingTaintSource extends TaintSource { - - override string toString() { - result = error() - } - - ValidatingTaintSource() { - this = uniqueCfgNode() - } - - override predicate isSourceOf(TaintKind kind) { none() } - - override predicate hasLocationInfo(string fp, int bl, int bc, int el, int ec) { - fp = error() and bl = 0 and bc = 0 and el = 0 and ec = 0 - } - - -} - -library class ValidatingTaintSink extends TaintSink { - - override string toString() { - result = error() - } - - ValidatingTaintSink() { - this = uniqueCfgNode() - } - - override predicate sinks(TaintKind kind) { none() } - - override predicate hasLocationInfo(string fp, int bl, int bc, int el, int ec) { - fp = error() and bl = 0 and bc = 0 and el = 0 and ec = 0 - } - -} - +/* Backwards compatible name */ +class TaintedNode = TaintTrackingNode; /* Helpers for Validating classes */ -private string locatable_module_name() { - exists(Module m | - exists(m.getLocation()) and - result = m.getName() - ) -} - -private ControlFlowNode uniqueCfgNode() { - exists(Module m | - result = m.getEntryNode() and - m.getName() = min(string name | name = locatable_module_name()) - ) -} - -private string error() { - forall(TaintSource s | s instanceof ValidatingTaintSource) and - result = "No sources defined" - or - forall(TaintSink s | s instanceof ValidatingTaintSink) and - result = "No sinks defined" -} - - -private newtype TCallContext = - TTop() - or - TCalleeContext(CallNode call, CallContext caller, int depth) { - caller.appliesToScope(call.getScope()) and - depth = caller.getDepth() + 1 and depth < 7 and - exists(TaintedNode n | - n = TTaintedNode_(_, caller, call.getAnArg()) - ) - } - private import semmle.python.pointsto.PointsTo -pragma [inline] -private string shortLocation(Location l) { - result = l.getFile().getShortName() + ":" + l.getStartLine() -} - -/** Call context for use in taint-tracking. - * Using call contexts prevents "cross talk" between different calls - * to the same function. For example, if a function f is defined as - * ```python - * def f(arg): - * return arg - * ``` - * Then `f("tainted")` is "tainted", but `f("ok") is "ok". - */ -class CallContext extends TCallContext { - - string toString() { - this = TTop() and result = "" - or - exists(CallNode callsite, CallContext caller | - this = TCalleeContext(callsite, caller, _) | - result = shortLocation(callsite.getLocation()) + " from " + caller.toString() and caller = TCalleeContext(_, _, _) - or - result = shortLocation(callsite.getLocation()) and caller = TTop() - ) - } - - /** Holds if this context can apply to `n`. - */ - pragma[inline] - predicate appliesTo(ControlFlowNode n) { - this.appliesToScope(n.getScope()) - } - - /** Holds if this context can apply to `s` - */ - predicate appliesToScope(Scope s) { - this = TTop() - or - exists(FunctionObject f, CallNode call | - this = TCalleeContext(call, _, _) and - f.getFunction() = s and f.getACall() = call - ) - or - exists(ClassValue cls, CallNode call | - this = TCalleeContext(call, _, _) and - call.getFunction().pointsTo(cls) and - s = cls.lookup("__init__").(CallableValue).getScope() and - call.getFunction().pointsTo(cls) - ) - } - - /** Gets the call depth of this context. - */ - int getDepth() { - this = TTop() and result = 0 - or - this = TCalleeContext(_, _, result) - } - - CallContext getCallee(CallNode call) { - result = TCalleeContext(call, this, _) - } - - CallContext getCaller() { - this = TCalleeContext(_, result, _) - } - -} - /** Data flow module providing an interface compatible with * the other language implementations. @@ -1658,8 +671,8 @@ module DataFlow { predicate hasFlow(ControlFlowNode source, ControlFlowNode sink) { exists(TaintedNode psource, TaintedNode psink | - psource.getNode() = source and - psink.getNode() = sink and + psource.getCfgNode() = source and + psink.getCfgNode() = sink and this.isSource(source) and this.isSink(sink) and this.hasFlowPath(psource, psink) @@ -1802,3 +815,24 @@ private predicate sequence_call(ControlFlowNode fromnode, CallNode tonode) { ) } + +class LegacyConfiguration extends TaintTracking::Configuration { + + LegacyConfiguration() { this = "Legacy configuration" } + + override predicate isSource(DataFlow::Node source, TaintKind kind) { + exists(TaintSource src | + source.asCfgNode() = src and + src.isSourceOf(kind) + ) + } + + override predicate isSink(DataFlow::Node sink, TaintKind kind) { + exists(TaintSink snk | + sink.asCfgNode() = snk and + snk.sinks(kind) + ) + } + +} + diff --git a/python/ql/src/semmle/python/web/Http.qll b/python/ql/src/semmle/python/web/Http.qll index 1b37cc035b5..02d1f78494b 100644 --- a/python/ql/src/semmle/python/web/Http.qll +++ b/python/ql/src/semmle/python/web/Http.qll @@ -1,5 +1,5 @@ import python -import semmle.python.security.TaintTracking +import semmle.python.dataflow.Implementation import semmle.python.security.strings.External import HttpConstants @@ -16,7 +16,7 @@ class WsgiEnvironment extends TaintKind { WsgiEnvironment() { this = "wsgi.environment" } override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - result = this and TaintFlowImplementation::copyCall(fromnode, tonode) + result = this and Implementation::copyCall(fromnode, tonode) or result = this and tonode.(CallNode).getFunction().refersTo(theDictType()) and diff --git a/python/ql/test/library-tests/taint/config/RockPaperScissors.expected b/python/ql/test/library-tests/taint/config/RockPaperScissors.expected index 440e7aedf25..afc5d7fd063 100644 --- a/python/ql/test/library-tests/taint/config/RockPaperScissors.expected +++ b/python/ql/test/library-tests/taint/config/RockPaperScissors.expected @@ -1,37 +1,234 @@ edges -| carrier.py:21:5:21:5 | explicit.carrier at carrier.py:21 | carrier.py:22:10:22:10 | explicit.carrier at carrier.py:22 | -| carrier.py:21:9:21:28 | explicit.carrier at carrier.py:21 | carrier.py:21:5:21:5 | explicit.carrier at carrier.py:21 | -| carrier.py:22:10:22:10 | explicit.carrier at carrier.py:22 | carrier.py:22:10:22:22 | simple.test at carrier.py:22 | -| rockpaperscissors.py:24:5:24:5 | rock at rockpaperscissors.py:24 | rockpaperscissors.py:25:9:25:9 | rock at rockpaperscissors.py:25 | -| rockpaperscissors.py:24:9:24:12 | rock at rockpaperscissors.py:24 | rockpaperscissors.py:24:5:24:5 | rock at rockpaperscissors.py:24 | -| rockpaperscissors.py:25:5:25:5 | paper at rockpaperscissors.py:25 | rockpaperscissors.py:26:14:26:14 | paper at rockpaperscissors.py:26 | -| rockpaperscissors.py:25:9:25:9 | rock at rockpaperscissors.py:25 | rockpaperscissors.py:25:9:25:16 | scissors at rockpaperscissors.py:25 | -| rockpaperscissors.py:25:9:25:16 | scissors at rockpaperscissors.py:25 | rockpaperscissors.py:25:9:25:23 | paper at rockpaperscissors.py:25 | -| rockpaperscissors.py:25:9:25:23 | paper at rockpaperscissors.py:25 | rockpaperscissors.py:25:5:25:5 | paper at rockpaperscissors.py:25 | -| test.py:6:5:6:5 | simple.test at test.py:6 | test.py:7:10:7:10 | simple.test at test.py:7 | -| test.py:6:9:6:14 | simple.test at test.py:6 | test.py:6:5:6:5 | simple.test at test.py:6 | -| test.py:12:10:12:12 | simple.test at test.py:12 | test.py:13:10:13:12 | simple.test at test.py:13 | -| test.py:20:5:20:5 | simple.test at test.py:20 | test.py:21:10:21:10 | simple.test at test.py:21 | -| test.py:20:9:20:14 | simple.test at test.py:20 | test.py:20:5:20:5 | simple.test at test.py:20 | -| test.py:21:10:21:10 | simple.test at test.py:21 | test.py:12:10:12:12 | simple.test at test.py:12 | -| test.py:37:9:37:9 | simple.test at test.py:37 | test.py:41:14:41:14 | simple.test at test.py:41 | -| test.py:37:13:37:18 | simple.test at test.py:37 | test.py:37:9:37:9 | simple.test at test.py:37 | -| test.py:49:17:49:19 | simple.test at test.py:49 | test.py:51:14:51:16 | simple.test at test.py:51 | -| test.py:51:14:51:16 | simple.test at test.py:51 | test.py:12:10:12:12 | simple.test at test.py:12 | -| test.py:62:9:62:9 | simple.test at test.py:62 | test.py:63:5:63:9 | simple.test at test.py:63 | -| test.py:62:13:62:18 | simple.test at test.py:62 | test.py:62:9:62:9 | simple.test at test.py:62 | -| test.py:63:5:63:9 | simple.test at test.py:63 | test.py:63:17:63:17 | simple.test at test.py:63 | -| test.py:63:17:63:17 | simple.test at test.py:63 | test.py:49:17:49:19 | simple.test at test.py:49 | -| test.py:67:9:67:9 | simple.test at test.py:67 | test.py:70:5:70:9 | simple.test at test.py:70 | -| test.py:67:13:67:18 | simple.test at test.py:67 | test.py:67:9:67:9 | simple.test at test.py:67 | -| test.py:70:5:70:9 | simple.test at test.py:70 | test.py:70:17:70:17 | simple.test at test.py:70 | -| test.py:70:17:70:17 | simple.test at test.py:70 | test.py:49:17:49:19 | simple.test at test.py:49 | -| test.py:126:9:126:9 | simple.test at test.py:126 | test.py:130:21:130:21 | simple.test at test.py:130 | -| test.py:126:13:126:25 | simple.test at test.py:126 | test.py:126:9:126:9 | simple.test at test.py:126 | -| test.py:128:9:128:9 | simple.test at test.py:128 | test.py:132:14:132:14 | simple.test at test.py:132 | -| test.py:128:13:128:18 | simple.test at test.py:128 | test.py:128:9:128:9 | simple.test at test.py:128 | +| carrier.py:13:9:13:11 | explicit.carrier | carrier.py:14:12:14:14 | explicit.carrier | +| carrier.py:14:12:14:14 | explicit.carrier | carrier.py:29:9:29:33 | explicit.carrier | +| carrier.py:21:9:21:28 | explicit.carrier | carrier.py:22:10:22:10 | explicit.carrier | +| carrier.py:22:10:22:10 | explicit.carrier | carrier.py:22:10:22:22 | simple.test | +| carrier.py:29:9:29:33 | explicit.carrier | carrier.py:30:10:30:10 | explicit.carrier | +| carrier.py:29:13:29:32 | explicit.carrier | carrier.py:13:9:13:11 | explicit.carrier | +| carrier.py:30:10:30:10 | explicit.carrier | carrier.py:30:10:30:22 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:12:12:12:18 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:15:12:15:18 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:18:12:18:18 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:17:8:17:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:20:5:20:14 | simple.test | +| deep.py:18:15:18:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:20:5:20:14 | simple.test | deep.py:22:6:22:6 | simple.test | +| deep.py:20:8:20:13 | simple.test | deep.py:17:8:17:10 | simple.test | +| rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:25:9:25:9 | rock | +| rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors | +| rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper | +| rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper | +| test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test | +| test.py:12:10:12:12 | simple.test | test.py:13:10:13:12 | simple.test | +| test.py:20:9:20:14 | simple.test | test.py:21:10:21:10 | simple.test | +| test.py:21:10:21:10 | simple.test | test.py:12:10:12:12 | simple.test | +| test.py:37:13:37:18 | simple.test | test.py:41:14:41:14 | simple.test | +| test.py:49:17:49:19 | simple.test | test.py:51:14:51:16 | simple.test | +| test.py:51:14:51:16 | simple.test | test.py:12:10:12:12 | simple.test | +| test.py:62:13:62:18 | simple.test | test.py:63:17:63:17 | simple.test | +| test.py:63:17:63:17 | simple.test | test.py:49:17:49:19 | simple.test | +| test.py:67:13:67:18 | simple.test | test.py:70:17:70:17 | simple.test | +| test.py:70:17:70:17 | simple.test | test.py:49:17:49:19 | simple.test | +| test.py:72:9:72:11 | simple.test | test.py:73:12:73:14 | simple.test | +| test.py:73:12:73:14 | simple.test | test.py:77:9:77:14 | simple.test | +| test.py:76:9:76:14 | simple.test | test.py:77:13:77:13 | simple.test | +| test.py:77:9:77:14 | simple.test | test.py:78:10:78:10 | simple.test | +| test.py:77:13:77:13 | simple.test | test.py:72:9:72:11 | simple.test | +| test.py:126:13:126:25 | simple.test | test.py:130:21:130:21 | simple.test | +| test.py:128:13:128:18 | simple.test | test.py:132:14:132:14 | simple.test | +| test.py:163:9:163:14 | simple.test | test.py:165:10:165:10 | simple.test | +| test.py:178:9:178:14 | simple.test | test.py:180:14:180:14 | simple.test | +| test.py:178:9:178:14 | simple.test | test.py:186:14:186:14 | simple.test | +| test.py:195:9:195:14 | simple.test | test.py:199:14:199:14 | simple.test | +| test.py:208:11:208:18 | sequence of simple.test | test.py:209:14:209:16 | sequence of simple.test | +| test.py:208:12:208:17 | simple.test | test.py:208:11:208:18 | sequence of simple.test | +| test.py:209:5:209:17 | simple.test | test.py:210:15:210:15 | simple.test | +| test.py:209:14:209:16 | sequence of simple.test | test.py:209:5:209:17 | simple.test | +| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | iterable.simple | +| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | sequence of simple.test | +| test.py:213:5:213:33 | simple.test | test.py:214:14:214:14 | simple.test | +| test.py:213:14:213:32 | iterable.simple | test.py:213:5:213:33 | simple.test | +| test.py:213:14:213:32 | sequence of simple.test | test.py:213:5:213:33 | simple.test | parents +| carrier.py:13:9:13:11 | explicit.carrier | carrier.py:29:13:29:32 | explicit.carrier | +| carrier.py:14:12:14:14 | explicit.carrier | carrier.py:29:13:29:32 | explicit.carrier | +| deep.py:2:8:2:10 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:12:12:12:18 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:17:8:17:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:12:12:12:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:15:12:15:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:18:15:18:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:18:15:18:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| test.py:12:10:12:12 | simple.test | test.py:21:10:21:10 | simple.test | +| test.py:12:10:12:12 | simple.test | test.py:51:14:51:16 | simple.test | +| test.py:13:10:13:12 | simple.test | test.py:12:10:12:12 | simple.test | +| test.py:13:10:13:12 | simple.test | test.py:21:10:21:10 | simple.test | +| test.py:13:10:13:12 | simple.test | test.py:51:14:51:16 | simple.test | +| test.py:49:17:49:19 | simple.test | test.py:63:17:63:17 | simple.test | +| test.py:49:17:49:19 | simple.test | test.py:70:17:70:17 | simple.test | +| test.py:51:14:51:16 | simple.test | test.py:63:17:63:17 | simple.test | +| test.py:51:14:51:16 | simple.test | test.py:70:17:70:17 | simple.test | +| test.py:72:9:72:11 | simple.test | test.py:77:13:77:13 | simple.test | +| test.py:73:12:73:14 | simple.test | test.py:72:9:72:11 | simple.test | +| test.py:73:12:73:14 | simple.test | test.py:77:13:77:13 | simple.test | #select -| rockpaperscissors.py:13:10:13:17 | ControlFlowNode for SCISSORS | rockpaperscissors.py:13:10:13:17 | scissors at rockpaperscissors.py:13 | rockpaperscissors.py:13:10:13:17 | scissors at rockpaperscissors.py:13 | $@ looses to $@. | rockpaperscissors.py:13:10:13:17 | ControlFlowNode for SCISSORS | scissors | rockpaperscissors.py:13:10:13:17 | ControlFlowNode for SCISSORS | scissors | -| rockpaperscissors.py:16:11:16:14 | ControlFlowNode for ROCK | rockpaperscissors.py:16:11:16:14 | rock at rockpaperscissors.py:16 | rockpaperscissors.py:16:11:16:14 | rock at rockpaperscissors.py:16 | $@ looses to $@. | rockpaperscissors.py:16:11:16:14 | ControlFlowNode for ROCK | rock | rockpaperscissors.py:16:11:16:14 | ControlFlowNode for ROCK | rock | -| rockpaperscissors.py:26:14:26:14 | ControlFlowNode for y | rockpaperscissors.py:24:9:24:12 | rock at rockpaperscissors.py:24 | rockpaperscissors.py:26:14:26:14 | paper at rockpaperscissors.py:26 | $@ looses to $@. | rockpaperscissors.py:24:9:24:12 | ControlFlowNode for ROCK | rock | rockpaperscissors.py:26:14:26:14 | ControlFlowNode for y | paper | +| rockpaperscissors.py:13:10:13:17 | ControlFlowNode for SCISSORS | rockpaperscissors.py:13:10:13:17 | scissors | rockpaperscissors.py:13:10:13:17 | scissors | $@ looses to $@. | rockpaperscissors.py:13:10:13:17 | ControlFlowNode for SCISSORS | scissors | rockpaperscissors.py:13:10:13:17 | ControlFlowNode for SCISSORS | scissors | +| rockpaperscissors.py:16:11:16:14 | ControlFlowNode for ROCK | rockpaperscissors.py:16:11:16:14 | rock | rockpaperscissors.py:16:11:16:14 | rock | $@ looses to $@. | rockpaperscissors.py:16:11:16:14 | ControlFlowNode for ROCK | rock | rockpaperscissors.py:16:11:16:14 | ControlFlowNode for ROCK | rock | +| rockpaperscissors.py:26:14:26:14 | ControlFlowNode for y | rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:26:14:26:14 | paper | $@ looses to $@. | rockpaperscissors.py:24:9:24:12 | ControlFlowNode for ROCK | rock | rockpaperscissors.py:26:14:26:14 | ControlFlowNode for y | paper | diff --git a/python/ql/test/library-tests/taint/config/Simple.expected b/python/ql/test/library-tests/taint/config/Simple.expected index b9d870c06cc..8e4136d1605 100644 --- a/python/ql/test/library-tests/taint/config/Simple.expected +++ b/python/ql/test/library-tests/taint/config/Simple.expected @@ -1,76 +1,245 @@ edges -| carrier.py:13:9:13:11 | explicit.carrier at carrier.py:13 | carrier.py:14:12:14:14 | explicit.carrier at carrier.py:14 | -| carrier.py:14:12:14:14 | explicit.carrier at carrier.py:14 | carrier.py:29:9:29:33 | explicit.carrier at carrier.py:29 | -| carrier.py:21:5:21:5 | explicit.carrier at carrier.py:21 | carrier.py:22:10:22:10 | explicit.carrier at carrier.py:22 | -| carrier.py:21:9:21:28 | explicit.carrier at carrier.py:21 | carrier.py:21:5:21:5 | explicit.carrier at carrier.py:21 | -| carrier.py:22:10:22:10 | explicit.carrier at carrier.py:22 | carrier.py:22:10:22:22 | simple.test at carrier.py:22 | -| carrier.py:29:5:29:5 | explicit.carrier at carrier.py:29 | carrier.py:30:10:30:10 | explicit.carrier at carrier.py:30 | -| carrier.py:29:9:29:33 | explicit.carrier at carrier.py:29 | carrier.py:29:5:29:5 | explicit.carrier at carrier.py:29 | -| carrier.py:29:13:29:32 | explicit.carrier at carrier.py:29 | carrier.py:13:9:13:11 | explicit.carrier at carrier.py:13 | -| carrier.py:30:10:30:10 | explicit.carrier at carrier.py:30 | carrier.py:30:10:30:22 | simple.test at carrier.py:30 | -| deep.py:2:8:2:10 | simple.test at deep.py:2 | deep.py:3:12:3:14 | simple.test at deep.py:3 | -| deep.py:3:12:3:14 | simple.test at deep.py:3 | deep.py:6:12:6:18 | simple.test at deep.py:6 | -| deep.py:5:8:5:10 | simple.test at deep.py:5 | deep.py:6:15:6:17 | simple.test at deep.py:6 | -| deep.py:6:12:6:18 | simple.test at deep.py:6 | deep.py:9:12:9:18 | simple.test at deep.py:9 | -| deep.py:6:15:6:17 | simple.test at deep.py:6 | deep.py:2:8:2:10 | simple.test at deep.py:2 | -| deep.py:8:8:8:10 | simple.test at deep.py:8 | deep.py:9:15:9:17 | simple.test at deep.py:9 | -| deep.py:9:12:9:18 | simple.test at deep.py:9 | deep.py:12:12:12:18 | simple.test at deep.py:12 | -| deep.py:9:15:9:17 | simple.test at deep.py:9 | deep.py:5:8:5:10 | simple.test at deep.py:5 | -| deep.py:11:8:11:10 | simple.test at deep.py:11 | deep.py:12:15:12:17 | simple.test at deep.py:12 | -| deep.py:12:12:12:18 | simple.test at deep.py:12 | deep.py:15:12:15:18 | simple.test at deep.py:15 | -| deep.py:12:15:12:17 | simple.test at deep.py:12 | deep.py:8:8:8:10 | simple.test at deep.py:8 | -| deep.py:14:8:14:10 | simple.test at deep.py:14 | deep.py:15:15:15:17 | simple.test at deep.py:15 | -| deep.py:15:12:15:18 | simple.test at deep.py:15 | deep.py:18:12:18:18 | simple.test at deep.py:18 | -| deep.py:15:15:15:17 | simple.test at deep.py:15 | deep.py:11:8:11:10 | simple.test at deep.py:11 | -| deep.py:17:8:17:10 | simple.test at deep.py:17 | deep.py:18:15:18:17 | simple.test at deep.py:18 | -| deep.py:18:12:18:18 | simple.test at deep.py:18 | deep.py:20:5:20:14 | simple.test at deep.py:20 | -| deep.py:18:15:18:17 | simple.test at deep.py:18 | deep.py:14:8:14:10 | simple.test at deep.py:14 | -| deep.py:20:1:20:1 | simple.test at deep.py:20 | deep.py:22:6:22:6 | simple.test at deep.py:22 | -| deep.py:20:5:20:14 | simple.test at deep.py:20 | deep.py:20:1:20:1 | simple.test at deep.py:20 | -| deep.py:20:8:20:13 | simple.test at deep.py:20 | deep.py:17:8:17:10 | simple.test at deep.py:17 | -| rockpaperscissors.py:24:5:24:5 | rock at rockpaperscissors.py:24 | rockpaperscissors.py:25:9:25:9 | rock at rockpaperscissors.py:25 | -| rockpaperscissors.py:24:9:24:12 | rock at rockpaperscissors.py:24 | rockpaperscissors.py:24:5:24:5 | rock at rockpaperscissors.py:24 | -| rockpaperscissors.py:25:5:25:5 | paper at rockpaperscissors.py:25 | rockpaperscissors.py:26:14:26:14 | paper at rockpaperscissors.py:26 | -| rockpaperscissors.py:25:9:25:9 | rock at rockpaperscissors.py:25 | rockpaperscissors.py:25:9:25:16 | scissors at rockpaperscissors.py:25 | -| rockpaperscissors.py:25:9:25:16 | scissors at rockpaperscissors.py:25 | rockpaperscissors.py:25:9:25:23 | paper at rockpaperscissors.py:25 | -| rockpaperscissors.py:25:9:25:23 | paper at rockpaperscissors.py:25 | rockpaperscissors.py:25:5:25:5 | paper at rockpaperscissors.py:25 | -| test.py:6:5:6:5 | simple.test at test.py:6 | test.py:7:10:7:10 | simple.test at test.py:7 | -| test.py:6:9:6:14 | simple.test at test.py:6 | test.py:6:5:6:5 | simple.test at test.py:6 | -| test.py:12:10:12:12 | simple.test at test.py:12 | test.py:13:10:13:12 | simple.test at test.py:13 | -| test.py:20:5:20:5 | simple.test at test.py:20 | test.py:21:10:21:10 | simple.test at test.py:21 | -| test.py:20:9:20:14 | simple.test at test.py:20 | test.py:20:5:20:5 | simple.test at test.py:20 | -| test.py:21:10:21:10 | simple.test at test.py:21 | test.py:12:10:12:12 | simple.test at test.py:12 | -| test.py:37:9:37:9 | simple.test at test.py:37 | test.py:41:14:41:14 | simple.test at test.py:41 | -| test.py:37:13:37:18 | simple.test at test.py:37 | test.py:37:9:37:9 | simple.test at test.py:37 | -| test.py:49:17:49:19 | simple.test at test.py:49 | test.py:51:14:51:16 | simple.test at test.py:51 | -| test.py:51:14:51:16 | simple.test at test.py:51 | test.py:12:10:12:12 | simple.test at test.py:12 | -| test.py:62:9:62:9 | simple.test at test.py:62 | test.py:63:5:63:9 | simple.test at test.py:63 | -| test.py:62:13:62:18 | simple.test at test.py:62 | test.py:62:9:62:9 | simple.test at test.py:62 | -| test.py:63:5:63:9 | simple.test at test.py:63 | test.py:63:17:63:17 | simple.test at test.py:63 | -| test.py:63:17:63:17 | simple.test at test.py:63 | test.py:49:17:49:19 | simple.test at test.py:49 | -| test.py:67:9:67:9 | simple.test at test.py:67 | test.py:70:5:70:9 | simple.test at test.py:70 | -| test.py:67:13:67:18 | simple.test at test.py:67 | test.py:67:9:67:9 | simple.test at test.py:67 | -| test.py:70:5:70:9 | simple.test at test.py:70 | test.py:70:17:70:17 | simple.test at test.py:70 | -| test.py:70:17:70:17 | simple.test at test.py:70 | test.py:49:17:49:19 | simple.test at test.py:49 | -| test.py:72:9:72:11 | simple.test at test.py:72 | test.py:73:12:73:14 | simple.test at test.py:73 | -| test.py:73:12:73:14 | simple.test at test.py:73 | test.py:77:9:77:14 | simple.test at test.py:77 | -| test.py:76:5:76:5 | simple.test at test.py:76 | test.py:77:13:77:13 | simple.test at test.py:77 | -| test.py:76:9:76:14 | simple.test at test.py:76 | test.py:76:5:76:5 | simple.test at test.py:76 | -| test.py:77:5:77:5 | simple.test at test.py:77 | test.py:78:10:78:10 | simple.test at test.py:78 | -| test.py:77:9:77:14 | simple.test at test.py:77 | test.py:77:5:77:5 | simple.test at test.py:77 | -| test.py:77:13:77:13 | simple.test at test.py:77 | test.py:72:9:72:11 | simple.test at test.py:72 | -| test.py:126:9:126:9 | simple.test at test.py:126 | test.py:130:21:130:21 | simple.test at test.py:130 | -| test.py:126:13:126:25 | simple.test at test.py:126 | test.py:126:9:126:9 | simple.test at test.py:126 | -| test.py:128:9:128:9 | simple.test at test.py:128 | test.py:132:14:132:14 | simple.test at test.py:132 | -| test.py:128:13:128:18 | simple.test at test.py:128 | test.py:128:9:128:9 | simple.test at test.py:128 | +| carrier.py:13:9:13:11 | explicit.carrier | carrier.py:14:12:14:14 | explicit.carrier | +| carrier.py:14:12:14:14 | explicit.carrier | carrier.py:29:9:29:33 | explicit.carrier | +| carrier.py:21:9:21:28 | explicit.carrier | carrier.py:22:10:22:10 | explicit.carrier | +| carrier.py:22:10:22:10 | explicit.carrier | carrier.py:22:10:22:22 | simple.test | +| carrier.py:29:9:29:33 | explicit.carrier | carrier.py:30:10:30:10 | explicit.carrier | +| carrier.py:29:13:29:32 | explicit.carrier | carrier.py:13:9:13:11 | explicit.carrier | +| carrier.py:30:10:30:10 | explicit.carrier | carrier.py:30:10:30:22 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:12:12:12:18 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:15:12:15:18 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:18:12:18:18 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:17:8:17:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:20:5:20:14 | simple.test | +| deep.py:18:15:18:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:20:5:20:14 | simple.test | deep.py:22:6:22:6 | simple.test | +| deep.py:20:8:20:13 | simple.test | deep.py:17:8:17:10 | simple.test | +| rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:25:9:25:9 | rock | +| rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors | +| rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper | +| rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper | +| test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test | +| test.py:12:10:12:12 | simple.test | test.py:13:10:13:12 | simple.test | +| test.py:20:9:20:14 | simple.test | test.py:21:10:21:10 | simple.test | +| test.py:21:10:21:10 | simple.test | test.py:12:10:12:12 | simple.test | +| test.py:37:13:37:18 | simple.test | test.py:41:14:41:14 | simple.test | +| test.py:49:17:49:19 | simple.test | test.py:51:14:51:16 | simple.test | +| test.py:51:14:51:16 | simple.test | test.py:12:10:12:12 | simple.test | +| test.py:62:13:62:18 | simple.test | test.py:63:17:63:17 | simple.test | +| test.py:63:17:63:17 | simple.test | test.py:49:17:49:19 | simple.test | +| test.py:67:13:67:18 | simple.test | test.py:70:17:70:17 | simple.test | +| test.py:70:17:70:17 | simple.test | test.py:49:17:49:19 | simple.test | +| test.py:72:9:72:11 | simple.test | test.py:73:12:73:14 | simple.test | +| test.py:73:12:73:14 | simple.test | test.py:77:9:77:14 | simple.test | +| test.py:76:9:76:14 | simple.test | test.py:77:13:77:13 | simple.test | +| test.py:77:9:77:14 | simple.test | test.py:78:10:78:10 | simple.test | +| test.py:77:13:77:13 | simple.test | test.py:72:9:72:11 | simple.test | +| test.py:126:13:126:25 | simple.test | test.py:130:21:130:21 | simple.test | +| test.py:128:13:128:18 | simple.test | test.py:132:14:132:14 | simple.test | +| test.py:163:9:163:14 | simple.test | test.py:165:10:165:10 | simple.test | +| test.py:178:9:178:14 | simple.test | test.py:180:14:180:14 | simple.test | +| test.py:178:9:178:14 | simple.test | test.py:186:14:186:14 | simple.test | +| test.py:195:9:195:14 | simple.test | test.py:199:14:199:14 | simple.test | +| test.py:208:11:208:18 | sequence of simple.test | test.py:209:14:209:16 | sequence of simple.test | +| test.py:208:12:208:17 | simple.test | test.py:208:11:208:18 | sequence of simple.test | +| test.py:209:5:209:17 | simple.test | test.py:210:15:210:15 | simple.test | +| test.py:209:14:209:16 | sequence of simple.test | test.py:209:5:209:17 | simple.test | +| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | iterable.simple | +| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | sequence of simple.test | +| test.py:213:5:213:33 | simple.test | test.py:214:14:214:14 | simple.test | +| test.py:213:14:213:32 | iterable.simple | test.py:213:5:213:33 | simple.test | +| test.py:213:14:213:32 | sequence of simple.test | test.py:213:5:213:33 | simple.test | parents +| carrier.py:13:9:13:11 | explicit.carrier | carrier.py:29:13:29:32 | explicit.carrier | +| carrier.py:14:12:14:14 | explicit.carrier | carrier.py:29:13:29:32 | explicit.carrier | +| deep.py:2:8:2:10 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:2:8:2:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:3:12:3:14 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:5:8:5:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:6:12:6:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:6:15:6:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:8:8:8:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:9:12:9:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:9:15:9:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:11:8:11:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:12:12:12:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:12:15:12:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:14:8:14:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:12:12:12:18 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:15:12:15:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:15:15:15:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:17:8:17:10 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:2:8:2:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:3:12:3:14 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:5:8:5:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:6:12:6:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:6:15:6:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:8:8:8:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:9:12:9:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:9:15:9:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:11:8:11:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:12:12:12:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:12:15:12:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:14:8:14:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:15:12:15:18 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:15:15:15:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:18:15:18:17 | simple.test | +| deep.py:18:12:18:18 | simple.test | deep.py:20:8:20:13 | simple.test | +| deep.py:18:15:18:17 | simple.test | deep.py:17:8:17:10 | simple.test | +| deep.py:18:15:18:17 | simple.test | deep.py:20:8:20:13 | simple.test | +| test.py:12:10:12:12 | simple.test | test.py:21:10:21:10 | simple.test | +| test.py:12:10:12:12 | simple.test | test.py:51:14:51:16 | simple.test | +| test.py:13:10:13:12 | simple.test | test.py:12:10:12:12 | simple.test | +| test.py:13:10:13:12 | simple.test | test.py:21:10:21:10 | simple.test | +| test.py:13:10:13:12 | simple.test | test.py:51:14:51:16 | simple.test | +| test.py:49:17:49:19 | simple.test | test.py:63:17:63:17 | simple.test | +| test.py:49:17:49:19 | simple.test | test.py:70:17:70:17 | simple.test | +| test.py:51:14:51:16 | simple.test | test.py:63:17:63:17 | simple.test | +| test.py:51:14:51:16 | simple.test | test.py:70:17:70:17 | simple.test | +| test.py:72:9:72:11 | simple.test | test.py:77:13:77:13 | simple.test | +| test.py:73:12:73:14 | simple.test | test.py:72:9:72:11 | simple.test | +| test.py:73:12:73:14 | simple.test | test.py:77:13:77:13 | simple.test | #select -| deep.py:22:6:22:6 | ControlFlowNode for x | deep.py:20:8:20:13 | simple.test at deep.py:20 | deep.py:22:6:22:6 | simple.test at deep.py:22 | $@ flows to $@. | deep.py:20:8:20:13 | ControlFlowNode for SOURCE | simple.test | deep.py:22:6:22:6 | ControlFlowNode for x | simple.test | -| test.py:3:10:3:15 | ControlFlowNode for SOURCE | test.py:3:10:3:15 | simple.test at test.py:3 | test.py:3:10:3:15 | simple.test at test.py:3 | $@ flows to $@. | test.py:3:10:3:15 | ControlFlowNode for SOURCE | simple.test | test.py:3:10:3:15 | ControlFlowNode for SOURCE | simple.test | -| test.py:7:10:7:10 | ControlFlowNode for s | test.py:6:9:6:14 | simple.test at test.py:6 | test.py:7:10:7:10 | simple.test at test.py:7 | $@ flows to $@. | test.py:6:9:6:14 | ControlFlowNode for SOURCE | simple.test | test.py:7:10:7:10 | ControlFlowNode for s | simple.test | -| test.py:13:10:13:12 | ControlFlowNode for arg | test.py:20:9:20:14 | simple.test at test.py:20 | test.py:13:10:13:12 | simple.test at test.py:13 | $@ flows to $@. | test.py:20:9:20:14 | ControlFlowNode for SOURCE | simple.test | test.py:13:10:13:12 | ControlFlowNode for arg | simple.test | -| test.py:13:10:13:12 | ControlFlowNode for arg | test.py:62:13:62:18 | simple.test at test.py:62 | test.py:13:10:13:12 | simple.test at test.py:13 | $@ flows to $@. | test.py:62:13:62:18 | ControlFlowNode for SOURCE | simple.test | test.py:13:10:13:12 | ControlFlowNode for arg | simple.test | -| test.py:13:10:13:12 | ControlFlowNode for arg | test.py:67:13:67:18 | simple.test at test.py:67 | test.py:13:10:13:12 | simple.test at test.py:13 | $@ flows to $@. | test.py:67:13:67:18 | ControlFlowNode for SOURCE | simple.test | test.py:13:10:13:12 | ControlFlowNode for arg | simple.test | -| test.py:41:14:41:14 | ControlFlowNode for t | test.py:37:13:37:18 | simple.test at test.py:37 | test.py:41:14:41:14 | simple.test at test.py:41 | $@ flows to $@. | test.py:37:13:37:18 | ControlFlowNode for SOURCE | simple.test | test.py:41:14:41:14 | ControlFlowNode for t | simple.test | -| test.py:78:10:78:10 | ControlFlowNode for t | test.py:76:9:76:14 | simple.test at test.py:76 | test.py:78:10:78:10 | simple.test at test.py:78 | $@ flows to $@. | test.py:76:9:76:14 | ControlFlowNode for SOURCE | simple.test | test.py:78:10:78:10 | ControlFlowNode for t | simple.test | -| test.py:132:14:132:14 | ControlFlowNode for t | test.py:128:13:128:18 | simple.test at test.py:128 | test.py:132:14:132:14 | simple.test at test.py:132 | $@ flows to $@. | test.py:128:13:128:18 | ControlFlowNode for SOURCE | simple.test | test.py:132:14:132:14 | ControlFlowNode for t | simple.test | +| deep.py:22:6:22:6 | ControlFlowNode for x | deep.py:20:8:20:13 | simple.test | deep.py:22:6:22:6 | simple.test | $@ flows to $@. | deep.py:20:8:20:13 | ControlFlowNode for SOURCE | simple.test | deep.py:22:6:22:6 | ControlFlowNode for x | simple.test | +| test.py:3:10:3:15 | ControlFlowNode for SOURCE | test.py:3:10:3:15 | simple.test | test.py:3:10:3:15 | simple.test | $@ flows to $@. | test.py:3:10:3:15 | ControlFlowNode for SOURCE | simple.test | test.py:3:10:3:15 | ControlFlowNode for SOURCE | simple.test | +| test.py:7:10:7:10 | ControlFlowNode for s | test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test | $@ flows to $@. | test.py:6:9:6:14 | ControlFlowNode for SOURCE | simple.test | test.py:7:10:7:10 | ControlFlowNode for s | simple.test | +| test.py:13:10:13:12 | ControlFlowNode for arg | test.py:20:9:20:14 | simple.test | test.py:13:10:13:12 | simple.test | $@ flows to $@. | test.py:20:9:20:14 | ControlFlowNode for SOURCE | simple.test | test.py:13:10:13:12 | ControlFlowNode for arg | simple.test | +| test.py:13:10:13:12 | ControlFlowNode for arg | test.py:62:13:62:18 | simple.test | test.py:13:10:13:12 | simple.test | $@ flows to $@. | test.py:62:13:62:18 | ControlFlowNode for SOURCE | simple.test | test.py:13:10:13:12 | ControlFlowNode for arg | simple.test | +| test.py:13:10:13:12 | ControlFlowNode for arg | test.py:67:13:67:18 | simple.test | test.py:13:10:13:12 | simple.test | $@ flows to $@. | test.py:67:13:67:18 | ControlFlowNode for SOURCE | simple.test | test.py:13:10:13:12 | ControlFlowNode for arg | simple.test | +| test.py:41:14:41:14 | ControlFlowNode for t | test.py:37:13:37:18 | simple.test | test.py:41:14:41:14 | simple.test | $@ flows to $@. | test.py:37:13:37:18 | ControlFlowNode for SOURCE | simple.test | test.py:41:14:41:14 | ControlFlowNode for t | simple.test | +| test.py:78:10:78:10 | ControlFlowNode for t | test.py:76:9:76:14 | simple.test | test.py:78:10:78:10 | simple.test | $@ flows to $@. | test.py:76:9:76:14 | ControlFlowNode for SOURCE | simple.test | test.py:78:10:78:10 | ControlFlowNode for t | simple.test | +| test.py:132:14:132:14 | ControlFlowNode for t | test.py:128:13:128:18 | simple.test | test.py:132:14:132:14 | simple.test | $@ flows to $@. | test.py:128:13:128:18 | ControlFlowNode for SOURCE | simple.test | test.py:132:14:132:14 | ControlFlowNode for t | simple.test | +| test.py:165:10:165:10 | ControlFlowNode for s | test.py:163:9:163:14 | simple.test | test.py:165:10:165:10 | simple.test | $@ flows to $@. | test.py:163:9:163:14 | ControlFlowNode for SOURCE | simple.test | test.py:165:10:165:10 | ControlFlowNode for s | simple.test | +| test.py:180:14:180:14 | ControlFlowNode for t | test.py:178:9:178:14 | simple.test | test.py:180:14:180:14 | simple.test | $@ flows to $@. | test.py:178:9:178:14 | ControlFlowNode for SOURCE | simple.test | test.py:180:14:180:14 | ControlFlowNode for t | simple.test | +| test.py:186:14:186:14 | ControlFlowNode for t | test.py:178:9:178:14 | simple.test | test.py:186:14:186:14 | simple.test | $@ flows to $@. | test.py:178:9:178:14 | ControlFlowNode for SOURCE | simple.test | test.py:186:14:186:14 | ControlFlowNode for t | simple.test | +| test.py:199:14:199:14 | ControlFlowNode for t | test.py:195:9:195:14 | simple.test | test.py:199:14:199:14 | simple.test | $@ flows to $@. | test.py:195:9:195:14 | ControlFlowNode for SOURCE | simple.test | test.py:199:14:199:14 | ControlFlowNode for t | simple.test | +| test.py:214:14:214:14 | ControlFlowNode for x | test.py:208:12:208:17 | simple.test | test.py:214:14:214:14 | simple.test | $@ flows to $@. | test.py:208:12:208:17 | ControlFlowNode for SOURCE | simple.test | test.py:214:14:214:14 | ControlFlowNode for x | simple.test | diff --git a/python/ql/test/library-tests/taint/config/TaintedArgument.expected b/python/ql/test/library-tests/taint/config/TaintedArgument.expected index 9dae856c349..ad37fa00461 100644 --- a/python/ql/test/library-tests/taint/config/TaintedArgument.expected +++ b/python/ql/test/library-tests/taint/config/TaintedArgument.expected @@ -1 +1,22 @@ -fail +| Rock-paper-scissors config | rockpaperscissors.py:13:10:13:17 | scissors | rockpaperscissors.py:13:5:13:18 | ControlFlowNode for rock() | | rockpaperscissors.py:3:1:3:14 | Function rock | 0 | no attribute | scissors | +| Rock-paper-scissors config | rockpaperscissors.py:16:11:16:14 | rock | rockpaperscissors.py:16:5:16:15 | ControlFlowNode for paper() | | rockpaperscissors.py:6:1:6:15 | Function paper | 0 | no attribute | rock | +| Rock-paper-scissors config | rockpaperscissors.py:21:14:21:14 | scissors | rockpaperscissors.py:21:5:21:15 | ControlFlowNode for scissors() | | rockpaperscissors.py:9:1:9:18 | Function scissors | 0 | no attribute | scissors | +| Rock-paper-scissors config | rockpaperscissors.py:26:14:26:14 | paper | rockpaperscissors.py:26:5:26:15 | ControlFlowNode for scissors() | | rockpaperscissors.py:9:1:9:18 | Function scissors | 0 | no attribute | paper | +| Rock-paper-scissors config | rockpaperscissors.py:31:11:31:11 | scissors | rockpaperscissors.py:31:5:31:12 | ControlFlowNode for paper() | | rockpaperscissors.py:6:1:6:15 | Function paper | 0 | no attribute | scissors | +| Rock-paper-scissors config | rockpaperscissors.py:32:11:32:11 | paper | rockpaperscissors.py:32:5:32:12 | ControlFlowNode for paper() | | rockpaperscissors.py:6:1:6:15 | Function paper | 0 | no attribute | paper | +| Simple config | carrier.py:17:25:17:30 | simple.test | carrier.py:17:9:17:31 | ControlFlowNode for ImplicitCarrier() | | carrier.py:4:5:4:28 | Function ImplicitCarrier.__init__ | 1 | no attribute | simple.test | +| Simple config | carrier.py:25:29:25:34 | simple.test | carrier.py:25:13:25:35 | ControlFlowNode for ImplicitCarrier() | | carrier.py:4:5:4:28 | Function ImplicitCarrier.__init__ | 1 | no attribute | simple.test | +| Simple config | deep.py:6:15:6:17 | simple.test | deep.py:6:12:6:18 | ControlFlowNode for f1() | Parameter 0(no attribute) is simple.test | deep.py:2:1:2:12 | Function f1 | 0 | no attribute | simple.test | +| Simple config | deep.py:9:15:9:17 | simple.test | deep.py:9:12:9:18 | ControlFlowNode for f2() | Parameter 0(no attribute) is simple.test | deep.py:5:1:5:12 | Function f2 | 0 | no attribute | simple.test | +| Simple config | deep.py:12:15:12:17 | simple.test | deep.py:12:12:12:18 | ControlFlowNode for f3() | Parameter 0(no attribute) is simple.test | deep.py:8:1:8:12 | Function f3 | 0 | no attribute | simple.test | +| Simple config | deep.py:15:15:15:17 | simple.test | deep.py:15:12:15:18 | ControlFlowNode for f4() | Parameter 0(no attribute) is simple.test | deep.py:11:1:11:12 | Function f4 | 0 | no attribute | simple.test | +| Simple config | deep.py:18:15:18:17 | simple.test | deep.py:18:12:18:18 | ControlFlowNode for f5() | Parameter 0(no attribute) is simple.test | deep.py:14:1:14:12 | Function f5 | 0 | no attribute | simple.test | +| Simple config | deep.py:20:8:20:13 | simple.test | deep.py:20:5:20:14 | ControlFlowNode for f6() | | deep.py:17:1:17:12 | Function f6 | 0 | no attribute | simple.test | +| Simple config | test.py:21:10:21:10 | simple.test | test.py:21:5:21:11 | ControlFlowNode for sink() | | test.py:12:1:12:14 | Function sink | 0 | no attribute | simple.test | +| Simple config | test.py:51:14:51:16 | simple.test | test.py:51:9:51:17 | ControlFlowNode for sink() | Parameter 1(no attribute) is simple.test | test.py:12:1:12:14 | Function sink | 0 | no attribute | simple.test | +| Simple config | test.py:63:17:63:17 | simple.test | test.py:63:5:63:18 | ControlFlowNode for sink3() | | test.py:49:1:49:21 | Function sink3 | 1 | no attribute | simple.test | +| Simple config | test.py:70:17:70:17 | simple.test | test.py:70:5:70:18 | ControlFlowNode for sink3() | | test.py:49:1:49:21 | Function sink3 | 1 | no attribute | simple.test | +| Simple config | test.py:77:13:77:13 | simple.test | test.py:77:9:77:14 | ControlFlowNode for hub() | | test.py:72:1:72:13 | Function hub | 0 | no attribute | simple.test | +| Simple config | test.py:196:19:196:19 | simple.test | test.py:196:8:196:25 | ControlFlowNode for isinstance() | | file://:0:0:0:0 | Builtin-function isinstance | 0 | no attribute | simple.test | +| Taint carrier config | carrier.py:29:13:29:32 | explicit.carrier | carrier.py:29:9:29:33 | ControlFlowNode for hub() | | carrier.py:13:1:13:13 | Function hub | 0 | no attribute | explicit.carrier | +| Taint carrier config | carrier.py:33:25:33:44 | explicit.carrier | carrier.py:33:9:33:45 | ControlFlowNode for ImplicitCarrier() | | carrier.py:4:5:4:28 | Function ImplicitCarrier.__init__ | 1 | no attribute | explicit.carrier | diff --git a/python/ql/test/library-tests/taint/config/TestNode.expected b/python/ql/test/library-tests/taint/config/TestNode.expected index e69de29bb2d..9ac9f275e6e 100644 --- a/python/ql/test/library-tests/taint/config/TestNode.expected +++ b/python/ql/test/library-tests/taint/config/TestNode.expected @@ -0,0 +1,278 @@ +| [simple.test] | test.py:168 | ControlFlowNode for List | no attribute | | +| [simple.test] | test.py:168 | SSA variable l | no attribute | | +| [simple.test] | test.py:170 | ControlFlowNode for l | no attribute | | +| [simple.test] | test.py:170 | SSA variable l | no attribute | | +| [simple.test] | test.py:174 | ControlFlowNode for l | no attribute | | +| [simple.test] | test.py:174 | ControlFlowNode for list() | no attribute | | +| [simple.test] | test.py:174 | SSA variable l | no attribute | | +| [simple.test] | test.py:174 | SSA variable l2 | no attribute | | +| [simple.test] | test.py:208 | ControlFlowNode for List | no attribute | | +| [simple.test] | test.py:208 | SSA variable seq | no attribute | | +| [simple.test] | test.py:209 | ControlFlowNode for seq | no attribute | | +| [simple.test] | test.py:213 | ControlFlowNode for flow_in_generator() | no attribute | | +| explicit.carrier | carrier.py:4 | ControlFlowNode for arg | no attribute | Parameter 1(no attribute) is explicit.carrier | +| explicit.carrier | carrier.py:4 | SSA variable arg | no attribute | Parameter 1(no attribute) is explicit.carrier | +| explicit.carrier | carrier.py:5 | ControlFlowNode for arg | no attribute | Parameter 1(no attribute) is explicit.carrier | +| explicit.carrier | carrier.py:13 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is explicit.carrier | +| explicit.carrier | carrier.py:13 | SSA variable arg | no attribute | Parameter 0(no attribute) is explicit.carrier | +| explicit.carrier | carrier.py:14 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is explicit.carrier | +| explicit.carrier | carrier.py:21 | ControlFlowNode for TAINT_CARRIER_SOURCE | no attribute | | +| explicit.carrier | carrier.py:21 | SSA variable c | no attribute | | +| explicit.carrier | carrier.py:22 | ControlFlowNode for c | no attribute | | +| explicit.carrier | carrier.py:22 | SSA variable c | no attribute | | +| explicit.carrier | carrier.py:29 | ControlFlowNode for TAINT_CARRIER_SOURCE | no attribute | | +| explicit.carrier | carrier.py:29 | ControlFlowNode for hub() | no attribute | | +| explicit.carrier | carrier.py:29 | SSA variable c | no attribute | | +| explicit.carrier | carrier.py:30 | ControlFlowNode for c | no attribute | | +| explicit.carrier | carrier.py:30 | SSA variable c | no attribute | | +| explicit.carrier | carrier.py:33 | ControlFlowNode for TAINT_CARRIER_SOURCE | no attribute | | +| iterable.simple | test.py:213 | ControlFlowNode for flow_in_generator() | no attribute | | +| paper | rockpaperscissors.py:6 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is paper | +| paper | rockpaperscissors.py:6 | SSA variable arg | no attribute | Parameter 0(no attribute) is paper | +| paper | rockpaperscissors.py:9 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is paper | +| paper | rockpaperscissors.py:9 | SSA variable arg | no attribute | Parameter 0(no attribute) is paper | +| paper | rockpaperscissors.py:25 | ControlFlowNode for Attribute() | no attribute | | +| paper | rockpaperscissors.py:25 | SSA variable y | no attribute | | +| paper | rockpaperscissors.py:26 | ControlFlowNode for y | no attribute | | +| paper | rockpaperscissors.py:26 | SSA variable y | no attribute | | +| paper | rockpaperscissors.py:30 | ControlFlowNode for Attribute() | no attribute | | +| paper | rockpaperscissors.py:30 | SSA variable y | no attribute | | +| paper | rockpaperscissors.py:32 | ControlFlowNode for y | no attribute | | +| paper | rockpaperscissors.py:32 | SSA variable y | no attribute | | +| rock | rockpaperscissors.py:6 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is rock | +| rock | rockpaperscissors.py:6 | SSA variable arg | no attribute | Parameter 0(no attribute) is rock | +| rock | rockpaperscissors.py:16 | ControlFlowNode for ROCK | no attribute | | +| rock | rockpaperscissors.py:19 | ControlFlowNode for ROCK | no attribute | | +| rock | rockpaperscissors.py:19 | SSA variable x | no attribute | | +| rock | rockpaperscissors.py:20 | ControlFlowNode for x | no attribute | | +| rock | rockpaperscissors.py:20 | SSA variable x | no attribute | | +| rock | rockpaperscissors.py:24 | ControlFlowNode for ROCK | no attribute | | +| rock | rockpaperscissors.py:24 | SSA variable x | no attribute | | +| rock | rockpaperscissors.py:25 | ControlFlowNode for x | no attribute | | +| rock | rockpaperscissors.py:25 | SSA variable x | no attribute | | +| scissors | rockpaperscissors.py:3 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is scissors | +| scissors | rockpaperscissors.py:3 | SSA variable arg | no attribute | Parameter 0(no attribute) is scissors | +| scissors | rockpaperscissors.py:6 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is scissors | +| scissors | rockpaperscissors.py:6 | SSA variable arg | no attribute | Parameter 0(no attribute) is scissors | +| scissors | rockpaperscissors.py:9 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is scissors | +| scissors | rockpaperscissors.py:9 | SSA variable arg | no attribute | Parameter 0(no attribute) is scissors | +| scissors | rockpaperscissors.py:13 | ControlFlowNode for SCISSORS | no attribute | | +| scissors | rockpaperscissors.py:20 | ControlFlowNode for Attribute() | no attribute | | +| scissors | rockpaperscissors.py:20 | SSA variable y | no attribute | | +| scissors | rockpaperscissors.py:21 | ControlFlowNode for y | no attribute | | +| scissors | rockpaperscissors.py:21 | SSA variable y | no attribute | | +| scissors | rockpaperscissors.py:25 | ControlFlowNode for Attribute() | no attribute | | +| scissors | rockpaperscissors.py:29 | ControlFlowNode for SCISSORS | no attribute | | +| scissors | rockpaperscissors.py:29 | SSA variable x | no attribute | | +| scissors | rockpaperscissors.py:30 | ControlFlowNode for x | no attribute | | +| scissors | rockpaperscissors.py:30 | SSA variable x | no attribute | | +| scissors | rockpaperscissors.py:31 | ControlFlowNode for x | no attribute | | +| scissors | rockpaperscissors.py:31 | SSA variable x | no attribute | | +| simple.test | carrier.py:4 | ControlFlowNode for arg | no attribute | Parameter 1(no attribute) is simple.test | +| simple.test | carrier.py:4 | SSA variable arg | no attribute | Parameter 1(no attribute) is simple.test | +| simple.test | carrier.py:5 | ControlFlowNode for arg | no attribute | Parameter 1(no attribute) is simple.test | +| simple.test | carrier.py:17 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | carrier.py:22 | ControlFlowNode for Attribute() | no attribute | | +| simple.test | carrier.py:25 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | carrier.py:30 | ControlFlowNode for Attribute() | no attribute | | +| simple.test | deep.py:2 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:2 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:3 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:5 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:5 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:6 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:6 | ControlFlowNode for f1() | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:6 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:8 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:8 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:9 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:9 | ControlFlowNode for f2() | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:9 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:11 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:11 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:12 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:12 | ControlFlowNode for f3() | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:12 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:14 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:14 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:15 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:15 | ControlFlowNode for f4() | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:15 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:17 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:17 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:18 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:18 | ControlFlowNode for f5() | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:18 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | deep.py:20 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | deep.py:20 | ControlFlowNode for f6() | no attribute | | +| simple.test | deep.py:20 | GSSA Variable x | no attribute | | +| simple.test | deep.py:22 | ControlFlowNode for x | no attribute | | +| simple.test | deep.py:22 | GSSA Variable x | no attribute | | +| simple.test | module.py:3 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | module.py:3 | GSSA Variable dangerous | no attribute | | +| simple.test | module.py:7 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | module.py:10 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:3 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:6 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:6 | SSA variable s | no attribute | | +| simple.test | test.py:7 | ControlFlowNode for s | no attribute | | +| simple.test | test.py:7 | SSA variable s | no attribute | | +| simple.test | test.py:10 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:12 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | test.py:12 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | test.py:13 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | test.py:13 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | test.py:20 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:20 | SSA variable t | no attribute | | +| simple.test | test.py:21 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:21 | SSA variable t | no attribute | | +| simple.test | test.py:31 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:31 | SSA variable t | no attribute | | +| simple.test | test.py:37 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:37 | SSA variable t | no attribute | | +| simple.test | test.py:41 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:41 | SSA variable t | no attribute | | +| simple.test | test.py:49 | ControlFlowNode for arg | no attribute | Parameter 1(no attribute) is simple.test | +| simple.test | test.py:49 | SSA variable arg | no attribute | Parameter 1(no attribute) is simple.test | +| simple.test | test.py:51 | ControlFlowNode for arg | no attribute | Parameter 1(no attribute) is simple.test | +| simple.test | test.py:51 | SSA variable arg | no attribute | Parameter 1(no attribute) is simple.test | +| simple.test | test.py:62 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:62 | SSA variable t | no attribute | | +| simple.test | test.py:63 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:63 | SSA variable t | no attribute | | +| simple.test | test.py:67 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:67 | SSA variable t | no attribute | | +| simple.test | test.py:70 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:70 | SSA variable t | no attribute | | +| simple.test | test.py:72 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | test.py:72 | SSA variable arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | test.py:73 | ControlFlowNode for arg | no attribute | Parameter 0(no attribute) is simple.test | +| simple.test | test.py:76 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:76 | SSA variable t | no attribute | | +| simple.test | test.py:77 | ControlFlowNode for hub() | no attribute | | +| simple.test | test.py:77 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:77 | SSA variable t | no attribute | | +| simple.test | test.py:78 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:78 | SSA variable t | no attribute | | +| simple.test | test.py:120 | ControlFlowNode for CUSTOM_SOURCE | no attribute | | +| simple.test | test.py:120 | SSA variable t | no attribute | | +| simple.test | test.py:121 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:126 | ControlFlowNode for CUSTOM_SOURCE | no attribute | | +| simple.test | test.py:126 | SSA variable t | no attribute | | +| simple.test | test.py:128 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:128 | SSA variable t | no attribute | | +| simple.test | test.py:130 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:130 | SSA variable t | no attribute | | +| simple.test | test.py:132 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:132 | SSA variable t | no attribute | | +| simple.test | test.py:136 | ControlFlowNode for CUSTOM_SOURCE | no attribute | | +| simple.test | test.py:136 | SSA variable t | no attribute | | +| simple.test | test.py:138 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:138 | SSA variable t | no attribute | | +| simple.test | test.py:140 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:140 | SSA variable t | no attribute | | +| simple.test | test.py:142 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:142 | SSA variable t | no attribute | | +| simple.test | test.py:146 | ControlFlowNode for CUSTOM_SOURCE | no attribute | | +| simple.test | test.py:146 | SSA variable t | no attribute | | +| simple.test | test.py:148 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:148 | SSA variable t | no attribute | | +| simple.test | test.py:149 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:159 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:163 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:163 | SSA variable s | no attribute | | +| simple.test | test.py:164 | ControlFlowNode for s | no attribute | | +| simple.test | test.py:164 | SSA variable s | no attribute | | +| simple.test | test.py:165 | ControlFlowNode for s | no attribute | | +| simple.test | test.py:165 | SSA variable s | no attribute | | +| simple.test | test.py:168 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:169 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:178 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:178 | SSA variable t | no attribute | | +| simple.test | test.py:179 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:180 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:180 | SSA variable t | no attribute | | +| simple.test | test.py:183 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:183 | SSA variable t | no attribute | | +| simple.test | test.py:186 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:186 | SSA variable t | no attribute | | +| simple.test | test.py:194 | SSA variable t | no attribute | | +| simple.test | test.py:195 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:195 | SSA variable t | no attribute | | +| simple.test | test.py:196 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:199 | ControlFlowNode for t | no attribute | | +| simple.test | test.py:199 | SSA variable t | no attribute | | +| simple.test | test.py:208 | ControlFlowNode for SOURCE | no attribute | | +| simple.test | test.py:209 | ControlFlowNode for For | no attribute | | +| simple.test | test.py:209 | SSA variable i | no attribute | | +| simple.test | test.py:210 | ControlFlowNode for i | no attribute | | +| simple.test | test.py:213 | ControlFlowNode for For | no attribute | | +| simple.test | test.py:213 | SSA variable x | no attribute | | +| simple.test | test.py:214 | ControlFlowNode for x | no attribute | | +| simple.test | test.py:214 | SSA variable x | no attribute | | +| {Command injection} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {Command injection} | test.py:175 | SSA variable d2 | no attribute | | +| {SQL injection} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {SQL injection} | test.py:175 | SSA variable d2 | no attribute | | +| {[Command injection]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[Command injection]} | test.py:175 | SSA variable d2 | no attribute | | +| {[SQL injection]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[SQL injection]} | test.py:175 | SSA variable d2 | no attribute | | +| {[basic.custom]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[basic.custom]} | test.py:175 | SSA variable d2 | no attribute | | +| {[explicit.carrier]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[explicit.carrier]} | test.py:175 | SSA variable d2 | no attribute | | +| {[falsey]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[falsey]} | test.py:175 | SSA variable d2 | no attribute | | +| {[iterable.simple]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[iterable.simple]} | test.py:175 | SSA variable d2 | no attribute | | +| {[paper]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[paper]} | test.py:175 | SSA variable d2 | no attribute | | +| {[rock]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[rock]} | test.py:175 | SSA variable d2 | no attribute | | +| {[scissors]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[scissors]} | test.py:175 | SSA variable d2 | no attribute | | +| {[simple.test]} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {[simple.test]} | test.py:175 | SSA variable d2 | no attribute | | +| {basic.custom} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {basic.custom} | test.py:175 | SSA variable d2 | no attribute | | +| {explicit.carrier} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {explicit.carrier} | test.py:175 | SSA variable d2 | no attribute | | +| {falsey} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {falsey} | test.py:175 | SSA variable d2 | no attribute | | +| {iterable.simple} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {iterable.simple} | test.py:175 | SSA variable d2 | no attribute | | +| {paper} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {paper} | test.py:175 | SSA variable d2 | no attribute | | +| {rock} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {rock} | test.py:175 | SSA variable d2 | no attribute | | +| {scissors} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {scissors} | test.py:175 | SSA variable d2 | no attribute | | +| {simple.test} | test.py:169 | ControlFlowNode for Dict | no attribute | | +| {simple.test} | test.py:169 | SSA variable d | no attribute | | +| {simple.test} | test.py:171 | ControlFlowNode for d | no attribute | | +| {simple.test} | test.py:171 | SSA variable d | no attribute | | +| {simple.test} | test.py:175 | ControlFlowNode for d | no attribute | | +| {simple.test} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {simple.test} | test.py:175 | SSA variable d | no attribute | | +| {simple.test} | test.py:175 | SSA variable d2 | no attribute | | +| {{Command injection}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{Command injection}} | test.py:175 | SSA variable d2 | no attribute | | +| {{SQL injection}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{SQL injection}} | test.py:175 | SSA variable d2 | no attribute | | +| {{basic.custom}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{basic.custom}} | test.py:175 | SSA variable d2 | no attribute | | +| {{explicit.carrier}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{explicit.carrier}} | test.py:175 | SSA variable d2 | no attribute | | +| {{falsey}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{falsey}} | test.py:175 | SSA variable d2 | no attribute | | +| {{iterable.simple}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{iterable.simple}} | test.py:175 | SSA variable d2 | no attribute | | +| {{paper}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{paper}} | test.py:175 | SSA variable d2 | no attribute | | +| {{rock}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{rock}} | test.py:175 | SSA variable d2 | no attribute | | +| {{scissors}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{scissors}} | test.py:175 | SSA variable d2 | no attribute | | +| {{simple.test}} | test.py:175 | ControlFlowNode for dict() | no attribute | | +| {{simple.test}} | test.py:175 | SSA variable d2 | no attribute | | diff --git a/python/ql/test/library-tests/taint/config/TestSink.expected b/python/ql/test/library-tests/taint/config/TestSink.expected index 7bece824242..b6f5a667806 100644 --- a/python/ql/test/library-tests/taint/config/TestSink.expected +++ b/python/ql/test/library-tests/taint/config/TestSink.expected @@ -1,3 +1,7 @@ +| Basic custom config | test.py:122 | 122 | ControlFlowNode for t | simple.test | +| Basic custom config | test.py:130 | 130 | ControlFlowNode for t | simple.test | +| Basic custom config | test.py:140 | 140 | ControlFlowNode for t | simple.test | +| Basic custom config | test.py:151 | 151 | ControlFlowNode for t | simple.test | | Rock-paper-scissors config | rockpaperscissors.py:13 | 13 | ControlFlowNode for SCISSORS | scissors | | Rock-paper-scissors config | rockpaperscissors.py:16 | 16 | ControlFlowNode for ROCK | rock | | Rock-paper-scissors config | rockpaperscissors.py:21 | 21 | ControlFlowNode for y | paper | @@ -9,6 +13,7 @@ | Simple config | carrier.py:26 | 26 | ControlFlowNode for Attribute() | simple.test | | Simple config | carrier.py:30 | 30 | ControlFlowNode for Attribute() | simple.test | | Simple config | carrier.py:35 | 35 | ControlFlowNode for Attribute() | simple.test | +| Simple config | deep.py:22 | 22 | ControlFlowNode for x | simple.test | | Simple config | test.py:3 | 3 | ControlFlowNode for SOURCE | simple.test | | Simple config | test.py:7 | 7 | ControlFlowNode for s | simple.test | | Simple config | test.py:13 | 13 | ControlFlowNode for arg | simple.test | @@ -43,6 +48,7 @@ | Taint carrier config | carrier.py:26 | 26 | ControlFlowNode for Attribute() | simple.test | | Taint carrier config | carrier.py:30 | 30 | ControlFlowNode for Attribute() | simple.test | | Taint carrier config | carrier.py:35 | 35 | ControlFlowNode for Attribute() | simple.test | +| Taint carrier config | deep.py:22 | 22 | ControlFlowNode for x | simple.test | | Taint carrier config | test.py:3 | 3 | ControlFlowNode for SOURCE | simple.test | | Taint carrier config | test.py:7 | 7 | ControlFlowNode for s | simple.test | | Taint carrier config | test.py:13 | 13 | ControlFlowNode for arg | simple.test | @@ -72,7 +78,3 @@ | Taint carrier config | test.py:197 | 197 | ControlFlowNode for t | simple.test | | Taint carrier config | test.py:199 | 199 | ControlFlowNode for t | simple.test | | Taint carrier config | test.py:214 | 214 | ControlFlowNode for x | simple.test | -| Basic custom config | test.py:122 | 122 | ControlFlowNode for t | simple.test | -| Basic custom config | test.py:130 | 130 | ControlFlowNode for t | simple.test | -| Basic custom config | test.py:140 | 140 | ControlFlowNode for t | simple.test | -| Basic custom config | test.py:151 | 151 | ControlFlowNode for t | simple.test | diff --git a/python/ql/test/library-tests/taint/config/TestSource.expected b/python/ql/test/library-tests/taint/config/TestSource.expected index 3ce5442539a..6b93d802f54 100644 --- a/python/ql/test/library-tests/taint/config/TestSource.expected +++ b/python/ql/test/library-tests/taint/config/TestSource.expected @@ -1,3 +1,7 @@ +| Basic custom config | test.py:120 | 120 | ControlFlowNode for CUSTOM_SOURCE | simple.test | +| Basic custom config | test.py:126 | 126 | ControlFlowNode for CUSTOM_SOURCE | simple.test | +| Basic custom config | test.py:136 | 136 | ControlFlowNode for CUSTOM_SOURCE | simple.test | +| Basic custom config | test.py:146 | 146 | ControlFlowNode for CUSTOM_SOURCE | simple.test | | Rock-paper-scissors config | rockpaperscissors.py:13 | 13 | ControlFlowNode for SCISSORS | scissors | | Rock-paper-scissors config | rockpaperscissors.py:16 | 16 | ControlFlowNode for ROCK | rock | | Rock-paper-scissors config | rockpaperscissors.py:19 | 19 | ControlFlowNode for ROCK | rock | @@ -31,7 +35,3 @@ | Taint carrier config | carrier.py:21 | 21 | ControlFlowNode for TAINT_CARRIER_SOURCE | explicit.carrier | | Taint carrier config | carrier.py:29 | 29 | ControlFlowNode for TAINT_CARRIER_SOURCE | explicit.carrier | | Taint carrier config | carrier.py:33 | 33 | ControlFlowNode for TAINT_CARRIER_SOURCE | explicit.carrier | -| Basic custom config | test.py:120 | 120 | ControlFlowNode for CUSTOM_SOURCE | simple.test | -| Basic custom config | test.py:126 | 126 | ControlFlowNode for CUSTOM_SOURCE | simple.test | -| Basic custom config | test.py:136 | 136 | ControlFlowNode for CUSTOM_SOURCE | simple.test | -| Basic custom config | test.py:146 | 146 | ControlFlowNode for CUSTOM_SOURCE | simple.test | diff --git a/python/ql/test/library-tests/taint/config/TestStep.expected b/python/ql/test/library-tests/taint/config/TestStep.expected index e69de29bb2d..21a45f86cb1 100644 --- a/python/ql/test/library-tests/taint/config/TestStep.expected +++ b/python/ql/test/library-tests/taint/config/TestStep.expected @@ -0,0 +1,187 @@ +| Basic custom config: | simple.test | test.py:120 | ControlFlowNode for CUSTOM_SOURCE | | --> | simple.test | test.py:121 | ControlFlowNode for t | | +| Basic custom config: | simple.test | test.py:120 | SSA variable t | | --> | simple.test | test.py:121 | ControlFlowNode for t | | +| Basic custom config: | simple.test | test.py:126 | ControlFlowNode for CUSTOM_SOURCE | | --> | simple.test | test.py:130 | ControlFlowNode for t | | +| Basic custom config: | simple.test | test.py:126 | SSA variable t | | --> | simple.test | test.py:130 | ControlFlowNode for t | | +| Basic custom config: | simple.test | test.py:136 | ControlFlowNode for CUSTOM_SOURCE | | --> | simple.test | test.py:142 | ControlFlowNode for t | | +| Basic custom config: | simple.test | test.py:136 | SSA variable t | | --> | simple.test | test.py:142 | ControlFlowNode for t | | +| Basic custom config: | simple.test | test.py:146 | ControlFlowNode for CUSTOM_SOURCE | | --> | simple.test | test.py:149 | ControlFlowNode for t | | +| Basic custom config: | simple.test | test.py:146 | SSA variable t | | --> | simple.test | test.py:149 | ControlFlowNode for t | | +| Rock-paper-scissors config: | paper | rockpaperscissors.py:25 | ControlFlowNode for Attribute() | | --> | paper | rockpaperscissors.py:26 | ControlFlowNode for y | | +| Rock-paper-scissors config: | paper | rockpaperscissors.py:25 | SSA variable y | | --> | paper | rockpaperscissors.py:26 | ControlFlowNode for y | | +| Rock-paper-scissors config: | paper | rockpaperscissors.py:26 | ControlFlowNode for y | | --> | paper | rockpaperscissors.py:9 | ControlFlowNode for arg | Parameter 0(no attribute) is paper | +| Rock-paper-scissors config: | paper | rockpaperscissors.py:30 | ControlFlowNode for Attribute() | | --> | paper | rockpaperscissors.py:32 | ControlFlowNode for y | | +| Rock-paper-scissors config: | paper | rockpaperscissors.py:30 | SSA variable y | | --> | paper | rockpaperscissors.py:32 | ControlFlowNode for y | | +| Rock-paper-scissors config: | paper | rockpaperscissors.py:32 | ControlFlowNode for y | | --> | paper | rockpaperscissors.py:6 | ControlFlowNode for arg | Parameter 0(no attribute) is paper | +| Rock-paper-scissors config: | rock | rockpaperscissors.py:16 | ControlFlowNode for ROCK | | --> | rock | rockpaperscissors.py:6 | ControlFlowNode for arg | Parameter 0(no attribute) is rock | +| Rock-paper-scissors config: | rock | rockpaperscissors.py:19 | ControlFlowNode for ROCK | | --> | rock | rockpaperscissors.py:20 | ControlFlowNode for x | | +| Rock-paper-scissors config: | rock | rockpaperscissors.py:19 | SSA variable x | | --> | rock | rockpaperscissors.py:20 | ControlFlowNode for x | | +| Rock-paper-scissors config: | rock | rockpaperscissors.py:20 | ControlFlowNode for x | | --> | scissors | rockpaperscissors.py:20 | ControlFlowNode for Attribute() | | +| Rock-paper-scissors config: | rock | rockpaperscissors.py:24 | ControlFlowNode for ROCK | | --> | rock | rockpaperscissors.py:25 | ControlFlowNode for x | | +| Rock-paper-scissors config: | rock | rockpaperscissors.py:24 | SSA variable x | | --> | rock | rockpaperscissors.py:25 | ControlFlowNode for x | | +| Rock-paper-scissors config: | rock | rockpaperscissors.py:25 | ControlFlowNode for x | | --> | scissors | rockpaperscissors.py:25 | ControlFlowNode for Attribute() | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:13 | ControlFlowNode for SCISSORS | | --> | scissors | rockpaperscissors.py:3 | ControlFlowNode for arg | Parameter 0(no attribute) is scissors | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:20 | ControlFlowNode for Attribute() | | --> | scissors | rockpaperscissors.py:21 | ControlFlowNode for y | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:20 | SSA variable y | | --> | scissors | rockpaperscissors.py:21 | ControlFlowNode for y | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:21 | ControlFlowNode for y | | --> | scissors | rockpaperscissors.py:9 | ControlFlowNode for arg | Parameter 0(no attribute) is scissors | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:25 | ControlFlowNode for Attribute() | | --> | paper | rockpaperscissors.py:25 | ControlFlowNode for Attribute() | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:29 | ControlFlowNode for SCISSORS | | --> | scissors | rockpaperscissors.py:30 | ControlFlowNode for x | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:29 | ControlFlowNode for SCISSORS | | --> | scissors | rockpaperscissors.py:31 | ControlFlowNode for x | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:29 | SSA variable x | | --> | scissors | rockpaperscissors.py:30 | ControlFlowNode for x | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:29 | SSA variable x | | --> | scissors | rockpaperscissors.py:31 | ControlFlowNode for x | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:30 | ControlFlowNode for x | | --> | paper | rockpaperscissors.py:30 | ControlFlowNode for Attribute() | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:30 | SSA variable x | | --> | scissors | rockpaperscissors.py:31 | ControlFlowNode for x | | +| Rock-paper-scissors config: | scissors | rockpaperscissors.py:31 | ControlFlowNode for x | | --> | scissors | rockpaperscissors.py:6 | ControlFlowNode for arg | Parameter 0(no attribute) is scissors | +| Simple config: | [simple.test] | test.py:168 | ControlFlowNode for List | | --> | [simple.test] | test.py:170 | ControlFlowNode for l | | +| Simple config: | [simple.test] | test.py:168 | ControlFlowNode for List | | --> | [simple.test] | test.py:174 | ControlFlowNode for l | | +| Simple config: | [simple.test] | test.py:168 | SSA variable l | | --> | [simple.test] | test.py:170 | ControlFlowNode for l | | +| Simple config: | [simple.test] | test.py:168 | SSA variable l | | --> | [simple.test] | test.py:174 | ControlFlowNode for l | | +| Simple config: | [simple.test] | test.py:170 | SSA variable l | | --> | [simple.test] | test.py:174 | ControlFlowNode for l | | +| Simple config: | [simple.test] | test.py:174 | ControlFlowNode for l | | --> | [simple.test] | test.py:174 | ControlFlowNode for list() | | +| Simple config: | [simple.test] | test.py:208 | ControlFlowNode for List | | --> | [simple.test] | test.py:209 | ControlFlowNode for seq | | +| Simple config: | [simple.test] | test.py:208 | SSA variable seq | | --> | [simple.test] | test.py:209 | ControlFlowNode for seq | | +| Simple config: | [simple.test] | test.py:209 | ControlFlowNode for seq | | --> | simple.test | test.py:209 | ControlFlowNode for For | | +| Simple config: | [simple.test] | test.py:213 | ControlFlowNode for flow_in_generator() | | --> | simple.test | test.py:213 | ControlFlowNode for For | | +| Simple config: | iterable.simple | test.py:213 | ControlFlowNode for flow_in_generator() | | --> | simple.test | test.py:213 | ControlFlowNode for For | | +| Simple config: | simple.test | carrier.py:4 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | --> | simple.test | carrier.py:5 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | carrier.py:4 | SSA variable arg | Parameter 1(no attribute) is simple.test | --> | simple.test | carrier.py:5 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | carrier.py:17 | ControlFlowNode for SOURCE | | --> | simple.test | carrier.py:4 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | carrier.py:25 | ControlFlowNode for SOURCE | | --> | simple.test | carrier.py:4 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:2 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:3 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:2 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:3 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:3 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:6 | ControlFlowNode for f1() | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:5 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:6 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:5 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:6 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:6 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:2 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:6 | ControlFlowNode for f1() | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:9 | ControlFlowNode for f2() | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:8 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:9 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:8 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:9 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:9 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:5 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:9 | ControlFlowNode for f2() | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:12 | ControlFlowNode for f3() | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:11 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:12 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:11 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:12 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:12 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:8 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:12 | ControlFlowNode for f3() | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:15 | ControlFlowNode for f4() | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:14 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:15 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:14 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:15 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:15 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:11 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:15 | ControlFlowNode for f4() | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:18 | ControlFlowNode for f5() | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:17 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:18 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:17 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:18 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:18 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:14 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:18 | ControlFlowNode for f5() | Parameter 0(no attribute) is simple.test | --> | simple.test | deep.py:20 | ControlFlowNode for f6() | | +| Simple config: | simple.test | deep.py:20 | ControlFlowNode for SOURCE | | --> | simple.test | deep.py:17 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | deep.py:20 | ControlFlowNode for f6() | | --> | simple.test | deep.py:22 | ControlFlowNode for x | | +| Simple config: | simple.test | deep.py:20 | GSSA Variable x | | --> | simple.test | deep.py:22 | ControlFlowNode for x | | +| Simple config: | simple.test | test.py:6 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:7 | ControlFlowNode for s | | +| Simple config: | simple.test | test.py:6 | SSA variable s | | --> | simple.test | test.py:7 | ControlFlowNode for s | | +| Simple config: | simple.test | test.py:12 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | test.py:13 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | test.py:12 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | test.py:13 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | test.py:20 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:21 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:20 | SSA variable t | | --> | simple.test | test.py:21 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:21 | ControlFlowNode for t | | --> | simple.test | test.py:12 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | test.py:37 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:41 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:37 | SSA variable t | | --> | simple.test | test.py:41 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:49 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | --> | simple.test | test.py:51 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | test.py:49 | SSA variable arg | Parameter 1(no attribute) is simple.test | --> | simple.test | test.py:51 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | test.py:51 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | --> | simple.test | test.py:12 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | test.py:62 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:63 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:62 | SSA variable t | | --> | simple.test | test.py:63 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:63 | ControlFlowNode for t | | --> | simple.test | test.py:49 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | test.py:63 | SSA variable t | | --> | simple.test | test.py:63 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:67 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:70 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:67 | SSA variable t | | --> | simple.test | test.py:70 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:70 | ControlFlowNode for t | | --> | simple.test | test.py:49 | ControlFlowNode for arg | Parameter 1(no attribute) is simple.test | +| Simple config: | simple.test | test.py:70 | SSA variable t | | --> | simple.test | test.py:70 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:72 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | test.py:73 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | test.py:72 | SSA variable arg | Parameter 0(no attribute) is simple.test | --> | simple.test | test.py:73 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | test.py:73 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | --> | simple.test | test.py:77 | ControlFlowNode for hub() | | +| Simple config: | simple.test | test.py:76 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:77 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:76 | SSA variable t | | --> | simple.test | test.py:77 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:77 | ControlFlowNode for hub() | | --> | simple.test | test.py:78 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:77 | ControlFlowNode for t | | --> | simple.test | test.py:72 | ControlFlowNode for arg | Parameter 0(no attribute) is simple.test | +| Simple config: | simple.test | test.py:77 | SSA variable t | | --> | simple.test | test.py:78 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:128 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:132 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:128 | SSA variable t | | --> | simple.test | test.py:132 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:138 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:140 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:138 | SSA variable t | | --> | simple.test | test.py:140 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:148 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:149 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:148 | SSA variable t | | --> | simple.test | test.py:149 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:163 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:164 | ControlFlowNode for s | | +| Simple config: | simple.test | test.py:163 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:165 | ControlFlowNode for s | | +| Simple config: | simple.test | test.py:163 | SSA variable s | | --> | simple.test | test.py:164 | ControlFlowNode for s | | +| Simple config: | simple.test | test.py:163 | SSA variable s | | --> | simple.test | test.py:165 | ControlFlowNode for s | | +| Simple config: | simple.test | test.py:164 | SSA variable s | | --> | simple.test | test.py:165 | ControlFlowNode for s | | +| Simple config: | simple.test | test.py:168 | ControlFlowNode for SOURCE | | --> | [simple.test] | test.py:168 | ControlFlowNode for List | | +| Simple config: | simple.test | test.py:169 | ControlFlowNode for SOURCE | | --> | {simple.test} | test.py:169 | ControlFlowNode for Dict | | +| Simple config: | simple.test | test.py:178 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:179 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:178 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:180 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:178 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:183 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:178 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:186 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:178 | SSA variable t | | --> | simple.test | test.py:179 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:178 | SSA variable t | | --> | simple.test | test.py:180 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:178 | SSA variable t | | --> | simple.test | test.py:183 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:178 | SSA variable t | | --> | simple.test | test.py:186 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:180 | SSA variable t | | --> | simple.test | test.py:180 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:180 | SSA variable t | | --> | simple.test | test.py:183 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:180 | SSA variable t | | --> | simple.test | test.py:186 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:183 | SSA variable t | | --> | simple.test | test.py:186 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:195 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:196 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:195 | ControlFlowNode for SOURCE | | --> | simple.test | test.py:199 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:195 | SSA variable t | | --> | simple.test | test.py:196 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:195 | SSA variable t | | --> | simple.test | test.py:199 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:199 | SSA variable t | | --> | simple.test | test.py:199 | ControlFlowNode for t | | +| Simple config: | simple.test | test.py:208 | ControlFlowNode for SOURCE | | --> | [simple.test] | test.py:208 | ControlFlowNode for List | | +| Simple config: | simple.test | test.py:209 | ControlFlowNode for For | | --> | simple.test | test.py:210 | ControlFlowNode for i | | +| Simple config: | simple.test | test.py:209 | SSA variable i | | --> | simple.test | test.py:210 | ControlFlowNode for i | | +| Simple config: | simple.test | test.py:210 | ControlFlowNode for i | | --> | [simple.test] | test.py:213 | ControlFlowNode for flow_in_generator() | | +| Simple config: | simple.test | test.py:210 | ControlFlowNode for i | | --> | iterable.simple | test.py:213 | ControlFlowNode for flow_in_generator() | | +| Simple config: | simple.test | test.py:213 | ControlFlowNode for For | | --> | simple.test | test.py:214 | ControlFlowNode for x | | +| Simple config: | simple.test | test.py:213 | SSA variable x | | --> | simple.test | test.py:214 | ControlFlowNode for x | | +| Simple config: | {simple.test} | test.py:169 | ControlFlowNode for Dict | | --> | {simple.test} | test.py:171 | ControlFlowNode for d | | +| Simple config: | {simple.test} | test.py:169 | ControlFlowNode for Dict | | --> | {simple.test} | test.py:175 | ControlFlowNode for d | | +| Simple config: | {simple.test} | test.py:169 | SSA variable d | | --> | {simple.test} | test.py:171 | ControlFlowNode for d | | +| Simple config: | {simple.test} | test.py:169 | SSA variable d | | --> | {simple.test} | test.py:175 | ControlFlowNode for d | | +| Simple config: | {simple.test} | test.py:171 | SSA variable d | | --> | {simple.test} | test.py:175 | ControlFlowNode for d | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {Command injection} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {SQL injection} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[Command injection]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[SQL injection]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[basic.custom]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[explicit.carrier]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[falsey]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[iterable.simple]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[paper]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[rock]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[scissors]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {[simple.test]} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {basic.custom} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {explicit.carrier} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {falsey} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {iterable.simple} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {paper} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {rock} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {scissors} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {simple.test} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{Command injection}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{SQL injection}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{basic.custom}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{explicit.carrier}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{falsey}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{iterable.simple}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{paper}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{rock}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{scissors}} | test.py:175 | ControlFlowNode for dict() | | +| Simple config: | {simple.test} | test.py:175 | ControlFlowNode for d | | --> | {{simple.test}} | test.py:175 | ControlFlowNode for dict() | | +| Taint carrier config: | explicit.carrier | carrier.py:4 | ControlFlowNode for arg | Parameter 1(no attribute) is explicit.carrier | --> | explicit.carrier | carrier.py:5 | ControlFlowNode for arg | Parameter 1(no attribute) is explicit.carrier | +| Taint carrier config: | explicit.carrier | carrier.py:4 | SSA variable arg | Parameter 1(no attribute) is explicit.carrier | --> | explicit.carrier | carrier.py:5 | ControlFlowNode for arg | Parameter 1(no attribute) is explicit.carrier | +| Taint carrier config: | explicit.carrier | carrier.py:13 | ControlFlowNode for arg | Parameter 0(no attribute) is explicit.carrier | --> | explicit.carrier | carrier.py:14 | ControlFlowNode for arg | Parameter 0(no attribute) is explicit.carrier | +| Taint carrier config: | explicit.carrier | carrier.py:13 | SSA variable arg | Parameter 0(no attribute) is explicit.carrier | --> | explicit.carrier | carrier.py:14 | ControlFlowNode for arg | Parameter 0(no attribute) is explicit.carrier | +| Taint carrier config: | explicit.carrier | carrier.py:14 | ControlFlowNode for arg | Parameter 0(no attribute) is explicit.carrier | --> | explicit.carrier | carrier.py:29 | ControlFlowNode for hub() | | +| Taint carrier config: | explicit.carrier | carrier.py:21 | ControlFlowNode for TAINT_CARRIER_SOURCE | | --> | explicit.carrier | carrier.py:22 | ControlFlowNode for c | | +| Taint carrier config: | explicit.carrier | carrier.py:21 | SSA variable c | | --> | explicit.carrier | carrier.py:22 | ControlFlowNode for c | | +| Taint carrier config: | explicit.carrier | carrier.py:22 | ControlFlowNode for c | | --> | simple.test | carrier.py:22 | ControlFlowNode for Attribute() | | +| Taint carrier config: | explicit.carrier | carrier.py:29 | ControlFlowNode for TAINT_CARRIER_SOURCE | | --> | explicit.carrier | carrier.py:13 | ControlFlowNode for arg | Parameter 0(no attribute) is explicit.carrier | +| Taint carrier config: | explicit.carrier | carrier.py:29 | ControlFlowNode for hub() | | --> | explicit.carrier | carrier.py:30 | ControlFlowNode for c | | +| Taint carrier config: | explicit.carrier | carrier.py:29 | SSA variable c | | --> | explicit.carrier | carrier.py:30 | ControlFlowNode for c | | +| Taint carrier config: | explicit.carrier | carrier.py:30 | ControlFlowNode for c | | --> | simple.test | carrier.py:30 | ControlFlowNode for Attribute() | | +| Taint carrier config: | explicit.carrier | carrier.py:33 | ControlFlowNode for TAINT_CARRIER_SOURCE | | --> | explicit.carrier | carrier.py:4 | ControlFlowNode for arg | Parameter 1(no attribute) is explicit.carrier | diff --git a/python/ql/test/library-tests/taint/dataflow/Dataflow.expected b/python/ql/test/library-tests/taint/dataflow/Dataflow.expected index d01f6c7b913..e69de29bb2d 100644 --- a/python/ql/test/library-tests/taint/dataflow/Dataflow.expected +++ b/python/ql/test/library-tests/taint/dataflow/Dataflow.expected @@ -1,16 +0,0 @@ -| test.py:3:10:3:15 | ControlFlowNode for SOURCE | test.py:3:10:3:15 | ControlFlowNode for SOURCE | -| test.py:6:9:6:14 | ControlFlowNode for SOURCE | test.py:7:10:7:10 | ControlFlowNode for s | -| test.py:10:12:10:17 | ControlFlowNode for SOURCE | test.py:13:10:13:12 | ControlFlowNode for arg | -| test.py:10:12:10:17 | ControlFlowNode for SOURCE | test.py:17:10:17:10 | ControlFlowNode for t | -| test.py:20:9:20:14 | ControlFlowNode for SOURCE | test.py:13:10:13:12 | ControlFlowNode for arg | -| test.py:37:13:37:18 | ControlFlowNode for SOURCE | test.py:41:14:41:14 | ControlFlowNode for t | -| test.py:62:13:62:18 | ControlFlowNode for SOURCE | test.py:13:10:13:12 | ControlFlowNode for arg | -| test.py:67:13:67:18 | ControlFlowNode for SOURCE | test.py:13:10:13:12 | ControlFlowNode for arg | -| test.py:76:9:76:14 | ControlFlowNode for SOURCE | test.py:78:10:78:10 | ControlFlowNode for t | -| test.py:108:13:108:18 | ControlFlowNode for SOURCE | test.py:112:14:112:14 | ControlFlowNode for t | -| test.py:139:10:139:15 | ControlFlowNode for SOURCE | test.py:140:14:140:14 | ControlFlowNode for t | -| test.py:143:9:143:14 | ControlFlowNode for SOURCE | test.py:145:10:145:10 | ControlFlowNode for s | -| test.py:148:10:148:15 | ControlFlowNode for SOURCE | test.py:152:10:152:13 | ControlFlowNode for Subscript | -| test.py:149:18:149:23 | ControlFlowNode for SOURCE | test.py:153:10:153:17 | ControlFlowNode for Subscript | -| test.py:158:9:158:14 | ControlFlowNode for SOURCE | test.py:160:14:160:14 | ControlFlowNode for t | -| test.py:158:9:158:14 | ControlFlowNode for SOURCE | test.py:166:14:166:14 | ControlFlowNode for t | diff --git a/python/ql/test/library-tests/taint/dataflow/TestNode.expected b/python/ql/test/library-tests/taint/dataflow/TestNode.expected index e5da7fd0405..fafd625611b 100644 --- a/python/ql/test/library-tests/taint/dataflow/TestNode.expected +++ b/python/ql/test/library-tests/taint/dataflow/TestNode.expected @@ -1,72 +1,2 @@ -| Taint Data flow | test.py:3 | SOURCE | | -| Taint Data flow | test.py:6 | SOURCE | | -| Taint Data flow | test.py:7 | s | | -| Taint Data flow | test.py:10 | SOURCE | | -| Taint Data flow | test.py:12 | arg | test.py:21 | -| Taint Data flow | test.py:12 | arg | test.py:25 | -| Taint Data flow | test.py:12 | arg | test.py:47 from test.py:55 | -| Taint Data flow | test.py:12 | arg | test.py:51 from test.py:63 | -| Taint Data flow | test.py:12 | arg | test.py:51 from test.py:70 | -| Taint Data flow | test.py:13 | arg | test.py:21 | -| Taint Data flow | test.py:13 | arg | test.py:25 | -| Taint Data flow | test.py:13 | arg | test.py:47 from test.py:55 | -| Taint Data flow | test.py:13 | arg | test.py:51 from test.py:63 | -| Taint Data flow | test.py:13 | arg | test.py:51 from test.py:70 | -| Taint Data flow | test.py:16 | source() | | -| Taint Data flow | test.py:17 | t | | -| Taint Data flow | test.py:20 | SOURCE | | -| Taint Data flow | test.py:21 | t | | -| Taint Data flow | test.py:24 | source() | | -| Taint Data flow | test.py:25 | t | | -| Taint Data flow | test.py:31 | SOURCE | | -| Taint Data flow | test.py:37 | SOURCE | | -| Taint Data flow | test.py:41 | t | | -| Taint Data flow | test.py:44 | source() | | -| Taint Data flow | test.py:46 | arg | test.py:55 | -| Taint Data flow | test.py:47 | arg | test.py:55 | -| Taint Data flow | test.py:49 | arg | test.py:63 | -| Taint Data flow | test.py:49 | arg | test.py:70 | -| Taint Data flow | test.py:51 | arg | test.py:63 | -| Taint Data flow | test.py:51 | arg | test.py:70 | -| Taint Data flow | test.py:54 | source2() | | -| Taint Data flow | test.py:55 | t | | -| Taint Data flow | test.py:62 | SOURCE | | -| Taint Data flow | test.py:63 | t | | -| Taint Data flow | test.py:67 | SOURCE | | -| Taint Data flow | test.py:70 | t | | -| Taint Data flow | test.py:72 | arg | test.py:77 | -| Taint Data flow | test.py:73 | arg | test.py:77 | -| Taint Data flow | test.py:76 | SOURCE | | -| Taint Data flow | test.py:77 | hub() | | -| Taint Data flow | test.py:77 | t | | -| Taint Data flow | test.py:78 | t | | -| Taint Data flow | test.py:108 | SOURCE | | -| Taint Data flow | test.py:112 | t | | -| Taint Data flow | test.py:118 | SOURCE | | -| Taint Data flow | test.py:120 | t | | -| Taint Data flow | test.py:128 | SOURCE | | -| Taint Data flow | test.py:129 | t | | -| Taint Data flow | test.py:139 | SOURCE | | -| Taint Data flow | test.py:140 | t | | -| Taint Data flow | test.py:143 | SOURCE | | -| Taint Data flow | test.py:144 | s | | -| Taint Data flow | test.py:145 | s | | -| Taint Data flow | test.py:148 | SOURCE | | -| Taint Data flow | test.py:149 | SOURCE | | -| Taint Data flow | test.py:152 | Subscript | | -| Taint Data flow | test.py:153 | Subscript | | -| Taint Data flow | test.py:158 | SOURCE | | -| Taint Data flow | test.py:159 | t | | -| Taint Data flow | test.py:160 | t | | -| Taint Data flow | test.py:163 | t | | -| Taint Data flow | test.py:166 | t | | -| Taint [Data flow] | test.py:148 | List | | -| Taint [Data flow] | test.py:150 | l | | -| Taint [Data flow] | test.py:152 | x | | -| Taint [Data flow] | test.py:154 | l | | -| Taint [Data flow] | test.py:154 | list() | | -| Taint {Data flow} | test.py:149 | Dict | | -| Taint {Data flow} | test.py:151 | d | | -| Taint {Data flow} | test.py:153 | y | | -| Taint {Data flow} | test.py:155 | d | | -| Taint {Data flow} | test.py:155 | dict() | | +ERROR: getNode() cannot be resolved for type Node (TestNode.ql:5,69-76) +ERROR: getTrackedValue() cannot be resolved for type TaintedNode (TestNode.ql:5,10-25) diff --git a/python/ql/test/library-tests/taint/general/TaintLib.qll b/python/ql/test/library-tests/taint/general/TaintLib.qll index 256ef1d8f1a..0fbad98ee9c 100644 --- a/python/ql/test/library-tests/taint/general/TaintLib.qll +++ b/python/ql/test/library-tests/taint/general/TaintLib.qll @@ -386,5 +386,3 @@ class TaintIterableSource extends TaintSource { } - - diff --git a/python/ql/test/library-tests/taint/general/TestDefn.ql b/python/ql/test/library-tests/taint/general/TestDefn.ql index 101be83be24..6cc9497583c 100644 --- a/python/ql/test/library-tests/taint/general/TestDefn.ql +++ b/python/ql/test/library-tests/taint/general/TestDefn.ql @@ -4,6 +4,6 @@ import TaintLib from EssaDefinition defn, TaintedNode n -where TaintFlowTest::tainted_def(defn, _, n) +where n.getNode().asVariable() = defn.getVariable() select - defn.getLocation().toString(), defn.getRepresentation(), n.getLocation().toString(), n.getTrackedValue(), n.getNode().getNode().toString() + defn.getLocation().toString(), defn.getRepresentation(), n.getLocation().toString(), "Taint " + n.getTaintKind(), n.getCfgNode().getNode().toString() diff --git a/python/ql/test/library-tests/taint/general/TestStep.ql b/python/ql/test/library-tests/taint/general/TestStep.ql index 191ab6b1483..3af5c2fc35f 100644 --- a/python/ql/test/library-tests/taint/general/TestStep.ql +++ b/python/ql/test/library-tests/taint/general/TestStep.ql @@ -6,6 +6,6 @@ import TaintLib from TaintedNode n, TaintedNode s where s = n.getASuccessor() select - n.getTrackedValue(), n.getLocation().toString(), n.getNode().getNode().toString(), n.getContext(), + n.getTaintKind(), n.getLocation().toString(), n.getNode().toString(), n.getContext(), " --> ", - s.getTrackedValue(), s.getLocation().toString(), s.getNode().getNode().toString(), s.getContext() + s.getTaintKind(), s.getLocation().toString(), s.getNode().toString(), s.getContext() diff --git a/python/ql/test/library-tests/taint/strings/DistinctStringKinds.expected b/python/ql/test/library-tests/taint/strings/DistinctStringKinds.expected index 684c12a3746..59886be2738 100644 --- a/python/ql/test/library-tests/taint/strings/DistinctStringKinds.expected +++ b/python/ql/test/library-tests/taint/strings/DistinctStringKinds.expected @@ -1,16 +1,16 @@ -| Taint exception.info | test.py:54 | test.py:54:22:54:26 | taint | test.py:59 | -| Taint exception.info | test.py:55 | test.py:55:12:55:22 | func() | test.py:59 | -| Taint exception.info | test.py:55 | test.py:55:17:55:21 | taint | test.py:59 | +| Taint exception.info | test.py:54 | test.py:54:22:54:26 | taint | Parameter 1(no attribute) is exception.info | +| Taint exception.info | test.py:55 | test.py:55:12:55:22 | func() | Parameter 1(no attribute) is exception.info | +| Taint exception.info | test.py:55 | test.py:55:17:55:21 | taint | Parameter 1(no attribute) is exception.info | | Taint exception.info | test.py:58 | test.py:58:12:58:33 | TAINTED_EXCEPTION_INFO | | | Taint exception.info | test.py:59 | test.py:59:11:59:41 | cross_over() | | | Taint exception.info | test.py:59 | test.py:59:37:59:40 | info | | -| Taint exception.info | test.py:61 | test.py:61:19:61:21 | arg | test.py:55 from test.py:59 | -| Taint exception.info | test.py:62 | test.py:62:12:62:14 | arg | test.py:55 from test.py:59 | -| Taint externally controlled string | test.py:54 | test.py:54:22:54:26 | taint | test.py:66 | -| Taint externally controlled string | test.py:55 | test.py:55:12:55:22 | func() | test.py:66 | -| Taint externally controlled string | test.py:55 | test.py:55:17:55:21 | taint | test.py:66 | -| Taint externally controlled string | test.py:61 | test.py:61:19:61:21 | arg | test.py:55 from test.py:66 | -| Taint externally controlled string | test.py:62 | test.py:62:12:62:14 | arg | test.py:55 from test.py:66 | +| Taint exception.info | test.py:61 | test.py:61:19:61:21 | arg | Parameter 0(no attribute) is exception.info | +| Taint exception.info | test.py:62 | test.py:62:12:62:14 | arg | Parameter 0(no attribute) is exception.info | +| Taint externally controlled string | test.py:54 | test.py:54:22:54:26 | taint | Parameter 1(no attribute) is externally controlled string | +| Taint externally controlled string | test.py:55 | test.py:55:12:55:22 | func() | Parameter 1(no attribute) is externally controlled string | +| Taint externally controlled string | test.py:55 | test.py:55:17:55:21 | taint | Parameter 1(no attribute) is externally controlled string | +| Taint externally controlled string | test.py:61 | test.py:61:19:61:21 | arg | Parameter 0(no attribute) is externally controlled string | +| Taint externally controlled string | test.py:62 | test.py:62:12:62:14 | arg | Parameter 0(no attribute) is externally controlled string | | Taint externally controlled string | test.py:65 | test.py:65:11:65:33 | TAINTED_EXTERNAL_STRING | | | Taint externally controlled string | test.py:66 | test.py:66:11:66:41 | cross_over() | | | Taint externally controlled string | test.py:66 | test.py:66:38:66:40 | ext | | diff --git a/python/ql/test/library-tests/taint/strings/DistinctStringKinds.ql b/python/ql/test/library-tests/taint/strings/DistinctStringKinds.ql index 93dd6caa29e..f8a154c1724 100644 --- a/python/ql/test/library-tests/taint/strings/DistinctStringKinds.ql +++ b/python/ql/test/library-tests/taint/strings/DistinctStringKinds.ql @@ -32,8 +32,7 @@ class ExternalStringSource extends TaintSource { } } - from TaintedNode n where n.getLocation().getFile().getName().matches("%test.py") -select n.getTrackedValue(), n.getLocation().toString(), n.getAstNode(), n.getContext() +select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext() diff --git a/python/ql/test/library-tests/taint/strings/Taint.qll b/python/ql/test/library-tests/taint/strings/Taint.qll index d39487b5ad3..6ed0d801fc7 100644 --- a/python/ql/test/library-tests/taint/strings/Taint.qll +++ b/python/ql/test/library-tests/taint/strings/Taint.qll @@ -11,7 +11,7 @@ class SimpleSource extends TaintSource { kind instanceof ExternalStringKind } - string toString() { + override string toString() { result = "taint source" } @@ -25,7 +25,7 @@ class ListSource extends TaintSource { kind instanceof ExternalStringSequenceKind } - string toString() { + override string toString() { result = "list taint source" } @@ -39,9 +39,8 @@ class DictSource extends TaintSource { kind instanceof ExternalStringDictKind } - string toString() { + override string toString() { result = "dict taint source" } -} - +} \ No newline at end of file diff --git a/python/ql/test/library-tests/taint/strings/TestNode.ql b/python/ql/test/library-tests/taint/strings/TestNode.ql index 61b27ced486..37275036feb 100644 --- a/python/ql/test/library-tests/taint/strings/TestNode.ql +++ b/python/ql/test/library-tests/taint/strings/TestNode.ql @@ -5,5 +5,5 @@ import Taint from TaintedNode n where n.getLocation().getFile().getName().matches("%test.py") -select n.getTrackedValue(), n.getLocation().toString(), n.getAstNode(), n.getContext() +select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getCfgNode().getNode(), n.getContext() diff --git a/python/ql/test/library-tests/taint/strings/TestStep.ql b/python/ql/test/library-tests/taint/strings/TestStep.ql index 9d28968ebde..ccd5a4ec642 100644 --- a/python/ql/test/library-tests/taint/strings/TestStep.ql +++ b/python/ql/test/library-tests/taint/strings/TestStep.ql @@ -8,6 +8,6 @@ where n.getLocation().getFile().getName().matches("%test.py") and s.getLocation().getFile().getName().matches("%test.py") and s = n.getASuccessor() select - n.getTrackedValue(), n.getLocation().toString(), n.getAstNode(), n.getContext(), + "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(), " --> ", - s.getTrackedValue(), s.getLocation().toString(), s.getAstNode(), s.getContext() + "Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext()