Merge branch 'main' into py/CsvInjection

This commit is contained in:
yoff
2022-05-25 10:43:08 +02:00
committed by GitHub
6918 changed files with 534741 additions and 123456 deletions

View File

@@ -55,6 +55,7 @@
| Dict | 46 | 54 | 46 | 55 |
| Dict | 48 | 9 | 48 | 19 |
| DictUnpacking | 46 | 52 | 46 | 55 |
| DjangoViewClassHelper | 4 | 1 | 4 | 8 |
| Ellipsis | 7 | 7 | 7 | 9 |
| Ellipsis | 50 | 14 | 50 | 16 |
| ExceptStmt | 32 | 9 | 32 | 31 |

View File

@@ -44,6 +44,7 @@
| Dict | 46 | 54 | 46 | 55 |
| Dict | 48 | 9 | 48 | 19 |
| DictUnpacking | 46 | 52 | 46 | 55 |
| DjangoViewClassHelper | 4 | 1 | 4 | 8 |
| Ellipsis | 7 | 7 | 7 | 9 |
| Ellipsis | 50 | 14 | 50 | 16 |
| ExceptStmt | 32 | 9 | 32 | 31 |

View File

@@ -11,6 +11,4 @@
| test.py:4:5:4:17 | CtxManager3() |
| test.py:4:5:4:29 | With |
| test.py:4:22:4:29 | example3 |
| test.py:4:31:4:30 | |
| test.py:4:31:4:30 | With |
| test.py:6:5:6:8 | Pass |

View File

@@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string {
abstract predicate hasActualResult(Location location, string element, string tag, string value);
/**
* Like `hasActualResult`, but returns results that do not require a matching annotation.
* Holds if there is an optional result on the specified location.
*
* This is similar to `hasActualResult`, but returns results that do not require a matching annotation.
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
* Override this predicate to specify optional results.
*/
@@ -179,7 +181,7 @@ private string expectationCommentPattern() { result = "\\s*\\$((?:[^/]|/[^/])*)(
/**
* The possible columns in an expectation comment. The `TDefaultColumn` branch represents the first
* column in a comment. This column is not precedeeded by a name. `TNamedColumn(name)` represents a
* column containing expected results preceeded by the string `name:`.
* column containing expected results preceded by the string `name:`.
*/
private newtype TColumn =
TDefaultColumn() or

View File

@@ -0,0 +1,135 @@
/**
* A test query that verifies assertions about the API graph embedded in source-code comments.
*
* An assertion is a comment of the form `def=<path>` or `use=<path>`, and asserts that
* there is a def/use feature reachable from the root along the given path, and its
* associated data-flow node must start on the same line as the comment.
*
* We also support negative assertions of the form `MISSING: def <path>` or `MISSING: use <path>`, which assert
* that there _isn't_ a node with the given path on the same line.
*
* The query only produces output for failed assertions, meaning that it should have no output
* under normal circumstances.
*
* The syntax is made to look exactly like inline expectation tests, so that the tests
* can remain consistent with other Python tests.
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.ApiGraphs
private DataFlow::Node getNode(API::Node nd, string kind) {
kind = "def" and
result = nd.getARhs()
or
kind = "use" and
result = nd.getAUse()
}
private string getLocStr(Location loc) {
exists(string filepath, int startline |
loc.hasLocationInfo(filepath, startline, _, _, _) and
result = filepath + ":" + startline
)
}
/**
* An assertion matching a data-flow node against an API-graph feature.
*/
class Assertion extends Comment {
string expectedKind;
string expectedLoc;
string path;
string polarity;
Assertion() {
exists(string txt, string rex |
txt = this.getText().trim() and
rex = "#\\$.*?((?:MISSING: )?)(def|use)=([\\w\\(\\)\"\\.]*).*"
|
polarity = txt.regexpCapture(rex, 1) and
expectedKind = txt.regexpCapture(rex, 2) and
path = txt.regexpCapture(rex, 3) and
expectedLoc = getLocStr(this.getLocation())
)
}
string getEdgeLabel(int i) {
// matches a single edge. E.g. `getParameter(1)` or `getMember("foo")`.
// The lookbehind/lookahead ensure that the boundary is correct, that is
// either the edge is next to a ".", or it's the end of the string.
result = path.regexpFind("(?<=\\.|^)([\\w\\(\\)\"]+)(?=\\.|$)", i, _).trim()
}
int getPathLength() { result = max(int i | exists(this.getEdgeLabel(i))) + 1 }
predicate isNegative() { polarity = "MISSING: " }
API::Node lookup(int i) {
i = 0 and
result = API::root()
or
result =
this.lookup(i - 1)
.getASuccessor(any(API::Label::ApiLabel label |
label.toString() = this.getEdgeLabel(i - 1)
))
}
API::Node lookup() { result = this.lookup(this.getPathLength()) }
predicate holds() { getLocStr(getNode(this.lookup(), expectedKind).getLocation()) = expectedLoc }
string tryExplainFailure() {
exists(int i, API::Node nd, string prefix, string suffix |
nd = this.lookup(i) and
i < getPathLength() and
not exists(this.lookup([i + 1 .. getPathLength()])) and
prefix = nd + " has no outgoing edge labelled " + this.getEdgeLabel(i) + ";" and
if exists(nd.getASuccessor())
then
suffix =
"it does have outgoing edges labelled " +
concat(string lbl |
exists(nd.getASuccessor(any(API::Label::ApiLabel label | label.toString() = lbl)))
|
lbl, ", "
) + "."
else suffix = "it has no outgoing edges at all."
|
result = prefix + " " + suffix
)
or
exists(API::Node nd, string kind | nd = this.lookup() |
exists(getNode(nd, kind)) and
not exists(getNode(nd, expectedKind)) and
result = "Expected " + expectedKind + " node, but found " + kind + " node."
)
or
exists(DataFlow::Node nd | nd = getNode(this.lookup(), expectedKind) |
not getLocStr(nd.getLocation()) = expectedLoc and
result =
"Node not found on this line (but there is one on line " + min(getLocStr(nd.getLocation())) +
")."
)
}
string explainFailure() {
if this.isNegative()
then (
this.holds() and
result = "Negative assertion failed."
) else (
not this.holds() and
(
result = this.tryExplainFailure()
or
not exists(this.tryExplainFailure()) and
result = "Positive assertion failed for unknown reasons."
)
)
}
}
query predicate failed(Assertion a, string explanation) { explanation = a.explainFailure() }

View File

@@ -0,0 +1,2 @@
| test.py:10:1:10:9 | ControlFlowNode for Attribute | test.py:10:1:10:5 | ControlFlowNode for myobj | foo |
| test.py:13:1:13:21 | ControlFlowNode for getattr() | test.py:13:9:13:13 | ControlFlowNode for myobj | foo |

View File

@@ -0,0 +1,5 @@
import python
private import semmle.python.dataflow.new.DataFlow
from DataFlow::AttrRead read
select read, read.getObject(), read.getAttributeName()

View File

@@ -0,0 +1,4 @@
| test.py:5:9:5:16 | ControlFlowNode for __init__ | test.py:4:1:4:20 | ControlFlowNode for ClassExpr | __init__ | test.py:5:5:5:28 | ControlFlowNode for FunctionExpr |
| test.py:6:9:6:16 | ControlFlowNode for Attribute | test.py:6:9:6:12 | ControlFlowNode for self | foo | test.py:6:20:6:22 | ControlFlowNode for foo |
| test.py:9:1:9:9 | ControlFlowNode for Attribute | test.py:9:1:9:5 | ControlFlowNode for myobj | foo | test.py:9:13:9:17 | ControlFlowNode for Str |
| test.py:12:1:12:25 | ControlFlowNode for setattr() | test.py:12:9:12:13 | ControlFlowNode for myobj | foo | test.py:12:23:12:24 | ControlFlowNode for IntegerLiteral |

View File

@@ -0,0 +1,5 @@
import python
private import semmle.python.dataflow.new.DataFlow
from DataFlow::AttrWrite write
select write, write.getObject(), write.getAttributeName(), write.getValue()

View File

@@ -0,0 +1,13 @@
# This file is a simple test of which nodes are included with AttrRead/AttrWrite.
# For actual data-flow tests, see fieldflow/ dir.
class MyObj(object):
def __init__(self, foo):
self.foo = foo
myobj = MyObj("foo")
myobj.foo = "bar"
myobj.foo
setattr(myobj, "foo", 42)
getattr(myobj, "foo")

View File

@@ -1,26 +0,0 @@
import python
import semmle.python.dataflow.new.DataFlow
import TestUtilities.InlineExpectationsTest
import semmle.python.ApiGraphs
class AwaitedTest extends InlineExpectationsTest {
AwaitedTest() { this = "AwaitedTest" }
override string getARelevantTag() { result = "awaited" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(API::Node awaited, DataFlow::Node use, API::Node pred |
awaited = pred.getAwaited() and
use = awaited.getAUse() and
location = use.getLocation() and
// Module variable nodes have no suitable location, so it's best to simply exclude them entirely
// from the inline tests.
not use instanceof DataFlow::ModuleVariableNode and
exists(location.getFile().getRelativePath())
|
tag = "awaited" and
value = pred.getPath() and
element = use.toString()
)
}
}

View File

@@ -1,35 +0,0 @@
import python
import semmle.python.dataflow.new.DataFlow
import TestUtilities.InlineExpectationsTest
import semmle.python.ApiGraphs
class ApiUseTest extends InlineExpectationsTest {
ApiUseTest() { this = "ApiUseTest" }
override string getARelevantTag() { result = "use" }
private predicate relevant_node(API::Node a, DataFlow::Node n, Location l) {
n = a.getAUse() and
l = n.getLocation() and
// Module variable nodes have no suitable location, so it's best to simply exclude them entirely
// from the inline tests.
not n instanceof DataFlow::ModuleVariableNode and
exists(l.getFile().getRelativePath())
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(API::Node a, DataFlow::Node n | relevant_node(a, n, location) |
tag = "use" and
// Only report the longest path on this line:
value =
max(API::Node a2, Location l2 |
relevant_node(a2, _, l2) and
l2.getFile() = location.getFile() and
l2.getStartLine() = location.getStartLine()
|
a2.getPath()
) and
element = n.toString()
)
}
}

View File

@@ -0,0 +1,33 @@
import python
import experimental.dataflow.TestUtil.FlowTest
import experimental.dataflow.testConfig
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowTest extends FlowTest {
DataFlowTest() { this = "DataFlowTest" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
}
}
query predicate missingAnnotationOnSINK(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: flow` annotation" and
exists(DataFlow::Node sink |
exists(DataFlow::CallCfgNode call |
// note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually.
call.getFunction().asCfgNode().(NameNode).getId() = "SINK" and
(sink = call.getArg(_) or sink = call.getArgByName(_))
) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not any(TestConfiguration config).hasFlow(_, sink) and
not exists(FalseNegativeExpectation missingResult |
missingResult.getTag() = "flow" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()
)
)
}

View File

@@ -0,0 +1,23 @@
import python
private import semmle.python.dataflow.new.internal.PrintNode
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
private import semmle.python.ApiGraphs
import TestUtilities.InlineExpectationsTest
class UnresolvedCallExpectations extends InlineExpectationsTest {
UnresolvedCallExpectations() { this = "UnresolvedCallExpectations" }
override string getARelevantTag() { result = "unresolved_call" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(CallNode call |
not exists(DataFlowPrivate::DataFlowCall dfc | dfc.getNode() = call) and
not call = API::builtin(_).getACall().asCfgNode() and
location = call.getLocation() and
tag = "unresolved_call" and
value = prettyExpr(call.getNode()) and
element = call.toString()
)
}
}

View File

@@ -0,0 +1,34 @@
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.internal.DataFlowPrivate
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowCallTest extends InlineExpectationsTest {
DataFlowCallTest() { this = "DataFlowCallTest" }
override string getARelevantTag() {
result in ["call", "qlclass"]
or
result = "arg_" + [0 .. 10]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(DataFlowCall call |
location = call.getLocation() and
element = call.toString()
|
value = prettyExpr(call.getNode().getNode()) and
tag = "call"
or
value = call.getAQlClass() and
tag = "qlclass"
or
exists(int n, DataFlow::Node arg | arg = call.getArg(n) |
value = prettyNodeForInlineTest(arg) and
tag = "arg_" + n
)
)
}
}

View File

@@ -0,0 +1,37 @@
# A very basic test of DataFlowCall
#
# see `coverage/argumentRoutingTest.ql` for a more in depth test of argument routing
# handling.
def func(arg):
pass
class MyClass(object):
def __init__(self, arg):
pass
def my_method(self, arg):
pass
def __getitem__(self, key):
pass
func("foo") # $ call=func(..) qlclass=FunctionCall arg_0="foo"
x = MyClass(1) # $ call=MyClass(..) qlclass=ClassCall arg_0=[pre]MyClass(..) arg_1=1
x.my_method(2) # $ call=x.my_method(..) qlclass=MethodCall arg_0=x arg_1=2
mm = x.my_method
mm(2) # $ call=mm(..) qlclass=MethodCall arg_1=2 MISSING: arg_0=x
x[3] # $ call=x[3] qlclass=SpecialCall arg_0=x arg_1=3
try:
# These are included to show how we handle absent things with points-to where
# `mypkg.foo` is a `missing module variable`, but `mypkg.subpkg.bar` is compeltely
# ignored.
import mypkg
mypkg.foo(42)
mypkg.subpkg.bar(43)
except:
pass

View File

@@ -0,0 +1,2 @@
missingAnnotationOnSINK
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.NormalDataflowTest

View File

@@ -1,8 +1,9 @@
import sys
import os
import functools
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
from testlib import *
from testlib import expects
arg = "source"
arg1 = "source1"
@@ -29,36 +30,13 @@ def SINK_F(x, unexpected=arg):
SINK_TEST(x, test=lambda x: x != unexpected)
def SINK1(x):
SINK(x, expected=arg1)
def SINK2(x):
SINK(x, expected=arg2)
def SINK2_F(x):
SINK_F(x, unexpected=arg2)
def SINK3(x):
SINK(x, expected=arg3)
def SINK4(x):
SINK(x, expected=arg4)
def SINK5(x):
SINK(x, expected=arg5)
def SINK6(x):
SINK(x, expected=arg6)
def SINK7(x):
SINK(x, expected=arg7)
SINK1 = functools.partial(SINK, expected=arg1)
SINK2 = functools.partial(SINK, expected=arg2)
SINK3 = functools.partial(SINK, expected=arg3)
SINK4 = functools.partial(SINK, expected=arg4)
SINK5 = functools.partial(SINK, expected=arg5)
SINK6 = functools.partial(SINK, expected=arg6)
SINK7 = functools.partial(SINK, expected=arg7)
def argument_passing(

View File

@@ -1,239 +0,0 @@
edges
| argumentPassing.py:65:5:65:5 | ControlFlowNode for a | argumentPassing.py:75:11:75:11 | ControlFlowNode for a |
| argumentPassing.py:89:22:89:25 | ControlFlowNode for arg1 | argumentPassing.py:65:5:65:5 | ControlFlowNode for a |
| argumentPassing.py:94:22:94:25 | ControlFlowNode for arg1 | argumentPassing.py:65:5:65:5 | ControlFlowNode for a |
| argumentPassing.py:97:19:97:19 | ControlFlowNode for a | argumentPassing.py:98:11:98:11 | ControlFlowNode for a |
| argumentPassing.py:104:19:104:22 | ControlFlowNode for arg1 | argumentPassing.py:97:19:97:19 | ControlFlowNode for a |
| argumentPassing.py:105:19:105:22 | ControlFlowNode for arg1 | argumentPassing.py:97:19:97:19 | ControlFlowNode for a |
| argumentPassing.py:106:19:106:22 | ControlFlowNode for arg1 | argumentPassing.py:97:19:97:19 | ControlFlowNode for a |
| argumentPassing.py:109:27:109:27 | ControlFlowNode for a | argumentPassing.py:110:11:110:11 | ControlFlowNode for a |
| argumentPassing.py:117:45:117:48 | ControlFlowNode for arg1 | argumentPassing.py:109:27:109:27 | ControlFlowNode for a |
| argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | argumentPassing.py:109:27:109:27 | ControlFlowNode for a |
| argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | argumentPassing.py:109:27:109:27 | ControlFlowNode for a |
| argumentPassing.py:120:5:120:70 | KwUnpacked a | argumentPassing.py:109:27:109:27 | ControlFlowNode for a |
| argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | argumentPassing.py:120:5:120:70 | KwUnpacked a |
| argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] |
| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | argumentPassing.py:124:11:124:11 | ControlFlowNode for a |
| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | argumentPassing.py:124:11:124:11 | ControlFlowNode for a |
| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:123:28:123:28 | ControlFlowNode for a |
| argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:123:28:123:28 | ControlFlowNode for a |
| argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | argumentPassing.py:139:11:139:13 | ControlFlowNode for foo |
| argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:138:22:138:24 | ControlFlowNode for foo |
| argumentPassing.py:165:18:165:18 | ControlFlowNode for a | argumentPassing.py:166:15:166:15 | ControlFlowNode for a |
| argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | argumentPassing.py:165:18:165:18 | ControlFlowNode for a |
| argumentPassing.py:172:23:172:23 | ControlFlowNode for a | argumentPassing.py:173:15:173:15 | ControlFlowNode for a |
| argumentPassing.py:175:19:175:22 | ControlFlowNode for arg1 | argumentPassing.py:172:23:172:23 | ControlFlowNode for a |
| argumentPassing.py:179:20:179:20 | ControlFlowNode for a [Tuple element at index 0] | argumentPassing.py:181:19:181:19 | ControlFlowNode for a [Tuple element at index 0] |
| argumentPassing.py:181:19:181:19 | ControlFlowNode for a [Tuple element at index 0] | argumentPassing.py:181:19:181:22 | ControlFlowNode for Subscript |
| argumentPassing.py:183:5:183:19 | PosOverflowNode for with_star() [Tuple element at index 0] | argumentPassing.py:179:20:179:20 | ControlFlowNode for a [Tuple element at index 0] |
| argumentPassing.py:183:15:183:18 | ControlFlowNode for arg1 | argumentPassing.py:183:5:183:19 | PosOverflowNode for with_star() [Tuple element at index 0] |
| argumentPassing.py:187:17:187:17 | ControlFlowNode for a | argumentPassing.py:188:15:188:15 | ControlFlowNode for a |
| argumentPassing.py:190:13:190:16 | ControlFlowNode for arg1 | argumentPassing.py:187:17:187:17 | ControlFlowNode for a |
| argumentPassing.py:194:18:194:18 | ControlFlowNode for a | argumentPassing.py:195:15:195:15 | ControlFlowNode for a |
| argumentPassing.py:197:16:197:19 | ControlFlowNode for arg1 | argumentPassing.py:194:18:194:18 | ControlFlowNode for a |
| argumentPassing.py:201:17:201:17 | ControlFlowNode for a | argumentPassing.py:202:15:202:15 | ControlFlowNode for a |
| argumentPassing.py:204:15:204:18 | ControlFlowNode for arg1 | argumentPassing.py:201:17:201:17 | ControlFlowNode for a |
| argumentPassing.py:208:27:208:27 | ControlFlowNode for a [Dictionary element at key a] | argumentPassing.py:209:15:209:15 | ControlFlowNode for a [Dictionary element at key a] |
| argumentPassing.py:209:15:209:15 | ControlFlowNode for a [Dictionary element at key a] | argumentPassing.py:209:15:209:20 | ControlFlowNode for Subscript |
| argumentPassing.py:211:5:211:27 | KwOverflowNode for with_doublestar() [Dictionary element at key a] | argumentPassing.py:208:27:208:27 | ControlFlowNode for a [Dictionary element at key a] |
| argumentPassing.py:211:23:211:26 | ControlFlowNode for arg1 | argumentPassing.py:211:5:211:27 | KwOverflowNode for with_doublestar() [Dictionary element at key a] |
| classes.py:555:21:555:24 | ControlFlowNode for self | classes.py:557:15:557:18 | ControlFlowNode for self |
| classes.py:563:5:563:16 | SSA variable with_getitem | classes.py:565:5:565:16 | ControlFlowNode for with_getitem |
| classes.py:565:5:565:16 | ControlFlowNode for with_getitem | classes.py:555:21:555:24 | ControlFlowNode for self |
| classes.py:570:21:570:24 | ControlFlowNode for self | classes.py:573:15:573:18 | ControlFlowNode for self |
| classes.py:578:5:578:16 | SSA variable with_setitem | classes.py:581:5:581:16 | ControlFlowNode for with_setitem |
| classes.py:581:5:581:16 | ControlFlowNode for with_setitem | classes.py:570:21:570:24 | ControlFlowNode for self |
| classes.py:586:21:586:24 | ControlFlowNode for self | classes.py:588:15:588:18 | ControlFlowNode for self |
| classes.py:593:5:593:16 | SSA variable with_delitem | classes.py:595:9:595:20 | ControlFlowNode for with_delitem |
| classes.py:595:9:595:20 | ControlFlowNode for with_delitem | classes.py:586:21:586:24 | ControlFlowNode for self |
| classes.py:657:17:657:20 | ControlFlowNode for self | classes.py:659:15:659:18 | ControlFlowNode for self |
| classes.py:665:5:665:12 | SSA variable with_add | classes.py:667:5:667:12 | ControlFlowNode for with_add |
| classes.py:667:5:667:12 | ControlFlowNode for with_add | classes.py:657:17:657:20 | ControlFlowNode for self |
| classes.py:672:17:672:20 | ControlFlowNode for self | classes.py:674:15:674:18 | ControlFlowNode for self |
| classes.py:680:5:680:12 | SSA variable with_sub | classes.py:682:5:682:12 | ControlFlowNode for with_sub |
| classes.py:682:5:682:12 | ControlFlowNode for with_sub | classes.py:672:17:672:20 | ControlFlowNode for self |
| classes.py:687:17:687:20 | ControlFlowNode for self | classes.py:689:15:689:18 | ControlFlowNode for self |
| classes.py:695:5:695:12 | SSA variable with_mul | classes.py:697:5:697:12 | ControlFlowNode for with_mul |
| classes.py:697:5:697:12 | ControlFlowNode for with_mul | classes.py:687:17:687:20 | ControlFlowNode for self |
| classes.py:702:20:702:23 | ControlFlowNode for self | classes.py:704:15:704:18 | ControlFlowNode for self |
| classes.py:710:5:710:15 | SSA variable with_matmul | classes.py:712:5:712:15 | ControlFlowNode for with_matmul |
| classes.py:712:5:712:15 | ControlFlowNode for with_matmul | classes.py:702:20:702:23 | ControlFlowNode for self |
| classes.py:717:21:717:24 | ControlFlowNode for self | classes.py:719:15:719:18 | ControlFlowNode for self |
| classes.py:725:5:725:16 | SSA variable with_truediv | classes.py:727:5:727:16 | ControlFlowNode for with_truediv |
| classes.py:727:5:727:16 | ControlFlowNode for with_truediv | classes.py:717:21:717:24 | ControlFlowNode for self |
| classes.py:732:22:732:25 | ControlFlowNode for self | classes.py:734:15:734:18 | ControlFlowNode for self |
| classes.py:740:5:740:17 | SSA variable with_floordiv | classes.py:742:5:742:17 | ControlFlowNode for with_floordiv |
| classes.py:742:5:742:17 | ControlFlowNode for with_floordiv | classes.py:732:22:732:25 | ControlFlowNode for self |
| classes.py:747:17:747:20 | ControlFlowNode for self | classes.py:749:15:749:18 | ControlFlowNode for self |
| classes.py:755:5:755:12 | SSA variable with_mod | classes.py:757:5:757:12 | ControlFlowNode for with_mod |
| classes.py:757:5:757:12 | ControlFlowNode for with_mod | classes.py:747:17:747:20 | ControlFlowNode for self |
| classes.py:777:17:777:20 | ControlFlowNode for self | classes.py:779:15:779:18 | ControlFlowNode for self |
| classes.py:791:5:791:12 | SSA variable with_pow | classes.py:793:5:793:12 | ControlFlowNode for with_pow |
| classes.py:793:5:793:12 | ControlFlowNode for with_pow | classes.py:777:17:777:20 | ControlFlowNode for self |
| classes.py:798:20:798:23 | ControlFlowNode for self | classes.py:800:15:800:18 | ControlFlowNode for self |
| classes.py:806:5:806:15 | SSA variable with_lshift | classes.py:808:5:808:15 | ControlFlowNode for with_lshift |
| classes.py:808:5:808:15 | ControlFlowNode for with_lshift | classes.py:798:20:798:23 | ControlFlowNode for self |
| classes.py:813:20:813:23 | ControlFlowNode for self | classes.py:815:15:815:18 | ControlFlowNode for self |
| classes.py:821:5:821:15 | SSA variable with_rshift | classes.py:823:5:823:15 | ControlFlowNode for with_rshift |
| classes.py:823:5:823:15 | ControlFlowNode for with_rshift | classes.py:813:20:813:23 | ControlFlowNode for self |
| classes.py:828:17:828:20 | ControlFlowNode for self | classes.py:830:15:830:18 | ControlFlowNode for self |
| classes.py:836:5:836:12 | SSA variable with_and | classes.py:838:5:838:12 | ControlFlowNode for with_and |
| classes.py:838:5:838:12 | ControlFlowNode for with_and | classes.py:828:17:828:20 | ControlFlowNode for self |
| classes.py:843:17:843:20 | ControlFlowNode for self | classes.py:845:15:845:18 | ControlFlowNode for self |
| classes.py:851:5:851:12 | SSA variable with_xor | classes.py:853:5:853:12 | ControlFlowNode for with_xor |
| classes.py:853:5:853:12 | ControlFlowNode for with_xor | classes.py:843:17:843:20 | ControlFlowNode for self |
| classes.py:858:16:858:19 | ControlFlowNode for self | classes.py:860:15:860:18 | ControlFlowNode for self |
| classes.py:866:5:866:11 | SSA variable with_or | classes.py:868:5:868:11 | ControlFlowNode for with_or |
| classes.py:868:5:868:11 | ControlFlowNode for with_or | classes.py:858:16:858:19 | ControlFlowNode for self |
nodes
| argumentPassing.py:65:5:65:5 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:75:11:75:11 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:89:22:89:25 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:94:22:94:25 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:97:19:97:19 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:98:11:98:11 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:104:19:104:22 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:105:19:105:22 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:106:19:106:22 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:109:27:109:27 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:110:11:110:11 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:117:45:117:48 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:120:5:120:70 | KwUnpacked a | semmle.label | KwUnpacked a |
| argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | semmle.label | ControlFlowNode for Dict [Dictionary element at key a] |
| argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:124:11:124:11 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| argumentPassing.py:139:11:139:13 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:165:18:165:18 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:166:15:166:15 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:172:23:172:23 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:173:15:173:15 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:175:19:175:22 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:179:20:179:20 | ControlFlowNode for a [Tuple element at index 0] | semmle.label | ControlFlowNode for a [Tuple element at index 0] |
| argumentPassing.py:181:19:181:19 | ControlFlowNode for a [Tuple element at index 0] | semmle.label | ControlFlowNode for a [Tuple element at index 0] |
| argumentPassing.py:181:19:181:22 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| argumentPassing.py:183:5:183:19 | PosOverflowNode for with_star() [Tuple element at index 0] | semmle.label | PosOverflowNode for with_star() [Tuple element at index 0] |
| argumentPassing.py:183:15:183:18 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:187:17:187:17 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:188:15:188:15 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:190:13:190:16 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:194:18:194:18 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:195:15:195:15 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:197:16:197:19 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:201:17:201:17 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:202:15:202:15 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| argumentPassing.py:204:15:204:18 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| argumentPassing.py:208:27:208:27 | ControlFlowNode for a [Dictionary element at key a] | semmle.label | ControlFlowNode for a [Dictionary element at key a] |
| argumentPassing.py:209:15:209:15 | ControlFlowNode for a [Dictionary element at key a] | semmle.label | ControlFlowNode for a [Dictionary element at key a] |
| argumentPassing.py:209:15:209:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| argumentPassing.py:211:5:211:27 | KwOverflowNode for with_doublestar() [Dictionary element at key a] | semmle.label | KwOverflowNode for with_doublestar() [Dictionary element at key a] |
| argumentPassing.py:211:23:211:26 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 |
| classes.py:555:21:555:24 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:557:15:557:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:563:5:563:16 | SSA variable with_getitem | semmle.label | SSA variable with_getitem |
| classes.py:565:5:565:16 | ControlFlowNode for with_getitem | semmle.label | ControlFlowNode for with_getitem |
| classes.py:570:21:570:24 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:573:15:573:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:578:5:578:16 | SSA variable with_setitem | semmle.label | SSA variable with_setitem |
| classes.py:581:5:581:16 | ControlFlowNode for with_setitem | semmle.label | ControlFlowNode for with_setitem |
| classes.py:586:21:586:24 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:588:15:588:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:593:5:593:16 | SSA variable with_delitem | semmle.label | SSA variable with_delitem |
| classes.py:595:9:595:20 | ControlFlowNode for with_delitem | semmle.label | ControlFlowNode for with_delitem |
| classes.py:657:17:657:20 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:659:15:659:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:665:5:665:12 | SSA variable with_add | semmle.label | SSA variable with_add |
| classes.py:667:5:667:12 | ControlFlowNode for with_add | semmle.label | ControlFlowNode for with_add |
| classes.py:672:17:672:20 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:674:15:674:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:680:5:680:12 | SSA variable with_sub | semmle.label | SSA variable with_sub |
| classes.py:682:5:682:12 | ControlFlowNode for with_sub | semmle.label | ControlFlowNode for with_sub |
| classes.py:687:17:687:20 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:689:15:689:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:695:5:695:12 | SSA variable with_mul | semmle.label | SSA variable with_mul |
| classes.py:697:5:697:12 | ControlFlowNode for with_mul | semmle.label | ControlFlowNode for with_mul |
| classes.py:702:20:702:23 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:704:15:704:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:710:5:710:15 | SSA variable with_matmul | semmle.label | SSA variable with_matmul |
| classes.py:712:5:712:15 | ControlFlowNode for with_matmul | semmle.label | ControlFlowNode for with_matmul |
| classes.py:717:21:717:24 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:719:15:719:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:725:5:725:16 | SSA variable with_truediv | semmle.label | SSA variable with_truediv |
| classes.py:727:5:727:16 | ControlFlowNode for with_truediv | semmle.label | ControlFlowNode for with_truediv |
| classes.py:732:22:732:25 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:734:15:734:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:740:5:740:17 | SSA variable with_floordiv | semmle.label | SSA variable with_floordiv |
| classes.py:742:5:742:17 | ControlFlowNode for with_floordiv | semmle.label | ControlFlowNode for with_floordiv |
| classes.py:747:17:747:20 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:749:15:749:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:755:5:755:12 | SSA variable with_mod | semmle.label | SSA variable with_mod |
| classes.py:757:5:757:12 | ControlFlowNode for with_mod | semmle.label | ControlFlowNode for with_mod |
| classes.py:777:17:777:20 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:779:15:779:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:791:5:791:12 | SSA variable with_pow | semmle.label | SSA variable with_pow |
| classes.py:793:5:793:12 | ControlFlowNode for with_pow | semmle.label | ControlFlowNode for with_pow |
| classes.py:798:20:798:23 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:800:15:800:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:806:5:806:15 | SSA variable with_lshift | semmle.label | SSA variable with_lshift |
| classes.py:808:5:808:15 | ControlFlowNode for with_lshift | semmle.label | ControlFlowNode for with_lshift |
| classes.py:813:20:813:23 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:815:15:815:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:821:5:821:15 | SSA variable with_rshift | semmle.label | SSA variable with_rshift |
| classes.py:823:5:823:15 | ControlFlowNode for with_rshift | semmle.label | ControlFlowNode for with_rshift |
| classes.py:828:17:828:20 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:830:15:830:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:836:5:836:12 | SSA variable with_and | semmle.label | SSA variable with_and |
| classes.py:838:5:838:12 | ControlFlowNode for with_and | semmle.label | ControlFlowNode for with_and |
| classes.py:843:17:843:20 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:845:15:845:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:851:5:851:12 | SSA variable with_xor | semmle.label | SSA variable with_xor |
| classes.py:853:5:853:12 | ControlFlowNode for with_xor | semmle.label | ControlFlowNode for with_xor |
| classes.py:858:16:858:19 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:860:15:860:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self |
| classes.py:866:5:866:11 | SSA variable with_or | semmle.label | SSA variable with_or |
| classes.py:868:5:868:11 | ControlFlowNode for with_or | semmle.label | ControlFlowNode for with_or |
subpaths
#select
| argumentPassing.py:89:22:89:25 | ControlFlowNode for arg1 | argumentPassing.py:89:22:89:25 | ControlFlowNode for arg1 | argumentPassing.py:75:11:75:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:94:22:94:25 | ControlFlowNode for arg1 | argumentPassing.py:94:22:94:25 | ControlFlowNode for arg1 | argumentPassing.py:75:11:75:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:104:19:104:22 | ControlFlowNode for arg1 | argumentPassing.py:104:19:104:22 | ControlFlowNode for arg1 | argumentPassing.py:98:11:98:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:105:19:105:22 | ControlFlowNode for arg1 | argumentPassing.py:105:19:105:22 | ControlFlowNode for arg1 | argumentPassing.py:98:11:98:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:106:19:106:22 | ControlFlowNode for arg1 | argumentPassing.py:106:19:106:22 | ControlFlowNode for arg1 | argumentPassing.py:98:11:98:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:117:45:117:48 | ControlFlowNode for arg1 | argumentPassing.py:117:45:117:48 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | Flow found |
| argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:139:11:139:13 | ControlFlowNode for foo | Flow found |
| argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | argumentPassing.py:166:15:166:15 | ControlFlowNode for a | Flow found |
| argumentPassing.py:175:19:175:22 | ControlFlowNode for arg1 | argumentPassing.py:175:19:175:22 | ControlFlowNode for arg1 | argumentPassing.py:173:15:173:15 | ControlFlowNode for a | Flow found |
| argumentPassing.py:183:15:183:18 | ControlFlowNode for arg1 | argumentPassing.py:183:15:183:18 | ControlFlowNode for arg1 | argumentPassing.py:181:19:181:22 | ControlFlowNode for Subscript | Flow found |
| argumentPassing.py:190:13:190:16 | ControlFlowNode for arg1 | argumentPassing.py:190:13:190:16 | ControlFlowNode for arg1 | argumentPassing.py:188:15:188:15 | ControlFlowNode for a | Flow found |
| argumentPassing.py:197:16:197:19 | ControlFlowNode for arg1 | argumentPassing.py:197:16:197:19 | ControlFlowNode for arg1 | argumentPassing.py:195:15:195:15 | ControlFlowNode for a | Flow found |
| argumentPassing.py:204:15:204:18 | ControlFlowNode for arg1 | argumentPassing.py:204:15:204:18 | ControlFlowNode for arg1 | argumentPassing.py:202:15:202:15 | ControlFlowNode for a | Flow found |
| argumentPassing.py:211:23:211:26 | ControlFlowNode for arg1 | argumentPassing.py:211:23:211:26 | ControlFlowNode for arg1 | argumentPassing.py:209:15:209:20 | ControlFlowNode for Subscript | Flow found |
| classes.py:563:5:563:16 | SSA variable with_getitem | classes.py:563:5:563:16 | SSA variable with_getitem | classes.py:557:15:557:18 | ControlFlowNode for self | Flow found |
| classes.py:578:5:578:16 | SSA variable with_setitem | classes.py:578:5:578:16 | SSA variable with_setitem | classes.py:573:15:573:18 | ControlFlowNode for self | Flow found |
| classes.py:593:5:593:16 | SSA variable with_delitem | classes.py:593:5:593:16 | SSA variable with_delitem | classes.py:588:15:588:18 | ControlFlowNode for self | Flow found |
| classes.py:665:5:665:12 | SSA variable with_add | classes.py:665:5:665:12 | SSA variable with_add | classes.py:659:15:659:18 | ControlFlowNode for self | Flow found |
| classes.py:680:5:680:12 | SSA variable with_sub | classes.py:680:5:680:12 | SSA variable with_sub | classes.py:674:15:674:18 | ControlFlowNode for self | Flow found |
| classes.py:695:5:695:12 | SSA variable with_mul | classes.py:695:5:695:12 | SSA variable with_mul | classes.py:689:15:689:18 | ControlFlowNode for self | Flow found |
| classes.py:710:5:710:15 | SSA variable with_matmul | classes.py:710:5:710:15 | SSA variable with_matmul | classes.py:704:15:704:18 | ControlFlowNode for self | Flow found |
| classes.py:725:5:725:16 | SSA variable with_truediv | classes.py:725:5:725:16 | SSA variable with_truediv | classes.py:719:15:719:18 | ControlFlowNode for self | Flow found |
| classes.py:740:5:740:17 | SSA variable with_floordiv | classes.py:740:5:740:17 | SSA variable with_floordiv | classes.py:734:15:734:18 | ControlFlowNode for self | Flow found |
| classes.py:755:5:755:12 | SSA variable with_mod | classes.py:755:5:755:12 | SSA variable with_mod | classes.py:749:15:749:18 | ControlFlowNode for self | Flow found |
| classes.py:791:5:791:12 | SSA variable with_pow | classes.py:791:5:791:12 | SSA variable with_pow | classes.py:779:15:779:18 | ControlFlowNode for self | Flow found |
| classes.py:806:5:806:15 | SSA variable with_lshift | classes.py:806:5:806:15 | SSA variable with_lshift | classes.py:800:15:800:18 | ControlFlowNode for self | Flow found |
| classes.py:821:5:821:15 | SSA variable with_rshift | classes.py:821:5:821:15 | SSA variable with_rshift | classes.py:815:15:815:18 | ControlFlowNode for self | Flow found |
| classes.py:836:5:836:12 | SSA variable with_and | classes.py:836:5:836:12 | SSA variable with_and | classes.py:830:15:830:18 | ControlFlowNode for self | Flow found |
| classes.py:851:5:851:12 | SSA variable with_xor | classes.py:851:5:851:12 | SSA variable with_xor | classes.py:845:15:845:18 | ControlFlowNode for self | Flow found |
| classes.py:866:5:866:11 | SSA variable with_or | classes.py:866:5:866:11 | SSA variable with_or | classes.py:860:15:860:18 | ControlFlowNode for self | Flow found |

View File

@@ -1,48 +0,0 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import DataFlow::PathGraph
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
/**
* A configuration to check routing of arguments through magic methods.
*/
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg1"
or
exists(AssignmentDefinition def, DataFlowPrivate::DataFlowCall call |
def.getVariable() = node.(DataFlow::EssaNode).getVar() and
def.getValue() = call.getNode() and
call.getNode().(CallNode).getFunction().(NameNode).getId().matches("With\\_%")
) and
node.(DataFlow::EssaNode).getVar().getName().matches("with\\_%")
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK1" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
source.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
sink.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
exists(ArgumentRoutingConfig cfg | cfg.hasFlowPath(source, sink))
select source.getNode(), source, sink, "Flow found"

View File

@@ -1,153 +0,0 @@
edges
| argumentPassing.py:66:5:66:5 | ControlFlowNode for b | argumentPassing.py:76:11:76:11 | ControlFlowNode for b |
| argumentPassing.py:94:28:94:31 | ControlFlowNode for arg2 | argumentPassing.py:66:5:66:5 | ControlFlowNode for b |
| argumentPassing.py:97:25:97:25 | ControlFlowNode for b | argumentPassing.py:99:11:99:11 | ControlFlowNode for b |
| argumentPassing.py:104:25:104:28 | ControlFlowNode for arg2 | argumentPassing.py:97:25:97:25 | ControlFlowNode for b |
| argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | argumentPassing.py:97:25:97:25 | ControlFlowNode for b |
| argumentPassing.py:109:30:109:30 | ControlFlowNode for b | argumentPassing.py:111:11:111:11 | ControlFlowNode for b |
| argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | argumentPassing.py:109:30:109:30 | ControlFlowNode for b |
| argumentPassing.py:120:5:120:70 | KwUnpacked b | argumentPassing.py:109:30:109:30 | ControlFlowNode for b |
| argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | argumentPassing.py:120:5:120:70 | KwUnpacked b |
| argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] |
| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | argumentPassing.py:125:11:125:11 | ControlFlowNode for b |
| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | argumentPassing.py:125:11:125:11 | ControlFlowNode for b |
| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:123:36:123:36 | ControlFlowNode for b |
| argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:123:36:123:36 | ControlFlowNode for b |
| argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key bar] | argumentPassing.py:140:20:140:25 | ControlFlowNode for kwargs [Dictionary element at key bar] |
| argumentPassing.py:140:5:140:26 | KwUnpacked bar | argumentPassing.py:145:18:145:20 | ControlFlowNode for bar |
| argumentPassing.py:140:20:140:25 | ControlFlowNode for kwargs [Dictionary element at key bar] | argumentPassing.py:140:5:140:26 | KwUnpacked bar |
| argumentPassing.py:145:18:145:20 | ControlFlowNode for bar | argumentPassing.py:146:11:146:13 | ControlFlowNode for bar |
| argumentPassing.py:160:5:160:50 | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key bar] | argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key bar] |
| argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | argumentPassing.py:160:5:160:50 | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key bar] |
| classes.py:555:27:555:29 | ControlFlowNode for key | classes.py:556:15:556:17 | ControlFlowNode for key |
| classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:555:27:555:29 | ControlFlowNode for key |
| classes.py:570:27:570:29 | ControlFlowNode for key | classes.py:572:15:572:17 | ControlFlowNode for key |
| classes.py:581:18:581:21 | ControlFlowNode for arg2 | classes.py:570:27:570:29 | ControlFlowNode for key |
| classes.py:586:27:586:29 | ControlFlowNode for key | classes.py:587:15:587:17 | ControlFlowNode for key |
| classes.py:595:22:595:25 | ControlFlowNode for arg2 | classes.py:586:27:586:29 | ControlFlowNode for key |
| classes.py:657:23:657:27 | ControlFlowNode for other | classes.py:658:15:658:19 | ControlFlowNode for other |
| classes.py:667:16:667:19 | ControlFlowNode for arg2 | classes.py:657:23:657:27 | ControlFlowNode for other |
| classes.py:672:23:672:27 | ControlFlowNode for other | classes.py:673:15:673:19 | ControlFlowNode for other |
| classes.py:682:16:682:19 | ControlFlowNode for arg2 | classes.py:672:23:672:27 | ControlFlowNode for other |
| classes.py:687:23:687:27 | ControlFlowNode for other | classes.py:688:15:688:19 | ControlFlowNode for other |
| classes.py:697:16:697:19 | ControlFlowNode for arg2 | classes.py:687:23:687:27 | ControlFlowNode for other |
| classes.py:702:26:702:30 | ControlFlowNode for other | classes.py:703:15:703:19 | ControlFlowNode for other |
| classes.py:712:19:712:22 | ControlFlowNode for arg2 | classes.py:702:26:702:30 | ControlFlowNode for other |
| classes.py:717:27:717:31 | ControlFlowNode for other | classes.py:718:15:718:19 | ControlFlowNode for other |
| classes.py:727:20:727:23 | ControlFlowNode for arg2 | classes.py:717:27:717:31 | ControlFlowNode for other |
| classes.py:732:28:732:32 | ControlFlowNode for other | classes.py:733:15:733:19 | ControlFlowNode for other |
| classes.py:742:22:742:25 | ControlFlowNode for arg2 | classes.py:732:28:732:32 | ControlFlowNode for other |
| classes.py:747:23:747:27 | ControlFlowNode for other | classes.py:748:15:748:19 | ControlFlowNode for other |
| classes.py:757:16:757:19 | ControlFlowNode for arg2 | classes.py:747:23:747:27 | ControlFlowNode for other |
| classes.py:777:23:777:27 | ControlFlowNode for other | classes.py:778:15:778:19 | ControlFlowNode for other |
| classes.py:793:17:793:20 | ControlFlowNode for arg2 | classes.py:777:23:777:27 | ControlFlowNode for other |
| classes.py:798:26:798:30 | ControlFlowNode for other | classes.py:799:15:799:19 | ControlFlowNode for other |
| classes.py:808:20:808:23 | ControlFlowNode for arg2 | classes.py:798:26:798:30 | ControlFlowNode for other |
| classes.py:813:26:813:30 | ControlFlowNode for other | classes.py:814:15:814:19 | ControlFlowNode for other |
| classes.py:823:20:823:23 | ControlFlowNode for arg2 | classes.py:813:26:813:30 | ControlFlowNode for other |
| classes.py:828:23:828:27 | ControlFlowNode for other | classes.py:829:15:829:19 | ControlFlowNode for other |
| classes.py:838:16:838:19 | ControlFlowNode for arg2 | classes.py:828:23:828:27 | ControlFlowNode for other |
| classes.py:843:23:843:27 | ControlFlowNode for other | classes.py:844:15:844:19 | ControlFlowNode for other |
| classes.py:853:16:853:19 | ControlFlowNode for arg2 | classes.py:843:23:843:27 | ControlFlowNode for other |
| classes.py:858:22:858:26 | ControlFlowNode for other | classes.py:859:15:859:19 | ControlFlowNode for other |
| classes.py:868:15:868:18 | ControlFlowNode for arg2 | classes.py:858:22:858:26 | ControlFlowNode for other |
nodes
| argumentPassing.py:66:5:66:5 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:76:11:76:11 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:94:28:94:31 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| argumentPassing.py:97:25:97:25 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:99:11:99:11 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:104:25:104:28 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| argumentPassing.py:109:30:109:30 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:111:11:111:11 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| argumentPassing.py:120:5:120:70 | KwUnpacked b | semmle.label | KwUnpacked b |
| argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] |
| argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| argumentPassing.py:125:11:125:11 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key bar] | semmle.label | ControlFlowNode for kwargs [Dictionary element at key bar] |
| argumentPassing.py:140:5:140:26 | KwUnpacked bar | semmle.label | KwUnpacked bar |
| argumentPassing.py:140:20:140:25 | ControlFlowNode for kwargs [Dictionary element at key bar] | semmle.label | ControlFlowNode for kwargs [Dictionary element at key bar] |
| argumentPassing.py:145:18:145:20 | ControlFlowNode for bar | semmle.label | ControlFlowNode for bar |
| argumentPassing.py:146:11:146:13 | ControlFlowNode for bar | semmle.label | ControlFlowNode for bar |
| argumentPassing.py:160:5:160:50 | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key bar] | semmle.label | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key bar] |
| argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:555:27:555:29 | ControlFlowNode for key | semmle.label | ControlFlowNode for key |
| classes.py:556:15:556:17 | ControlFlowNode for key | semmle.label | ControlFlowNode for key |
| classes.py:565:18:565:21 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:570:27:570:29 | ControlFlowNode for key | semmle.label | ControlFlowNode for key |
| classes.py:572:15:572:17 | ControlFlowNode for key | semmle.label | ControlFlowNode for key |
| classes.py:581:18:581:21 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:586:27:586:29 | ControlFlowNode for key | semmle.label | ControlFlowNode for key |
| classes.py:587:15:587:17 | ControlFlowNode for key | semmle.label | ControlFlowNode for key |
| classes.py:595:22:595:25 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:657:23:657:27 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:658:15:658:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:667:16:667:19 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:672:23:672:27 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:673:15:673:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:682:16:682:19 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:687:23:687:27 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:688:15:688:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:697:16:697:19 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:702:26:702:30 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:703:15:703:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:712:19:712:22 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:717:27:717:31 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:718:15:718:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:727:20:727:23 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:732:28:732:32 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:733:15:733:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:742:22:742:25 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:747:23:747:27 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:748:15:748:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:757:16:757:19 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:777:23:777:27 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:778:15:778:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:793:17:793:20 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:798:26:798:30 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:799:15:799:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:808:20:808:23 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:813:26:813:30 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:814:15:814:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:823:20:823:23 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:828:23:828:27 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:829:15:829:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:838:16:838:19 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:843:23:843:27 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:844:15:844:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:853:16:853:19 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
| classes.py:858:22:858:26 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:859:15:859:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other |
| classes.py:868:15:868:18 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 |
subpaths
#select
| argumentPassing.py:94:28:94:31 | ControlFlowNode for arg2 | argumentPassing.py:94:28:94:31 | ControlFlowNode for arg2 | argumentPassing.py:76:11:76:11 | ControlFlowNode for b | Flow found |
| argumentPassing.py:104:25:104:28 | ControlFlowNode for arg2 | argumentPassing.py:104:25:104:28 | ControlFlowNode for arg2 | argumentPassing.py:99:11:99:11 | ControlFlowNode for b | Flow found |
| argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | argumentPassing.py:99:11:99:11 | ControlFlowNode for b | Flow found |
| argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | argumentPassing.py:111:11:111:11 | ControlFlowNode for b | Flow found |
| argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:111:11:111:11 | ControlFlowNode for b | Flow found |
| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | Flow found |
| argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | Flow found |
| argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | argumentPassing.py:146:11:146:13 | ControlFlowNode for bar | Flow found |
| classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:556:15:556:17 | ControlFlowNode for key | Flow found |
| classes.py:581:18:581:21 | ControlFlowNode for arg2 | classes.py:581:18:581:21 | ControlFlowNode for arg2 | classes.py:572:15:572:17 | ControlFlowNode for key | Flow found |
| classes.py:595:22:595:25 | ControlFlowNode for arg2 | classes.py:595:22:595:25 | ControlFlowNode for arg2 | classes.py:587:15:587:17 | ControlFlowNode for key | Flow found |
| classes.py:667:16:667:19 | ControlFlowNode for arg2 | classes.py:667:16:667:19 | ControlFlowNode for arg2 | classes.py:658:15:658:19 | ControlFlowNode for other | Flow found |
| classes.py:682:16:682:19 | ControlFlowNode for arg2 | classes.py:682:16:682:19 | ControlFlowNode for arg2 | classes.py:673:15:673:19 | ControlFlowNode for other | Flow found |
| classes.py:697:16:697:19 | ControlFlowNode for arg2 | classes.py:697:16:697:19 | ControlFlowNode for arg2 | classes.py:688:15:688:19 | ControlFlowNode for other | Flow found |
| classes.py:712:19:712:22 | ControlFlowNode for arg2 | classes.py:712:19:712:22 | ControlFlowNode for arg2 | classes.py:703:15:703:19 | ControlFlowNode for other | Flow found |
| classes.py:727:20:727:23 | ControlFlowNode for arg2 | classes.py:727:20:727:23 | ControlFlowNode for arg2 | classes.py:718:15:718:19 | ControlFlowNode for other | Flow found |
| classes.py:742:22:742:25 | ControlFlowNode for arg2 | classes.py:742:22:742:25 | ControlFlowNode for arg2 | classes.py:733:15:733:19 | ControlFlowNode for other | Flow found |
| classes.py:757:16:757:19 | ControlFlowNode for arg2 | classes.py:757:16:757:19 | ControlFlowNode for arg2 | classes.py:748:15:748:19 | ControlFlowNode for other | Flow found |
| classes.py:793:17:793:20 | ControlFlowNode for arg2 | classes.py:793:17:793:20 | ControlFlowNode for arg2 | classes.py:778:15:778:19 | ControlFlowNode for other | Flow found |
| classes.py:808:20:808:23 | ControlFlowNode for arg2 | classes.py:808:20:808:23 | ControlFlowNode for arg2 | classes.py:799:15:799:19 | ControlFlowNode for other | Flow found |
| classes.py:823:20:823:23 | ControlFlowNode for arg2 | classes.py:823:20:823:23 | ControlFlowNode for arg2 | classes.py:814:15:814:19 | ControlFlowNode for other | Flow found |
| classes.py:838:16:838:19 | ControlFlowNode for arg2 | classes.py:838:16:838:19 | ControlFlowNode for arg2 | classes.py:829:15:829:19 | ControlFlowNode for other | Flow found |
| classes.py:853:16:853:19 | ControlFlowNode for arg2 | classes.py:853:16:853:19 | ControlFlowNode for arg2 | classes.py:844:15:844:19 | ControlFlowNode for other | Flow found |
| classes.py:868:15:868:18 | ControlFlowNode for arg2 | classes.py:868:15:868:18 | ControlFlowNode for arg2 | classes.py:859:15:859:19 | ControlFlowNode for other | Flow found |

View File

@@ -1,40 +0,0 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import DataFlow::PathGraph
/**
* A configuration to check routing of arguments through magic methods.
*/
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg2"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK2" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
source.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
sink.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
exists(ArgumentRoutingConfig cfg | cfg.hasFlowPath(source, sink))
select source.getNode(), source, sink, "Flow found"

View File

@@ -1,69 +0,0 @@
edges
| argumentPassing.py:68:5:68:5 | ControlFlowNode for c | argumentPassing.py:77:11:77:11 | ControlFlowNode for c |
| argumentPassing.py:94:34:94:37 | ControlFlowNode for arg3 | argumentPassing.py:68:5:68:5 | ControlFlowNode for c |
| argumentPassing.py:109:33:109:33 | ControlFlowNode for c | argumentPassing.py:112:11:112:11 | ControlFlowNode for c |
| argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | argumentPassing.py:109:33:109:33 | ControlFlowNode for c |
| argumentPassing.py:119:5:119:54 | KwUnpacked c | argumentPassing.py:109:33:109:33 | ControlFlowNode for c |
| argumentPassing.py:119:35:119:45 | ControlFlowNode for Dict [Dictionary element at key c] | argumentPassing.py:119:5:119:54 | KwUnpacked c |
| argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:119:35:119:45 | ControlFlowNode for Dict [Dictionary element at key c] |
| argumentPassing.py:120:5:120:70 | KwUnpacked c | argumentPassing.py:109:33:109:33 | ControlFlowNode for c |
| argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | argumentPassing.py:120:5:120:70 | KwUnpacked c |
| argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] |
| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | argumentPassing.py:126:11:126:11 | ControlFlowNode for c |
| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | argumentPassing.py:126:11:126:11 | ControlFlowNode for c |
| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:123:44:123:44 | ControlFlowNode for c |
| argumentPassing.py:134:5:134:41 | KwUnpacked c | argumentPassing.py:123:44:123:44 | ControlFlowNode for c |
| argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | argumentPassing.py:134:5:134:41 | KwUnpacked c |
| argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] |
| argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key baz] | argumentPassing.py:140:5:140:26 | KwOverflowNode for grab_bar_baz() [Dictionary element at key baz] |
| argumentPassing.py:140:5:140:26 | KwOverflowNode for grab_bar_baz() [Dictionary element at key baz] | argumentPassing.py:145:25:145:30 | ControlFlowNode for kwargs [Dictionary element at key baz] |
| argumentPassing.py:145:25:145:30 | ControlFlowNode for kwargs [Dictionary element at key baz] | argumentPassing.py:151:16:151:21 | ControlFlowNode for kwargs [Dictionary element at key baz] |
| argumentPassing.py:151:5:151:22 | KwUnpacked baz | argumentPassing.py:154:14:154:16 | ControlFlowNode for baz |
| argumentPassing.py:151:16:151:21 | ControlFlowNode for kwargs [Dictionary element at key baz] | argumentPassing.py:151:5:151:22 | KwUnpacked baz |
| argumentPassing.py:154:14:154:16 | ControlFlowNode for baz | argumentPassing.py:155:11:155:13 | ControlFlowNode for baz |
| argumentPassing.py:160:5:160:50 | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key baz] | argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key baz] |
| argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:160:5:160:50 | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key baz] |
| classes.py:570:32:570:36 | ControlFlowNode for value | classes.py:571:15:571:19 | ControlFlowNode for value |
| classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:570:32:570:36 | ControlFlowNode for value |
nodes
| argumentPassing.py:68:5:68:5 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
| argumentPassing.py:77:11:77:11 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
| argumentPassing.py:94:34:94:37 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
| argumentPassing.py:109:33:109:33 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
| argumentPassing.py:112:11:112:11 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
| argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
| argumentPassing.py:119:5:119:54 | KwUnpacked c | semmle.label | KwUnpacked c |
| argumentPassing.py:119:35:119:45 | ControlFlowNode for Dict [Dictionary element at key c] | semmle.label | ControlFlowNode for Dict [Dictionary element at key c] |
| argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
| argumentPassing.py:120:5:120:70 | KwUnpacked c | semmle.label | KwUnpacked c |
| argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | semmle.label | ControlFlowNode for Dict [Dictionary element at key c] |
| argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
| argumentPassing.py:126:11:126:11 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
| argumentPassing.py:134:5:134:41 | KwUnpacked c | semmle.label | KwUnpacked c |
| argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | semmle.label | ControlFlowNode for Dict [Dictionary element at key c] |
| argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
| argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key baz] | semmle.label | ControlFlowNode for kwargs [Dictionary element at key baz] |
| argumentPassing.py:140:5:140:26 | KwOverflowNode for grab_bar_baz() [Dictionary element at key baz] | semmle.label | KwOverflowNode for grab_bar_baz() [Dictionary element at key baz] |
| argumentPassing.py:145:25:145:30 | ControlFlowNode for kwargs [Dictionary element at key baz] | semmle.label | ControlFlowNode for kwargs [Dictionary element at key baz] |
| argumentPassing.py:151:5:151:22 | KwUnpacked baz | semmle.label | KwUnpacked baz |
| argumentPassing.py:151:16:151:21 | ControlFlowNode for kwargs [Dictionary element at key baz] | semmle.label | ControlFlowNode for kwargs [Dictionary element at key baz] |
| argumentPassing.py:154:14:154:16 | ControlFlowNode for baz | semmle.label | ControlFlowNode for baz |
| argumentPassing.py:155:11:155:13 | ControlFlowNode for baz | semmle.label | ControlFlowNode for baz |
| argumentPassing.py:160:5:160:50 | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key baz] | semmle.label | KwOverflowNode for grab_foo_bar_baz() [Dictionary element at key baz] |
| argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
| classes.py:570:32:570:36 | ControlFlowNode for value | semmle.label | ControlFlowNode for value |
| classes.py:571:15:571:19 | ControlFlowNode for value | semmle.label | ControlFlowNode for value |
| classes.py:581:26:581:29 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 |
subpaths
#select
| argumentPassing.py:94:34:94:37 | ControlFlowNode for arg3 | argumentPassing.py:94:34:94:37 | ControlFlowNode for arg3 | argumentPassing.py:77:11:77:11 | ControlFlowNode for c | Flow found |
| argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found |
| argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found |
| argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found |
| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | Flow found |
| argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | Flow found |
| argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:155:11:155:13 | ControlFlowNode for baz | Flow found |
| classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:571:15:571:19 | ControlFlowNode for value | Flow found |

View File

@@ -1,40 +0,0 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import DataFlow::PathGraph
/**
* A configuration to check routing of arguments through magic methods.
*/
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg3"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK3" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
source.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
sink.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
exists(ArgumentRoutingConfig cfg | cfg.hasFlowPath(source, sink))
select source.getNode(), source, sink, "Flow found"

View File

@@ -1,10 +0,0 @@
edges
| argumentPassing.py:69:5:69:5 | ControlFlowNode for d | argumentPassing.py:78:11:78:11 | ControlFlowNode for d |
| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:69:5:69:5 | ControlFlowNode for d |
nodes
| argumentPassing.py:69:5:69:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d |
| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | semmle.label | ControlFlowNode for arg4 |
| argumentPassing.py:78:11:78:11 | ControlFlowNode for d | semmle.label | ControlFlowNode for d |
subpaths
#select
| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:78:11:78:11 | ControlFlowNode for d | Flow found |

View File

@@ -1,40 +0,0 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import DataFlow::PathGraph
/**
* A configuration to check routing of arguments through magic methods.
*/
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg4"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK4" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
source.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
sink.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
exists(ArgumentRoutingConfig cfg | cfg.hasFlowPath(source, sink))
select source.getNode(), source, sink, "Flow found"

View File

@@ -1,10 +0,0 @@
edges
| argumentPassing.py:71:5:71:5 | ControlFlowNode for e | argumentPassing.py:79:11:79:11 | ControlFlowNode for e |
| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:71:5:71:5 | ControlFlowNode for e |
nodes
| argumentPassing.py:71:5:71:5 | ControlFlowNode for e | semmle.label | ControlFlowNode for e |
| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | semmle.label | ControlFlowNode for arg5 |
| argumentPassing.py:79:11:79:11 | ControlFlowNode for e | semmle.label | ControlFlowNode for e |
subpaths
#select
| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:79:11:79:11 | ControlFlowNode for e | Flow found |

View File

@@ -1,40 +0,0 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import DataFlow::PathGraph
/**
* A configuration to check routing of arguments through magic methods.
*/
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg5"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK5" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
source.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
sink.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
exists(ArgumentRoutingConfig cfg | cfg.hasFlowPath(source, sink))
select source.getNode(), source, sink, "Flow found"

View File

@@ -1,4 +0,0 @@
edges
nodes
subpaths
#select

View File

@@ -1,40 +0,0 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import DataFlow::PathGraph
/**
* A configuration to check routing of arguments through magic methods.
*/
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg6"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK6" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
source.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
sink.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
exists(ArgumentRoutingConfig cfg | cfg.hasFlowPath(source, sink))
select source.getNode(), source, sink, "Flow found"

View File

@@ -1,16 +0,0 @@
edges
| argumentPassing.py:73:7:73:7 | ControlFlowNode for g [Dictionary element at key g] | argumentPassing.py:82:15:82:15 | ControlFlowNode for g [Dictionary element at key g] |
| argumentPassing.py:82:15:82:15 | ControlFlowNode for g [Dictionary element at key g] | argumentPassing.py:82:15:82:20 | ControlFlowNode for Subscript |
| argumentPassing.py:89:5:89:81 | KwOverflowNode for argument_passing() [Dictionary element at key g] | argumentPassing.py:73:7:73:7 | ControlFlowNode for g [Dictionary element at key g] |
| argumentPassing.py:89:59:89:80 | ControlFlowNode for Dict [Dictionary element at key g] | argumentPassing.py:89:5:89:81 | KwOverflowNode for argument_passing() [Dictionary element at key g] |
| argumentPassing.py:89:76:89:79 | ControlFlowNode for arg7 | argumentPassing.py:89:59:89:80 | ControlFlowNode for Dict [Dictionary element at key g] |
nodes
| argumentPassing.py:73:7:73:7 | ControlFlowNode for g [Dictionary element at key g] | semmle.label | ControlFlowNode for g [Dictionary element at key g] |
| argumentPassing.py:82:15:82:15 | ControlFlowNode for g [Dictionary element at key g] | semmle.label | ControlFlowNode for g [Dictionary element at key g] |
| argumentPassing.py:82:15:82:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| argumentPassing.py:89:5:89:81 | KwOverflowNode for argument_passing() [Dictionary element at key g] | semmle.label | KwOverflowNode for argument_passing() [Dictionary element at key g] |
| argumentPassing.py:89:59:89:80 | ControlFlowNode for Dict [Dictionary element at key g] | semmle.label | ControlFlowNode for Dict [Dictionary element at key g] |
| argumentPassing.py:89:76:89:79 | ControlFlowNode for arg7 | semmle.label | ControlFlowNode for arg7 |
subpaths
#select
| argumentPassing.py:89:76:89:79 | ControlFlowNode for arg7 | argumentPassing.py:89:76:89:79 | ControlFlowNode for arg7 | argumentPassing.py:82:15:82:20 | ControlFlowNode for Subscript | Flow found |

View File

@@ -1,40 +0,0 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import DataFlow::PathGraph
/**
* A configuration to check routing of arguments through magic methods.
*/
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg7"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK7" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
source.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
sink.getNode().getLocation().getFile().getBaseName() in ["classes.py", "argumentPassing.py"] and
exists(ArgumentRoutingConfig cfg | cfg.hasFlowPath(source, sink))
select source.getNode(), source, sink, "Flow found"

View File

@@ -43,32 +43,51 @@ class Argument1RoutingConfig extends DataFlow::Configuration {
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
override predicate isBarrierIn(DataFlow::Node node) { this.isSource(node) }
}
class Argument2RoutingTest extends RoutingTest {
Argument2RoutingTest() { this = "Argument2RoutingTest" }
// for argument 2 and up, we use a generic approach. Change `maxNumArgs` below if we
// need to increase the maximum number of arguments.
private int maxNumArgs() { result = 7 }
override string flowTag() { result = "arg2" }
class RestArgumentRoutingTest extends RoutingTest {
int argNumber;
RestArgumentRoutingTest() {
argNumber in [2 .. maxNumArgs()] and
this = "Argument" + argNumber + "RoutingTest"
}
override string flowTag() { result = "arg" + argNumber }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(Argument2RoutingConfig cfg | cfg.hasFlow(source, sink))
exists(RestArgumentRoutingConfig cfg | cfg.getArgNumber() = argNumber |
cfg.hasFlow(source, sink)
)
}
}
/**
* A configuration to check routing of arguments through magic methods.
*/
class Argument2RoutingConfig extends DataFlow::Configuration {
Argument2RoutingConfig() { this = "Argument2RoutingConfig" }
class RestArgumentRoutingConfig extends DataFlow::Configuration {
int argNumber;
RestArgumentRoutingConfig() {
argNumber in [2 .. maxNumArgs()] and
this = "Argument" + argNumber + "RoutingConfig"
}
/** Gets the argument number this configuration is for. */
int getArgNumber() { result = argNumber }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg2"
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg" + argNumber
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK2" and
call.getFunction().(NameNode).getId() = "SINK" + argNumber and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
@@ -79,185 +98,5 @@ class Argument2RoutingConfig extends DataFlow::Configuration {
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
class Argument3RoutingTest extends RoutingTest {
Argument3RoutingTest() { this = "Argument3RoutingTest" }
override string flowTag() { result = "arg3" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(Argument3RoutingConfig cfg | cfg.hasFlow(source, sink))
}
}
/**
* A configuration to check routing of arguments through magic methods.
*/
class Argument3RoutingConfig extends DataFlow::Configuration {
Argument3RoutingConfig() { this = "Argument3RoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg3"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK3" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
class Argument4RoutingTest extends RoutingTest {
Argument4RoutingTest() { this = "Argument4RoutingTest" }
override string flowTag() { result = "arg4" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(Argument4RoutingConfig cfg | cfg.hasFlow(source, sink))
}
}
/**
* A configuration to check routing of arguments through magic methods.
*/
class Argument4RoutingConfig extends DataFlow::Configuration {
Argument4RoutingConfig() { this = "Argument4RoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg4"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK4" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
class Argument5RoutingTest extends RoutingTest {
Argument5RoutingTest() { this = "Argument5RoutingTest" }
override string flowTag() { result = "arg5" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(Argument5RoutingConfig cfg | cfg.hasFlow(source, sink))
}
}
/**
* A configuration to check routing of arguments through magic methods.
*/
class Argument5RoutingConfig extends DataFlow::Configuration {
Argument5RoutingConfig() { this = "Argument5RoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg5"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK5" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
class Argument6RoutingTest extends RoutingTest {
Argument6RoutingTest() { this = "Argument6RoutingTest" }
override string flowTag() { result = "arg6" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(Argument6RoutingConfig cfg | cfg.hasFlow(source, sink))
}
}
/**
* A configuration to check routing of arguments through magic methods.
*/
class Argument6RoutingConfig extends DataFlow::Configuration {
Argument6RoutingConfig() { this = "Argument6RoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg6"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK6" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
class Argument7RoutingTest extends RoutingTest {
Argument7RoutingTest() { this = "Argument7RoutingTest" }
override string flowTag() { result = "arg7" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(Argument7RoutingConfig cfg | cfg.hasFlow(source, sink))
}
}
/**
* A configuration to check routing of arguments through magic methods.
*/
class Argument7RoutingConfig extends DataFlow::Configuration {
Argument7RoutingConfig() { this = "Argument7RoutingConfig" }
override predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg7"
}
override predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK7" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
* Use-use flow lets the argument to the first call reach the sink inside the second call,
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
override predicate isBarrierIn(DataFlow::Node node) { this.isSource(node) }
}

View File

@@ -12,7 +12,7 @@ import sys
import os
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
from testlib import *
from testlib import expects
import asyncio

View File

@@ -1,5 +1,8 @@
| classes.py:45:16:45:35 | ControlFlowNode for Attribute() | classes.py:45:16:45:35 | ControlFlowNode for Attribute() |
| classes.py:60:17:60:27 | [pre objCreate] ControlFlowNode for With_init() | classes.py:54:18:54:21 | ControlFlowNode for self |
| classes.py:242:9:242:24 | ControlFlowNode for set() | classes.py:242:9:242:24 | ControlFlowNode for set() |
| classes.py:247:9:247:30 | ControlFlowNode for frozenset() | classes.py:247:9:247:30 | ControlFlowNode for frozenset() |
| classes.py:252:9:252:28 | ControlFlowNode for dict() | classes.py:252:9:252:28 | ControlFlowNode for dict() |
| classes.py:565:5:565:16 | ControlFlowNode for with_getitem | classes.py:555:21:555:24 | ControlFlowNode for self |
| classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:555:27:555:29 | ControlFlowNode for key |
| classes.py:581:5:581:16 | ControlFlowNode for with_setitem | classes.py:570:21:570:24 | ControlFlowNode for self |

View File

@@ -1,13 +0,0 @@
import python
import experimental.dataflow.TestUtil.FlowTest
import experimental.dataflow.testConfig
class DataFlowTest extends FlowTest {
DataFlowTest() { this = "DataFlowTest" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
}
}

View File

@@ -90,11 +90,11 @@ def gen(x, count):
n -= 1
iter = gen(SOURCE, 1)
SINK(iter.__next__())
SINK(iter.__next__()) # $ MISSING: flow
# SINK_F(iter.__next__()) # throws StopIteration, FP
oiter = c.gen(SOURCE, 1)
SINK(oiter.__next__())
SINK(oiter.__next__()) # $ MISSING: flow
# SINK_F(oiter.__next__()) # throws StopIteration, FP
# Coroutine functions
@@ -103,8 +103,8 @@ async def coro(x):
return x
import asyncio
SINK(asyncio.run(coro(SOURCE)))
SINK(asyncio.run(c.coro(SOURCE)))
SINK(asyncio.run(coro(SOURCE))) # $ MISSING: flow
SINK(asyncio.run(c.coro(SOURCE))) # $ MISSING: flow
class A:
@@ -116,7 +116,7 @@ async def agen(x):
a = A()
return await a
SINK(asyncio.run(agen(SOURCE)))
SINK(asyncio.run(agen(SOURCE))) # $ MISSING: flow
# Asynchronous generator functions
# A function or method which is defined using async def and which uses the yield statement is called a asynchronous generator function. Such a function, when called, returns an asynchronous iterator object which can be used in an async for statement to execute the body of the function.

View File

@@ -13,7 +13,7 @@ import sys
import os
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
from testlib import *
from testlib import expects
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"

View File

@@ -0,0 +1,2 @@
missingAnnotationOnSINK
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.NormalDataflowTest

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.UnresolvedCalls

View File

@@ -1,183 +0,0 @@
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:28:1:28:4 | ControlFlowNode for SINK |
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:27:15:27:20 | ControlFlowNode for SOURCE |
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:6:13:6:18 | ControlFlowNode for object |
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:6:7:6:11 | GSSA Variable MyObj |
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:25:9:25:13 | ControlFlowNode for MyObj |
| examples.py:6:13:6:18 | ControlFlowNode for object | examples.py:11:17:11:22 | ControlFlowNode for object |
| examples.py:7:5:7:28 | ControlFlowNode for FunctionExpr | examples.py:7:9:7:16 | SSA variable __init__ |
| examples.py:7:18:7:21 | ControlFlowNode for self | examples.py:7:18:7:21 | SSA variable self |
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:12 | ControlFlowNode for self |
| examples.py:7:24:7:26 | ControlFlowNode for foo | examples.py:7:24:7:26 | SSA variable foo |
| examples.py:7:24:7:26 | SSA variable foo | examples.py:8:20:8:22 | ControlFlowNode for foo |
| examples.py:11:1:11:24 | ControlFlowNode for ClassExpr | examples.py:11:7:11:15 | GSSA Variable NestedObj |
| examples.py:11:7:11:15 | GSSA Variable NestedObj | examples.py:33:5:33:13 | ControlFlowNode for NestedObj |
| examples.py:12:5:12:23 | ControlFlowNode for FunctionExpr | examples.py:12:9:12:16 | SSA variable __init__ |
| examples.py:12:5:12:23 | GSSA Variable MyObj | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
| examples.py:12:18:12:21 | ControlFlowNode for self | examples.py:12:18:12:21 | SSA variable self |
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:12 | ControlFlowNode for self |
| examples.py:15:5:15:21 | ControlFlowNode for FunctionExpr | examples.py:15:9:15:14 | SSA variable getObj |
| examples.py:15:16:15:19 | ControlFlowNode for self | examples.py:15:16:15:19 | SSA variable self |
| examples.py:15:16:15:19 | SSA variable self | examples.py:16:16:16:19 | ControlFlowNode for self |
| examples.py:20:1:20:19 | ControlFlowNode for FunctionExpr | examples.py:20:5:20:10 | GSSA Variable setFoo |
| examples.py:20:1:20:19 | GSSA Variable SINK_F | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
| examples.py:20:5:20:10 | GSSA Variable setFoo | examples.py:27:1:27:6 | ControlFlowNode for setFoo |
| examples.py:20:12:20:14 | ControlFlowNode for obj | examples.py:20:12:20:14 | SSA variable obj |
| examples.py:20:12:20:14 | SSA variable obj | examples.py:21:12:21:14 | ControlFlowNode for obj |
| examples.py:20:17:20:17 | ControlFlowNode for x | examples.py:20:17:20:17 | SSA variable x |
| examples.py:20:17:20:17 | SSA variable x | examples.py:22:15:22:15 | ControlFlowNode for x |
| examples.py:21:12:21:14 | ControlFlowNode for obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
| examples.py:21:12:21:14 | [post read] ControlFlowNode for obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:27:8:27:12 | ControlFlowNode for myobj |
| examples.py:25:9:25:13 | ControlFlowNode for MyObj | examples.py:49:7:49:11 | ControlFlowNode for MyObj |
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:25:1:25:5 | GSSA Variable myobj |
| examples.py:27:8:27:12 | ControlFlowNode for myobj | examples.py:28:6:28:10 | ControlFlowNode for myobj |
| examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj | examples.py:28:6:28:10 | ControlFlowNode for myobj |
| examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:31:5:31:10 | ControlFlowNode for SOURCE |
| examples.py:27:15:27:20 | [post arg] ControlFlowNode for SOURCE | examples.py:31:5:31:10 | ControlFlowNode for SOURCE |
| examples.py:28:1:28:4 | ControlFlowNode for SINK | examples.py:37:1:37:4 | ControlFlowNode for SINK |
| examples.py:31:1:31:1 | GSSA Variable x | examples.py:35:13:35:13 | ControlFlowNode for x |
| examples.py:31:5:31:10 | ControlFlowNode for SOURCE | examples.py:31:1:31:1 | GSSA Variable x |
| examples.py:31:5:31:10 | ControlFlowNode for SOURCE | examples.py:40:5:40:10 | ControlFlowNode for SOURCE |
| examples.py:33:1:33:1 | GSSA Variable a | examples.py:35:1:35:1 | ControlFlowNode for a |
| examples.py:33:5:33:13 | ControlFlowNode for NestedObj | examples.py:42:5:42:13 | ControlFlowNode for NestedObj |
| examples.py:33:5:33:15 | ControlFlowNode for NestedObj() | examples.py:33:1:33:1 | GSSA Variable a |
| examples.py:35:1:35:1 | ControlFlowNode for a | examples.py:37:6:37:6 | ControlFlowNode for a |
| examples.py:35:1:35:1 | [post read] ControlFlowNode for a | examples.py:37:6:37:6 | ControlFlowNode for a |
| examples.py:37:1:37:4 | ControlFlowNode for SINK | examples.py:46:1:46:4 | ControlFlowNode for SINK |
| examples.py:40:1:40:1 | GSSA Variable x | examples.py:44:18:44:18 | ControlFlowNode for x |
| examples.py:40:5:40:10 | ControlFlowNode for SOURCE | examples.py:40:1:40:1 | GSSA Variable x |
| examples.py:40:5:40:10 | ControlFlowNode for SOURCE | examples.py:49:13:49:18 | ControlFlowNode for SOURCE |
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:44:1:44:1 | ControlFlowNode for a |
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:42:1:42:1 | GSSA Variable a |
| examples.py:44:1:44:1 | ControlFlowNode for a | examples.py:46:6:46:6 | ControlFlowNode for a |
| examples.py:44:1:44:1 | [post read] ControlFlowNode for a | examples.py:46:6:46:6 | ControlFlowNode for a |
| examples.py:46:1:46:4 | ControlFlowNode for SINK | examples.py:50:1:50:4 | ControlFlowNode for SINK |
| examples.py:49:1:49:3 | GSSA Variable obj | examples.py:50:6:50:8 | ControlFlowNode for obj |
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() | examples.py:49:1:49:3 | GSSA Variable obj |
| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
| examples.py:49:13:49:18 | [post arg] ControlFlowNode for SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
| examples.py:50:1:50:4 | ControlFlowNode for SINK | examples.py:59:1:59:4 | ControlFlowNode for SINK |
| examples.py:53:1:53:30 | ControlFlowNode for FunctionExpr | examples.py:53:5:53:26 | GSSA Variable fields_with_local_flow |
| examples.py:53:1:53:30 | GSSA Variable MyObj | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
| examples.py:53:5:53:26 | GSSA Variable fields_with_local_flow | examples.py:59:6:59:27 | ControlFlowNode for fields_with_local_flow |
| examples.py:53:28:53:28 | ControlFlowNode for x | examples.py:53:28:53:28 | SSA variable x |
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:17:54:17 | ControlFlowNode for x |
| examples.py:54:5:54:7 | SSA variable obj | examples.py:55:9:55:11 | ControlFlowNode for obj |
| examples.py:54:11:54:18 | ControlFlowNode for MyObj() | examples.py:54:5:54:7 | SSA variable obj |
| examples.py:55:5:55:5 | SSA variable a | examples.py:56:12:56:12 | ControlFlowNode for a |
| examples.py:55:9:55:15 | ControlFlowNode for Attribute | examples.py:55:5:55:5 | SSA variable a |
| test.py:2:13:2:26 | ControlFlowNode for Str | test.py:2:1:2:9 | GSSA Variable NONSOURCE |
| test.py:3:10:3:17 | ControlFlowNode for Str | test.py:3:1:3:6 | GSSA Variable SOURCE |
| test.py:6:1:6:17 | ControlFlowNode for FunctionExpr | test.py:6:5:6:13 | GSSA Variable is_source |
| test.py:6:15:6:15 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
| test.py:6:15:6:15 | SSA variable x | test.py:7:12:7:12 | ControlFlowNode for x |
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:29:7:29 | ControlFlowNode for x |
| test.py:7:12:7:24 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:47:7:47 | ControlFlowNode for x |
| test.py:7:29:7:42 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
| test.py:7:47:7:53 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
| test.py:7:58:7:66 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
| test.py:7:71:7:78 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
| test.py:10:1:10:12 | ControlFlowNode for FunctionExpr | test.py:10:5:10:8 | GSSA Variable SINK |
| test.py:10:1:10:12 | GSSA Variable is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
| test.py:10:10:10:10 | ControlFlowNode for x | test.py:10:10:10:10 | SSA variable x |
| test.py:10:10:10:10 | SSA variable x | test.py:11:18:11:18 | ControlFlowNode for x |
| test.py:11:18:11:18 | ControlFlowNode for x | test.py:14:34:14:34 | ControlFlowNode for x |
| test.py:11:18:11:18 | [post arg] ControlFlowNode for x | test.py:14:34:14:34 | ControlFlowNode for x |
| test.py:17:1:17:14 | ControlFlowNode for FunctionExpr | test.py:17:5:17:10 | GSSA Variable SINK_F |
| test.py:17:1:17:14 | GSSA Variable is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
| test.py:17:12:17:12 | ControlFlowNode for x | test.py:17:12:17:12 | SSA variable x |
| test.py:17:12:17:12 | SSA variable x | test.py:18:18:18:18 | ControlFlowNode for x |
| test.py:18:18:18:18 | ControlFlowNode for x | test.py:19:34:19:34 | ControlFlowNode for x |
| test.py:18:18:18:18 | [post arg] ControlFlowNode for x | test.py:19:34:19:34 | ControlFlowNode for x |
| test.py:25:1:25:20 | ControlFlowNode for ClassExpr | test.py:25:7:25:11 | GSSA Variable MyObj |
| test.py:25:13:25:18 | ControlFlowNode for object | test.py:33:17:33:22 | ControlFlowNode for object |
| test.py:26:5:26:28 | ControlFlowNode for FunctionExpr | test.py:26:9:26:16 | SSA variable __init__ |
| test.py:26:18:26:21 | ControlFlowNode for self | test.py:26:18:26:21 | SSA variable self |
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:12 | ControlFlowNode for self |
| test.py:26:24:26:26 | ControlFlowNode for foo | test.py:26:24:26:26 | SSA variable foo |
| test.py:26:24:26:26 | SSA variable foo | test.py:27:20:27:22 | ControlFlowNode for foo |
| test.py:29:5:29:26 | ControlFlowNode for FunctionExpr | test.py:29:9:29:14 | SSA variable setFoo |
| test.py:29:16:29:19 | ControlFlowNode for self | test.py:29:16:29:19 | SSA variable self |
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:12 | ControlFlowNode for self |
| test.py:29:22:29:24 | ControlFlowNode for foo | test.py:29:22:29:24 | SSA variable foo |
| test.py:29:22:29:24 | SSA variable foo | test.py:30:20:30:22 | ControlFlowNode for foo |
| test.py:33:1:33:24 | ControlFlowNode for ClassExpr | test.py:33:7:33:15 | GSSA Variable NestedObj |
| test.py:34:5:34:23 | ControlFlowNode for FunctionExpr | test.py:34:9:34:16 | SSA variable __init__ |
| test.py:34:5:34:23 | GSSA Variable MyObj | test.py:35:20:35:24 | ControlFlowNode for MyObj |
| test.py:34:18:34:21 | ControlFlowNode for self | test.py:34:18:34:21 | SSA variable self |
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:12 | ControlFlowNode for self |
| test.py:37:5:37:21 | ControlFlowNode for FunctionExpr | test.py:37:9:37:14 | SSA variable getObj |
| test.py:37:16:37:19 | ControlFlowNode for self | test.py:37:16:37:19 | SSA variable self |
| test.py:37:16:37:19 | SSA variable self | test.py:38:16:38:19 | ControlFlowNode for self |
| test.py:41:1:41:19 | ControlFlowNode for FunctionExpr | test.py:41:5:41:10 | GSSA Variable setFoo |
| test.py:41:1:41:19 | GSSA Variable SINK_F | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
| test.py:41:12:41:14 | ControlFlowNode for obj | test.py:41:12:41:14 | SSA variable obj |
| test.py:41:12:41:14 | SSA variable obj | test.py:42:12:42:14 | ControlFlowNode for obj |
| test.py:41:17:41:17 | ControlFlowNode for x | test.py:41:17:41:17 | SSA variable x |
| test.py:41:17:41:17 | SSA variable x | test.py:43:15:43:15 | ControlFlowNode for x |
| test.py:42:12:42:14 | ControlFlowNode for obj | test.py:43:5:43:7 | ControlFlowNode for obj |
| test.py:42:12:42:14 | [post read] ControlFlowNode for obj | test.py:43:5:43:7 | ControlFlowNode for obj |
| test.py:46:1:46:20 | ControlFlowNode for FunctionExpr | test.py:46:5:46:17 | GSSA Variable test_example1 |
| test.py:46:1:46:20 | GSSA Variable MyObj | test.py:47:13:47:17 | ControlFlowNode for MyObj |
| test.py:46:1:46:20 | GSSA Variable SINK | test.py:50:5:50:8 | ControlFlowNode for SINK |
| test.py:46:1:46:20 | GSSA Variable SOURCE | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
| test.py:46:1:46:20 | GSSA Variable setFoo | test.py:49:5:49:10 | ControlFlowNode for setFoo |
| test.py:47:5:47:9 | SSA variable myobj | test.py:49:12:49:16 | ControlFlowNode for myobj |
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:47:5:47:9 | SSA variable myobj |
| test.py:49:12:49:16 | ControlFlowNode for myobj | test.py:50:10:50:14 | ControlFlowNode for myobj |
| test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj | test.py:50:10:50:14 | ControlFlowNode for myobj |
| test.py:53:1:53:27 | ControlFlowNode for FunctionExpr | test.py:53:5:53:24 | GSSA Variable test_example1_method |
| test.py:53:1:53:27 | GSSA Variable MyObj | test.py:54:13:54:17 | ControlFlowNode for MyObj |
| test.py:53:1:53:27 | GSSA Variable SINK | test.py:57:5:57:8 | ControlFlowNode for SINK |
| test.py:53:1:53:27 | GSSA Variable SOURCE | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
| test.py:54:5:54:9 | SSA variable myobj | test.py:56:5:56:9 | ControlFlowNode for myobj |
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:54:5:54:9 | SSA variable myobj |
| test.py:56:5:56:9 | ControlFlowNode for myobj | test.py:57:10:57:14 | ControlFlowNode for myobj |
| test.py:56:5:56:9 | [post read] ControlFlowNode for myobj | test.py:57:10:57:14 | ControlFlowNode for myobj |
| test.py:60:1:60:20 | ControlFlowNode for FunctionExpr | test.py:60:5:60:17 | GSSA Variable test_example2 |
| test.py:60:1:60:20 | GSSA Variable NestedObj | test.py:63:9:63:17 | ControlFlowNode for NestedObj |
| test.py:60:1:60:20 | GSSA Variable SINK | test.py:67:5:67:8 | ControlFlowNode for SINK |
| test.py:60:1:60:20 | GSSA Variable SOURCE | test.py:61:9:61:14 | ControlFlowNode for SOURCE |
| test.py:61:5:61:5 | SSA variable x | test.py:65:17:65:17 | ControlFlowNode for x |
| test.py:61:9:61:14 | ControlFlowNode for SOURCE | test.py:61:5:61:5 | SSA variable x |
| test.py:63:5:63:5 | SSA variable a | test.py:65:5:65:5 | ControlFlowNode for a |
| test.py:63:9:63:19 | ControlFlowNode for NestedObj() | test.py:63:5:63:5 | SSA variable a |
| test.py:65:5:65:5 | ControlFlowNode for a | test.py:67:10:67:10 | ControlFlowNode for a |
| test.py:65:5:65:5 | [post read] ControlFlowNode for a | test.py:67:10:67:10 | ControlFlowNode for a |
| test.py:70:1:70:27 | ControlFlowNode for FunctionExpr | test.py:70:5:70:24 | GSSA Variable test_example2_method |
| test.py:70:1:70:27 | GSSA Variable NestedObj | test.py:73:9:73:17 | ControlFlowNode for NestedObj |
| test.py:70:1:70:27 | GSSA Variable SINK | test.py:77:5:77:8 | ControlFlowNode for SINK |
| test.py:70:1:70:27 | GSSA Variable SOURCE | test.py:71:9:71:14 | ControlFlowNode for SOURCE |
| test.py:71:5:71:5 | SSA variable x | test.py:75:22:75:22 | ControlFlowNode for x |
| test.py:71:9:71:14 | ControlFlowNode for SOURCE | test.py:71:5:71:5 | SSA variable x |
| test.py:73:5:73:5 | SSA variable a | test.py:75:5:75:5 | ControlFlowNode for a |
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:73:5:73:5 | SSA variable a |
| test.py:75:5:75:5 | ControlFlowNode for a | test.py:77:10:77:10 | ControlFlowNode for a |
| test.py:75:5:75:5 | [post read] ControlFlowNode for a | test.py:77:10:77:10 | ControlFlowNode for a |
| test.py:80:1:80:20 | ControlFlowNode for FunctionExpr | test.py:80:5:80:17 | GSSA Variable test_example3 |
| test.py:80:1:80:20 | GSSA Variable MyObj | test.py:81:11:81:15 | ControlFlowNode for MyObj |
| test.py:80:1:80:20 | GSSA Variable SINK | test.py:82:5:82:8 | ControlFlowNode for SINK |
| test.py:80:1:80:20 | GSSA Variable SOURCE | test.py:81:17:81:22 | ControlFlowNode for SOURCE |
| test.py:81:5:81:7 | SSA variable obj | test.py:82:10:82:12 | ControlFlowNode for obj |
| test.py:81:11:81:23 | ControlFlowNode for MyObj() | test.py:81:5:81:7 | SSA variable obj |
| test.py:85:1:85:23 | ControlFlowNode for FunctionExpr | test.py:85:5:85:20 | GSSA Variable test_example3_kw |
| test.py:85:1:85:23 | GSSA Variable MyObj | test.py:86:11:86:15 | ControlFlowNode for MyObj |
| test.py:85:1:85:23 | GSSA Variable SINK | test.py:87:5:87:8 | ControlFlowNode for SINK |
| test.py:85:1:85:23 | GSSA Variable SOURCE | test.py:86:21:86:26 | ControlFlowNode for SOURCE |
| test.py:86:5:86:7 | SSA variable obj | test.py:87:10:87:12 | ControlFlowNode for obj |
| test.py:86:11:86:27 | ControlFlowNode for MyObj() | test.py:86:5:86:7 | SSA variable obj |
| test.py:90:1:90:30 | ControlFlowNode for FunctionExpr | test.py:90:5:90:26 | GSSA Variable fields_with_local_flow |
| test.py:90:1:90:30 | GSSA Variable MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
| test.py:90:28:90:28 | ControlFlowNode for x | test.py:90:28:90:28 | SSA variable x |
| test.py:90:28:90:28 | SSA variable x | test.py:91:17:91:17 | ControlFlowNode for x |
| test.py:91:5:91:7 | SSA variable obj | test.py:92:9:92:11 | ControlFlowNode for obj |
| test.py:91:11:91:18 | ControlFlowNode for MyObj() | test.py:91:5:91:7 | SSA variable obj |
| test.py:92:5:92:5 | SSA variable a | test.py:93:12:93:12 | ControlFlowNode for a |
| test.py:92:9:92:15 | ControlFlowNode for Attribute | test.py:92:5:92:5 | SSA variable a |
| test.py:96:1:96:18 | ControlFlowNode for FunctionExpr | test.py:96:5:96:15 | GSSA Variable test_fields |
| test.py:96:1:96:18 | GSSA Variable SINK | test.py:97:5:97:8 | ControlFlowNode for SINK |
| test.py:96:1:96:18 | GSSA Variable SOURCE | test.py:97:33:97:38 | ControlFlowNode for SOURCE |
| test.py:96:1:96:18 | GSSA Variable fields_with_local_flow | test.py:97:10:97:31 | ControlFlowNode for fields_with_local_flow |

View File

@@ -1,8 +0,0 @@
import python
import semmle.python.dataflow.new.DataFlow
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
where
DataFlow::localFlowStep(nodeFrom, nodeTo) and
nodeFrom.getLocation().getFile().getParent().getBaseName() = "fieldflow"
select nodeFrom, nodeTo

View File

@@ -1,169 +0,0 @@
edges
| examples.py:7:24:7:26 | ControlFlowNode for foo | examples.py:8:20:8:22 | ControlFlowNode for foo |
| examples.py:8:20:8:22 | ControlFlowNode for foo | examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] |
| examples.py:20:17:20:17 | ControlFlowNode for x | examples.py:22:15:22:15 | ControlFlowNode for x |
| examples.py:22:15:22:15 | ControlFlowNode for x | examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] |
| examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] | examples.py:28:6:28:10 | ControlFlowNode for myobj [Attribute foo] |
| examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:20:17:20:17 | ControlFlowNode for x |
| examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] |
| examples.py:28:6:28:10 | ControlFlowNode for myobj [Attribute foo] | examples.py:28:6:28:14 | ControlFlowNode for Attribute |
| examples.py:31:5:31:10 | ControlFlowNode for SOURCE | examples.py:35:13:35:13 | ControlFlowNode for x |
| examples.py:35:1:35:1 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | examples.py:37:6:37:6 | ControlFlowNode for a [Attribute obj, Attribute foo] |
| examples.py:35:1:35:5 | [post store] ControlFlowNode for Attribute [Attribute foo] | examples.py:35:1:35:1 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
| examples.py:35:13:35:13 | ControlFlowNode for x | examples.py:35:1:35:5 | [post store] ControlFlowNode for Attribute [Attribute foo] |
| examples.py:37:6:37:6 | ControlFlowNode for a [Attribute obj, Attribute foo] | examples.py:37:6:37:10 | ControlFlowNode for Attribute [Attribute foo] |
| examples.py:37:6:37:10 | ControlFlowNode for Attribute [Attribute foo] | examples.py:37:6:37:14 | ControlFlowNode for Attribute |
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] | examples.py:50:6:50:8 | ControlFlowNode for obj [Attribute foo] |
| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:7:24:7:26 | ControlFlowNode for foo |
| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] |
| examples.py:50:6:50:8 | ControlFlowNode for obj [Attribute foo] | examples.py:50:6:50:12 | ControlFlowNode for Attribute |
| examples.py:53:28:53:28 | ControlFlowNode for x | examples.py:54:17:54:17 | ControlFlowNode for x |
| examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] | examples.py:55:9:55:11 | ControlFlowNode for obj [Attribute foo] |
| examples.py:54:17:54:17 | ControlFlowNode for x | examples.py:7:24:7:26 | ControlFlowNode for foo |
| examples.py:54:17:54:17 | ControlFlowNode for x | examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] |
| examples.py:55:9:55:11 | ControlFlowNode for obj [Attribute foo] | examples.py:55:9:55:15 | ControlFlowNode for Attribute |
| examples.py:55:9:55:15 | ControlFlowNode for Attribute | examples.py:56:12:56:12 | ControlFlowNode for a |
| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:53:28:53:28 | ControlFlowNode for x |
| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() |
| test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:20:27:22 | ControlFlowNode for foo |
| test.py:27:20:27:22 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] |
| test.py:29:22:29:24 | ControlFlowNode for foo | test.py:30:20:30:22 | ControlFlowNode for foo |
| test.py:30:20:30:22 | ControlFlowNode for foo | test.py:30:9:30:12 | [post store] ControlFlowNode for self [Attribute foo] |
| test.py:41:17:41:17 | ControlFlowNode for x | test.py:43:15:43:15 | ControlFlowNode for x |
| test.py:43:15:43:15 | ControlFlowNode for x | test.py:43:5:43:7 | [post store] ControlFlowNode for obj [Attribute foo] |
| test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | test.py:50:10:50:14 | ControlFlowNode for myobj [Attribute foo] |
| test.py:49:19:49:24 | ControlFlowNode for SOURCE | test.py:41:17:41:17 | ControlFlowNode for x |
| test.py:49:19:49:24 | ControlFlowNode for SOURCE | test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] |
| test.py:50:10:50:14 | ControlFlowNode for myobj [Attribute foo] | test.py:50:10:50:18 | ControlFlowNode for Attribute |
| test.py:56:5:56:9 | [post read] ControlFlowNode for myobj [Attribute foo] | test.py:57:10:57:14 | ControlFlowNode for myobj [Attribute foo] |
| test.py:56:18:56:23 | ControlFlowNode for SOURCE | test.py:29:22:29:24 | ControlFlowNode for foo |
| test.py:56:18:56:23 | ControlFlowNode for SOURCE | test.py:56:5:56:9 | [post read] ControlFlowNode for myobj [Attribute foo] |
| test.py:57:10:57:14 | ControlFlowNode for myobj [Attribute foo] | test.py:57:10:57:18 | ControlFlowNode for Attribute |
| test.py:61:9:61:14 | ControlFlowNode for SOURCE | test.py:65:17:65:17 | ControlFlowNode for x |
| test.py:65:5:65:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:67:10:67:10 | ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:65:5:65:9 | [post store] ControlFlowNode for Attribute [Attribute foo] | test.py:65:5:65:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:65:17:65:17 | ControlFlowNode for x | test.py:65:5:65:9 | [post store] ControlFlowNode for Attribute [Attribute foo] |
| test.py:67:10:67:10 | ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:67:10:67:14 | ControlFlowNode for Attribute [Attribute foo] |
| test.py:67:10:67:14 | ControlFlowNode for Attribute [Attribute foo] | test.py:67:10:67:18 | ControlFlowNode for Attribute |
| test.py:71:9:71:14 | ControlFlowNode for SOURCE | test.py:75:22:75:22 | ControlFlowNode for x |
| test.py:75:5:75:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:77:10:77:10 | ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:75:5:75:14 | [post store] ControlFlowNode for Attribute() [Attribute foo] | test.py:75:5:75:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:75:22:75:22 | ControlFlowNode for x | test.py:75:5:75:14 | [post store] ControlFlowNode for Attribute() [Attribute foo] |
| test.py:77:10:77:10 | ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:77:10:77:14 | ControlFlowNode for Attribute [Attribute foo] |
| test.py:77:10:77:14 | ControlFlowNode for Attribute [Attribute foo] | test.py:77:10:77:18 | ControlFlowNode for Attribute |
| test.py:81:11:81:23 | ControlFlowNode for MyObj() [Attribute foo] | test.py:82:10:82:12 | ControlFlowNode for obj [Attribute foo] |
| test.py:81:17:81:22 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo |
| test.py:81:17:81:22 | ControlFlowNode for SOURCE | test.py:81:11:81:23 | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:82:10:82:12 | ControlFlowNode for obj [Attribute foo] | test.py:82:10:82:16 | ControlFlowNode for Attribute |
| test.py:86:11:86:27 | ControlFlowNode for MyObj() [Attribute foo] | test.py:87:10:87:12 | ControlFlowNode for obj [Attribute foo] |
| test.py:86:21:86:26 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo |
| test.py:86:21:86:26 | ControlFlowNode for SOURCE | test.py:86:11:86:27 | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:87:10:87:12 | ControlFlowNode for obj [Attribute foo] | test.py:87:10:87:16 | ControlFlowNode for Attribute |
| test.py:90:28:90:28 | ControlFlowNode for x | test.py:91:17:91:17 | ControlFlowNode for x |
| test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] | test.py:92:9:92:11 | ControlFlowNode for obj [Attribute foo] |
| test.py:91:17:91:17 | ControlFlowNode for x | test.py:26:24:26:26 | ControlFlowNode for foo |
| test.py:91:17:91:17 | ControlFlowNode for x | test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:92:9:92:11 | ControlFlowNode for obj [Attribute foo] | test.py:92:9:92:15 | ControlFlowNode for Attribute |
| test.py:92:9:92:15 | ControlFlowNode for Attribute | test.py:93:12:93:12 | ControlFlowNode for a |
| test.py:97:33:97:38 | ControlFlowNode for SOURCE | test.py:90:28:90:28 | ControlFlowNode for x |
| test.py:97:33:97:38 | ControlFlowNode for SOURCE | test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() |
nodes
| examples.py:7:24:7:26 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] | semmle.label | [post store] ControlFlowNode for self [Attribute foo] |
| examples.py:8:20:8:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| examples.py:20:17:20:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] | semmle.label | [post store] ControlFlowNode for obj [Attribute foo] |
| examples.py:22:15:22:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] | semmle.label | [post arg] ControlFlowNode for myobj [Attribute foo] |
| examples.py:27:15:27:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| examples.py:28:6:28:10 | ControlFlowNode for myobj [Attribute foo] | semmle.label | ControlFlowNode for myobj [Attribute foo] |
| examples.py:28:6:28:14 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| examples.py:31:5:31:10 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| examples.py:35:1:35:1 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
| examples.py:35:1:35:5 | [post store] ControlFlowNode for Attribute [Attribute foo] | semmle.label | [post store] ControlFlowNode for Attribute [Attribute foo] |
| examples.py:35:13:35:13 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| examples.py:37:6:37:6 | ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | ControlFlowNode for a [Attribute obj, Attribute foo] |
| examples.py:37:6:37:10 | ControlFlowNode for Attribute [Attribute foo] | semmle.label | ControlFlowNode for Attribute [Attribute foo] |
| examples.py:37:6:37:14 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] | semmle.label | ControlFlowNode for MyObj() [Attribute foo] |
| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| examples.py:50:6:50:8 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] |
| examples.py:50:6:50:12 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| examples.py:53:28:53:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] | semmle.label | ControlFlowNode for MyObj() [Attribute foo] |
| examples.py:54:17:54:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| examples.py:55:9:55:11 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] |
| examples.py:55:9:55:15 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| examples.py:56:12:56:12 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() | semmle.label | ControlFlowNode for fields_with_local_flow() |
| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:26:24:26:26 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | semmle.label | [post store] ControlFlowNode for self [Attribute foo] |
| test.py:27:20:27:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| test.py:29:22:29:24 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| test.py:30:9:30:12 | [post store] ControlFlowNode for self [Attribute foo] | semmle.label | [post store] ControlFlowNode for self [Attribute foo] |
| test.py:30:20:30:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| test.py:41:17:41:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:43:5:43:7 | [post store] ControlFlowNode for obj [Attribute foo] | semmle.label | [post store] ControlFlowNode for obj [Attribute foo] |
| test.py:43:15:43:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | semmle.label | [post arg] ControlFlowNode for myobj [Attribute foo] |
| test.py:49:19:49:24 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:50:10:50:14 | ControlFlowNode for myobj [Attribute foo] | semmle.label | ControlFlowNode for myobj [Attribute foo] |
| test.py:50:10:50:18 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:56:5:56:9 | [post read] ControlFlowNode for myobj [Attribute foo] | semmle.label | [post read] ControlFlowNode for myobj [Attribute foo] |
| test.py:56:18:56:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:57:10:57:14 | ControlFlowNode for myobj [Attribute foo] | semmle.label | ControlFlowNode for myobj [Attribute foo] |
| test.py:57:10:57:18 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:61:9:61:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:65:5:65:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:65:5:65:9 | [post store] ControlFlowNode for Attribute [Attribute foo] | semmle.label | [post store] ControlFlowNode for Attribute [Attribute foo] |
| test.py:65:17:65:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:67:10:67:10 | ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:67:10:67:14 | ControlFlowNode for Attribute [Attribute foo] | semmle.label | ControlFlowNode for Attribute [Attribute foo] |
| test.py:67:10:67:18 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:71:9:71:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:75:5:75:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:75:5:75:14 | [post store] ControlFlowNode for Attribute() [Attribute foo] | semmle.label | [post store] ControlFlowNode for Attribute() [Attribute foo] |
| test.py:75:22:75:22 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:77:10:77:10 | ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | ControlFlowNode for a [Attribute obj, Attribute foo] |
| test.py:77:10:77:14 | ControlFlowNode for Attribute [Attribute foo] | semmle.label | ControlFlowNode for Attribute [Attribute foo] |
| test.py:77:10:77:18 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:81:11:81:23 | ControlFlowNode for MyObj() [Attribute foo] | semmle.label | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:81:17:81:22 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:82:10:82:12 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] |
| test.py:82:10:82:16 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:86:11:86:27 | ControlFlowNode for MyObj() [Attribute foo] | semmle.label | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:86:21:86:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:87:10:87:12 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] |
| test.py:87:10:87:16 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:90:28:90:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] | semmle.label | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:91:17:91:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:92:9:92:11 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] |
| test.py:92:9:92:15 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:93:12:93:12 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() | semmle.label | ControlFlowNode for fields_with_local_flow() |
| test.py:97:33:97:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
subpaths
| examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:20:17:20:17 | ControlFlowNode for x | examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] | examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] |
| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:7:24:7:26 | ControlFlowNode for foo | examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] | examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] |
| examples.py:54:17:54:17 | ControlFlowNode for x | examples.py:7:24:7:26 | ControlFlowNode for foo | examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] | examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] |
| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:53:28:53:28 | ControlFlowNode for x | examples.py:56:12:56:12 | ControlFlowNode for a | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() |
| test.py:49:19:49:24 | ControlFlowNode for SOURCE | test.py:41:17:41:17 | ControlFlowNode for x | test.py:43:5:43:7 | [post store] ControlFlowNode for obj [Attribute foo] | test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] |
| test.py:56:18:56:23 | ControlFlowNode for SOURCE | test.py:29:22:29:24 | ControlFlowNode for foo | test.py:30:9:30:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:56:5:56:9 | [post read] ControlFlowNode for myobj [Attribute foo] |
| test.py:81:17:81:22 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:81:11:81:23 | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:86:21:86:26 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:86:11:86:27 | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:91:17:91:17 | ControlFlowNode for x | test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] |
| test.py:97:33:97:38 | ControlFlowNode for SOURCE | test.py:90:28:90:28 | ControlFlowNode for x | test.py:93:12:93:12 | ControlFlowNode for a | test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() |
#select
| examples.py:28:6:28:14 | ControlFlowNode for Attribute | examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:28:6:28:14 | ControlFlowNode for Attribute | Flow found |
| examples.py:37:6:37:14 | ControlFlowNode for Attribute | examples.py:31:5:31:10 | ControlFlowNode for SOURCE | examples.py:37:6:37:14 | ControlFlowNode for Attribute | Flow found |
| examples.py:50:6:50:12 | ControlFlowNode for Attribute | examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:50:6:50:12 | ControlFlowNode for Attribute | Flow found |
| examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() | examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() | Flow found |
| test.py:50:10:50:18 | ControlFlowNode for Attribute | test.py:49:19:49:24 | ControlFlowNode for SOURCE | test.py:50:10:50:18 | ControlFlowNode for Attribute | Flow found |
| test.py:57:10:57:18 | ControlFlowNode for Attribute | test.py:56:18:56:23 | ControlFlowNode for SOURCE | test.py:57:10:57:18 | ControlFlowNode for Attribute | Flow found |
| test.py:67:10:67:18 | ControlFlowNode for Attribute | test.py:61:9:61:14 | ControlFlowNode for SOURCE | test.py:67:10:67:18 | ControlFlowNode for Attribute | Flow found |
| test.py:77:10:77:18 | ControlFlowNode for Attribute | test.py:71:9:71:14 | ControlFlowNode for SOURCE | test.py:77:10:77:18 | ControlFlowNode for Attribute | Flow found |
| test.py:82:10:82:16 | ControlFlowNode for Attribute | test.py:81:17:81:22 | ControlFlowNode for SOURCE | test.py:82:10:82:16 | ControlFlowNode for Attribute | Flow found |
| test.py:87:10:87:16 | ControlFlowNode for Attribute | test.py:86:21:86:26 | ControlFlowNode for SOURCE | test.py:87:10:87:16 | ControlFlowNode for Attribute | Flow found |
| test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() | test.py:97:33:97:38 | ControlFlowNode for SOURCE | test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() | Flow found |

View File

@@ -1,10 +0,0 @@
/**
* @kind path-problem
*/
import experimental.dataflow.testConfig
import DataFlow::PathGraph
from TestConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Flow found"

View File

@@ -1,59 +0,0 @@
from python.ql.test.experimental.dataflow.testDefinitions import *
# Preamble
class MyObj(object):
def __init__(self, foo):
self.foo = foo
class NestedObj(object):
def __init__(self):
self.obj = MyObj("OK")
def getObj(self):
return self.obj
# Example 1
def setFoo(obj, x):
SINK_F(obj.foo)
obj.foo = x
myobj = MyObj("OK")
setFoo(myobj, SOURCE)
SINK(myobj.foo)
# Example 2
x = SOURCE
a = NestedObj()
a.obj.foo = x
SINK(a.obj.foo)
# Example 2 with method call
x = SOURCE
a = NestedObj()
a.getObj().foo = x
SINK(a.obj.foo) # Flow missing
# Example 3
obj = MyObj(SOURCE)
SINK(obj.foo)
# Local flow
def fields_with_local_flow(x):
obj = MyObj(x)
a = obj.foo
return a
SINK(fields_with_local_flow(SOURCE))

View File

@@ -1,7 +0,0 @@
import experimental.dataflow.basic.allFlowsConfig
from DataFlow::PathNode fromNode, DataFlow::PathNode toNode
where
toNode = fromNode.getASuccessor() and
fromNode.getNode().getLocation().getFile().getParent().getBaseName() = "fieldflow"
select fromNode, toNode

View File

@@ -1,14 +0,0 @@
| examples.py:53:1:53:30 | GSSA Variable MyObj | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
| examples.py:53:28:53:28 | ControlFlowNode for x | examples.py:53:28:53:28 | SSA variable x |
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:17:54:17 | ControlFlowNode for x |
| examples.py:54:5:54:7 | SSA variable obj | examples.py:55:9:55:11 | ControlFlowNode for obj |
| examples.py:54:11:54:18 | ControlFlowNode for MyObj() | examples.py:54:5:54:7 | SSA variable obj |
| examples.py:55:5:55:5 | SSA variable a | examples.py:56:12:56:12 | ControlFlowNode for a |
| examples.py:55:9:55:15 | ControlFlowNode for Attribute | examples.py:55:5:55:5 | SSA variable a |
| test.py:90:1:90:30 | GSSA Variable MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
| test.py:90:28:90:28 | ControlFlowNode for x | test.py:90:28:90:28 | SSA variable x |
| test.py:90:28:90:28 | SSA variable x | test.py:91:17:91:17 | ControlFlowNode for x |
| test.py:91:5:91:7 | SSA variable obj | test.py:92:9:92:11 | ControlFlowNode for obj |
| test.py:91:11:91:18 | ControlFlowNode for MyObj() | test.py:91:5:91:7 | SSA variable obj |
| test.py:92:5:92:5 | SSA variable a | test.py:93:12:93:12 | ControlFlowNode for a |
| test.py:92:9:92:15 | ControlFlowNode for Attribute | test.py:92:5:92:5 | SSA variable a |

View File

@@ -1,8 +0,0 @@
import python
import semmle.python.dataflow.new.DataFlow
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
where
DataFlow::localFlowStep(nodeFrom, nodeTo) and
nodeFrom.getEnclosingCallable().getName().matches("%\\_with\\_local\\_flow")
select nodeFrom, nodeTo

View File

@@ -0,0 +1 @@
semmle-extractor-options: --max-import-depth=3

View File

@@ -1,80 +0,0 @@
| examples.py:8:9:8:12 | [post store] ControlFlowNode for self | examples.py:8:9:8:12 | ControlFlowNode for self |
| examples.py:13:9:13:12 | [post store] ControlFlowNode for self | examples.py:13:9:13:12 | ControlFlowNode for self |
| examples.py:13:20:13:30 | ControlFlowNode for MyObj() | examples.py:13:20:13:30 | [pre objCreate] ControlFlowNode for MyObj() |
| examples.py:13:26:13:29 | [post arg] ControlFlowNode for Str | examples.py:13:26:13:29 | ControlFlowNode for Str |
| examples.py:16:16:16:19 | [post read] ControlFlowNode for self | examples.py:16:16:16:19 | ControlFlowNode for self |
| examples.py:21:12:21:14 | [post read] ControlFlowNode for obj | examples.py:21:12:21:14 | ControlFlowNode for obj |
| examples.py:22:5:22:7 | [post store] ControlFlowNode for obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:25:9:25:19 | [pre objCreate] ControlFlowNode for MyObj() |
| examples.py:25:15:25:18 | [post arg] ControlFlowNode for Str | examples.py:25:15:25:18 | ControlFlowNode for Str |
| examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj | examples.py:27:8:27:12 | ControlFlowNode for myobj |
| examples.py:27:15:27:20 | [post arg] ControlFlowNode for SOURCE | examples.py:27:15:27:20 | ControlFlowNode for SOURCE |
| examples.py:28:6:28:10 | [post read] ControlFlowNode for myobj | examples.py:28:6:28:10 | ControlFlowNode for myobj |
| examples.py:33:5:33:15 | ControlFlowNode for NestedObj() | examples.py:33:5:33:15 | [pre objCreate] ControlFlowNode for NestedObj() |
| examples.py:35:1:35:1 | [post read] ControlFlowNode for a | examples.py:35:1:35:1 | ControlFlowNode for a |
| examples.py:35:1:35:5 | [post store] ControlFlowNode for Attribute | examples.py:35:1:35:5 | ControlFlowNode for Attribute |
| examples.py:37:6:37:6 | [post read] ControlFlowNode for a | examples.py:37:6:37:6 | ControlFlowNode for a |
| examples.py:37:6:37:10 | [post read] ControlFlowNode for Attribute | examples.py:37:6:37:10 | ControlFlowNode for Attribute |
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:42:5:42:15 | [pre objCreate] ControlFlowNode for NestedObj() |
| examples.py:44:1:44:1 | [post read] ControlFlowNode for a | examples.py:44:1:44:1 | ControlFlowNode for a |
| examples.py:44:1:44:10 | [post store] ControlFlowNode for Attribute() | examples.py:44:1:44:10 | ControlFlowNode for Attribute() |
| examples.py:46:6:46:6 | [post read] ControlFlowNode for a | examples.py:46:6:46:6 | ControlFlowNode for a |
| examples.py:46:6:46:10 | [post read] ControlFlowNode for Attribute | examples.py:46:6:46:10 | ControlFlowNode for Attribute |
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() | examples.py:49:7:49:19 | [pre objCreate] ControlFlowNode for MyObj() |
| examples.py:49:13:49:18 | [post arg] ControlFlowNode for SOURCE | examples.py:49:13:49:18 | ControlFlowNode for SOURCE |
| examples.py:50:6:50:8 | [post read] ControlFlowNode for obj | examples.py:50:6:50:8 | ControlFlowNode for obj |
| examples.py:54:11:54:18 | ControlFlowNode for MyObj() | examples.py:54:11:54:18 | [pre objCreate] ControlFlowNode for MyObj() |
| examples.py:54:17:54:17 | [post arg] ControlFlowNode for x | examples.py:54:17:54:17 | ControlFlowNode for x |
| examples.py:55:9:55:11 | [post read] ControlFlowNode for obj | examples.py:55:9:55:11 | ControlFlowNode for obj |
| examples.py:59:29:59:34 | [post arg] ControlFlowNode for SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
| test.py:11:18:11:18 | [post arg] ControlFlowNode for x | test.py:11:18:11:18 | ControlFlowNode for x |
| test.py:18:18:18:18 | [post arg] ControlFlowNode for x | test.py:18:18:18:18 | ControlFlowNode for x |
| test.py:19:15:19:31 | [post arg] ControlFlowNode for Str | test.py:19:15:19:31 | ControlFlowNode for Str |
| test.py:19:34:19:34 | [post arg] ControlFlowNode for x | test.py:19:34:19:34 | ControlFlowNode for x |
| test.py:21:15:21:18 | [post arg] ControlFlowNode for Str | test.py:21:15:21:18 | ControlFlowNode for Str |
| test.py:27:9:27:12 | [post store] ControlFlowNode for self | test.py:27:9:27:12 | ControlFlowNode for self |
| test.py:30:9:30:12 | [post store] ControlFlowNode for self | test.py:30:9:30:12 | ControlFlowNode for self |
| test.py:35:9:35:12 | [post store] ControlFlowNode for self | test.py:35:9:35:12 | ControlFlowNode for self |
| test.py:35:20:35:30 | ControlFlowNode for MyObj() | test.py:35:20:35:30 | [pre objCreate] ControlFlowNode for MyObj() |
| test.py:35:26:35:29 | [post arg] ControlFlowNode for Str | test.py:35:26:35:29 | ControlFlowNode for Str |
| test.py:38:16:38:19 | [post read] ControlFlowNode for self | test.py:38:16:38:19 | ControlFlowNode for self |
| test.py:42:12:42:14 | [post read] ControlFlowNode for obj | test.py:42:12:42:14 | ControlFlowNode for obj |
| test.py:42:12:42:18 | [post arg] ControlFlowNode for Attribute | test.py:42:12:42:18 | ControlFlowNode for Attribute |
| test.py:43:5:43:7 | [post store] ControlFlowNode for obj | test.py:43:5:43:7 | ControlFlowNode for obj |
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:47:13:47:23 | [pre objCreate] ControlFlowNode for MyObj() |
| test.py:47:19:47:22 | [post arg] ControlFlowNode for Str | test.py:47:19:47:22 | ControlFlowNode for Str |
| test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj | test.py:49:12:49:16 | ControlFlowNode for myobj |
| test.py:49:19:49:24 | [post arg] ControlFlowNode for SOURCE | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
| test.py:50:10:50:14 | [post read] ControlFlowNode for myobj | test.py:50:10:50:14 | ControlFlowNode for myobj |
| test.py:50:10:50:18 | [post arg] ControlFlowNode for Attribute | test.py:50:10:50:18 | ControlFlowNode for Attribute |
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:54:13:54:23 | [pre objCreate] ControlFlowNode for MyObj() |
| test.py:54:19:54:22 | [post arg] ControlFlowNode for Str | test.py:54:19:54:22 | ControlFlowNode for Str |
| test.py:56:5:56:9 | [post read] ControlFlowNode for myobj | test.py:56:5:56:9 | ControlFlowNode for myobj |
| test.py:56:18:56:23 | [post arg] ControlFlowNode for SOURCE | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
| test.py:57:10:57:14 | [post read] ControlFlowNode for myobj | test.py:57:10:57:14 | ControlFlowNode for myobj |
| test.py:57:10:57:18 | [post arg] ControlFlowNode for Attribute | test.py:57:10:57:18 | ControlFlowNode for Attribute |
| test.py:63:9:63:19 | ControlFlowNode for NestedObj() | test.py:63:9:63:19 | [pre objCreate] ControlFlowNode for NestedObj() |
| test.py:65:5:65:5 | [post read] ControlFlowNode for a | test.py:65:5:65:5 | ControlFlowNode for a |
| test.py:65:5:65:9 | [post store] ControlFlowNode for Attribute | test.py:65:5:65:9 | ControlFlowNode for Attribute |
| test.py:67:10:67:10 | [post read] ControlFlowNode for a | test.py:67:10:67:10 | ControlFlowNode for a |
| test.py:67:10:67:14 | [post read] ControlFlowNode for Attribute | test.py:67:10:67:14 | ControlFlowNode for Attribute |
| test.py:67:10:67:18 | [post arg] ControlFlowNode for Attribute | test.py:67:10:67:18 | ControlFlowNode for Attribute |
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:73:9:73:19 | [pre objCreate] ControlFlowNode for NestedObj() |
| test.py:75:5:75:5 | [post read] ControlFlowNode for a | test.py:75:5:75:5 | ControlFlowNode for a |
| test.py:75:5:75:14 | [post store] ControlFlowNode for Attribute() | test.py:75:5:75:14 | ControlFlowNode for Attribute() |
| test.py:77:10:77:10 | [post read] ControlFlowNode for a | test.py:77:10:77:10 | ControlFlowNode for a |
| test.py:77:10:77:14 | [post read] ControlFlowNode for Attribute | test.py:77:10:77:14 | ControlFlowNode for Attribute |
| test.py:77:10:77:18 | [post arg] ControlFlowNode for Attribute | test.py:77:10:77:18 | ControlFlowNode for Attribute |
| test.py:81:11:81:23 | ControlFlowNode for MyObj() | test.py:81:11:81:23 | [pre objCreate] ControlFlowNode for MyObj() |
| test.py:81:17:81:22 | [post arg] ControlFlowNode for SOURCE | test.py:81:17:81:22 | ControlFlowNode for SOURCE |
| test.py:82:10:82:12 | [post read] ControlFlowNode for obj | test.py:82:10:82:12 | ControlFlowNode for obj |
| test.py:82:10:82:16 | [post arg] ControlFlowNode for Attribute | test.py:82:10:82:16 | ControlFlowNode for Attribute |
| test.py:86:11:86:27 | ControlFlowNode for MyObj() | test.py:86:11:86:27 | [pre objCreate] ControlFlowNode for MyObj() |
| test.py:86:21:86:26 | [post arg] ControlFlowNode for SOURCE | test.py:86:21:86:26 | ControlFlowNode for SOURCE |
| test.py:87:10:87:12 | [post read] ControlFlowNode for obj | test.py:87:10:87:12 | ControlFlowNode for obj |
| test.py:87:10:87:16 | [post arg] ControlFlowNode for Attribute | test.py:87:10:87:16 | ControlFlowNode for Attribute |
| test.py:91:11:91:18 | ControlFlowNode for MyObj() | test.py:91:11:91:18 | [pre objCreate] ControlFlowNode for MyObj() |
| test.py:91:17:91:17 | [post arg] ControlFlowNode for x | test.py:91:17:91:17 | ControlFlowNode for x |
| test.py:92:9:92:11 | [post read] ControlFlowNode for obj | test.py:92:9:92:11 | ControlFlowNode for obj |
| test.py:97:10:97:39 | [post arg] ControlFlowNode for fields_with_local_flow() | test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() |
| test.py:97:33:97:38 | [post arg] ControlFlowNode for SOURCE | test.py:97:33:97:38 | ControlFlowNode for SOURCE |

View File

@@ -1,4 +0,0 @@
import experimental.dataflow.testConfig
from DataFlow::PostUpdateNode pun
select pun, pun.getPreUpdateNode()

View File

@@ -1,3 +1,9 @@
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname((__file__)))) # $ unresolved_call=sys.path.append(..)
from testlib import expects
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
@@ -21,7 +27,10 @@ def SINK_F(x):
print("OK")
# Preamble
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
class MyObj(object):
def __init__(self, foo):
self.foo = foo
@@ -29,6 +38,106 @@ class MyObj(object):
def setFoo(self, foo):
self.foo = foo
def setFoo(obj, x):
SINK_F(obj.foo)
obj.foo = x
@expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
def test_indirect_assign():
myobj = MyObj("OK")
setFoo(myobj, SOURCE)
SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo"
def test_indirect_assign_method():
myobj = MyObj("OK")
myobj.setFoo(SOURCE)
SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo"
def test_direct_assign():
myobj = MyObj(NONSOURCE)
myobj.foo = SOURCE
SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo"
def test_direct_assign_overwrite():
myobj = MyObj(NONSOURCE)
myobj.foo = SOURCE
myobj.foo = NONSOURCE
SINK_F(myobj.foo)
def test_direct_if_assign(cond = False):
myobj = MyObj(NONSOURCE)
myobj.foo = SOURCE
if cond:
myobj.foo = NONSOURCE
SINK_F(myobj.foo)
SINK(myobj.foo) # $ flow="SOURCE, l:-4 -> myobj.foo"
@expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
def test_direct_if_always_assign(cond = True):
myobj = MyObj(NONSOURCE)
myobj.foo = SOURCE
if cond:
myobj.foo = NONSOURCE
SINK_F(myobj.foo)
else:
myobj.foo = NONSOURCE
SINK_F(myobj.foo)
SINK_F(myobj.foo)
def test_getattr():
myobj = MyObj(NONSOURCE)
myobj.foo = SOURCE
SINK(getattr(myobj, "foo")) # $ flow="SOURCE, l:-1 -> getattr(..)"
def test_setattr():
myobj = MyObj(NONSOURCE)
setattr(myobj, "foo", SOURCE)
SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo"
def test_setattr_getattr():
myobj = MyObj(NONSOURCE)
setattr(myobj, "foo", SOURCE)
SINK(getattr(myobj, "foo")) # $ flow="SOURCE, l:-1 -> getattr(..)"
def test_setattr_getattr_overwrite():
myobj = MyObj(NONSOURCE)
setattr(myobj, "foo", SOURCE)
setattr(myobj, "foo", NONSOURCE)
SINK_F(getattr(myobj, "foo"))
def test_constructor_assign():
obj = MyObj(SOURCE)
SINK(obj.foo) # $ flow="SOURCE, l:-1 -> obj.foo"
def test_constructor_assign_kw():
obj = MyObj(foo=SOURCE)
SINK(obj.foo) # $ flow="SOURCE, l:-1 -> obj.foo"
def fields_with_local_flow(x):
obj = MyObj(x)
a = obj.foo
return a
def test_fields():
SINK(fields_with_local_flow(SOURCE)) # $ flow="SOURCE -> fields_with_local_flow(..)"
# ------------------------------------------------------------------------------
# Nested Object
# ------------------------------------------------------------------------------
class NestedObj(object):
def __init__(self):
@@ -38,60 +147,103 @@ class NestedObj(object):
return self.obj
def setFoo(obj, x):
SINK_F(obj.foo)
obj.foo = x
def test_example1():
myobj = MyObj("OK")
setFoo(myobj, SOURCE)
SINK(myobj.foo)
def test_example1_method():
myobj = MyObj("OK")
myobj.setFoo(SOURCE)
SINK(myobj.foo)
def test_example2():
def test_nested_obj():
x = SOURCE
a = NestedObj()
a.obj.foo = x
SINK(a.obj.foo)
SINK(a.obj.foo) # $ flow="SOURCE, l:-3 -> a.obj.foo"
def test_example2_method():
def test_nested_obj_method():
x = SOURCE
a = NestedObj()
a.getObj().foo = x
SINK(a.obj.foo) # $ flow="SOURCE, l:-3 -> a.obj.foo"
SINK(a.obj.foo)
# ------------------------------------------------------------------------------
# Global scope
# ------------------------------------------------------------------------------
# since these are defined on global scope, and we still want to run them with
# `validTest.py`, we have them defined in a different file, and have hardcoded this
# number that reflects how many OK we expect to see ... Not an ideal solution, but at
# least we know that the tests are actually valid.
#
# Notice that since the tests are run in a random order, we cannot split the global
# scope tests into multiple functions, since we wouldn't know which one did the initial
# import that does all the printing :|
@expects(18 + 2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
def test_global_scope():
import fieldflow.test_global
fieldflow.test_global.func_defined_before() # $ unresolved_call=fieldflow.test_global.func_defined_before()
fieldflow.test_global.func_defined_after() # $ unresolved_call=fieldflow.test_global.func_defined_after()
# ------------------------------------------------------------------------------
# Global flow cases that doesn't work in this file, but works in test_global.py
# ------------------------------------------------------------------------------
# --------------------------------------
# method calls _before_ those ifs
# --------------------------------------
# def test_indirect_assign_method():
myobj2 = MyObj("OK")
myobj2.setFoo(SOURCE)
SINK(myobj2.foo) # $ flow="SOURCE, l:-1 -> myobj2.foo"
# def test_nested_obj_method():
x2 = SOURCE
a2 = NestedObj()
a2.getObj().foo = x2
SINK(a2.obj.foo) # $ flow="SOURCE, l:-3 -> a2.obj.foo"
def test_example3():
obj = MyObj(SOURCE)
SINK(obj.foo)
# --------------------------------------
# using constructor
# --------------------------------------
# def test_constructor_assign():
obj2 = MyObj(SOURCE)
SINK(obj2.foo) # $ flow="SOURCE, l:-1 -> obj2.foo"
def test_example3_kw():
obj = MyObj(foo=SOURCE)
SINK(obj.foo)
# apparently these if statements below makes a difference :O
# but one is not enough
cond = os.urandom(1)[0] > 128
if cond:
pass
def fields_with_local_flow(x):
obj = MyObj(x)
a = obj.foo
return a
# def test_constructor_assign():
obj2 = MyObj(SOURCE)
SINK(obj2.foo) # $ flow="SOURCE, l:-1 -> obj2.foo"
if cond:
pass
def test_fields():
SINK(fields_with_local_flow(SOURCE))
# def test_constructor_assign():
obj2 = MyObj(SOURCE)
SINK(obj2.foo) # $ flow="SOURCE, l:-1 -> obj2.foo"
# def test_constructor_assign_kw():
obj3 = MyObj(foo=SOURCE)
SINK(obj3.foo) # $ flow="SOURCE, l:-1 -> obj3.foo"
# def test_fields():
SINK(fields_with_local_flow(SOURCE)) # $ flow="SOURCE -> fields_with_local_flow(..)"
# --------------------------------------
# method calls _after_ those ifs
# --------------------------------------
# def test_indirect_assign_method():
myobj2 = MyObj("OK")
myobj2.setFoo(SOURCE)
SINK(myobj2.foo) # $ flow="SOURCE, l:-1 -> myobj2.foo"
# def test_nested_obj_method():
x2 = SOURCE
a2 = NestedObj()
a2.getObj().foo = x2
SINK(a2.obj.foo) # $ flow="SOURCE, l:-3 -> a2.obj.foo"

View File

@@ -0,0 +1,179 @@
"""
This file contains a copy of the tests from `test.py` along with some cases that check
the interaction between global variables and assignment on global scope.
You might think that these are a bit useless since field-flow should work just the same
on global or non-global scope, but then you would be wrong!
"""
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
class MyObj(object):
def __init__(self, foo):
self.foo = foo
def setFoo(self, foo):
self.foo = foo
def setFoo(obj, x):
SINK_F(obj.foo)
obj.foo = x
# def test_indirect_assign():
myobj1 = MyObj("OK")
setFoo(myobj1, SOURCE)
SINK(myobj1.foo) # $ flow="SOURCE, l:-1 -> myobj1.foo"
# def test_indirect_assign_method():
myobj2 = MyObj("OK")
myobj2.setFoo(SOURCE)
SINK(myobj2.foo) # $ flow="SOURCE, l:-1 -> myobj2.foo"
# def test_direct_assign():
myobj3 = MyObj(NONSOURCE)
myobj3.foo = SOURCE
SINK(myobj3.foo) # $ flow="SOURCE, l:-1 -> myobj3.foo"
# def test_direct_assign_overwrite():
myobj4 = MyObj(NONSOURCE)
myobj4.foo = SOURCE
myobj4.foo = NONSOURCE
SINK_F(myobj4.foo)
# def test_direct_if_assign(cond = False):
# this way, our analysis isn't able to understand that `cond` is just False,
# and therefore isn't able to determine that the if below will not hold.
cond = eval("False")
myobj5 = MyObj(NONSOURCE)
myobj5.foo = SOURCE
if cond:
myobj5.foo = NONSOURCE
SINK_F(myobj5.foo)
# SPLITTING happens here, so in one version there is flow, and in the other there isn't
# that's why it has both a flow and a MISSING: flow annotation
SINK(myobj5.foo) # $ flow="SOURCE, l:-6 -> myobj5.foo" MISSING: flow
# def test_direct_if_always_assign(cond = True):
myobj6 = MyObj(NONSOURCE)
myobj6.foo = SOURCE
if cond:
myobj6.foo = NONSOURCE
SINK_F(myobj6.foo)
else:
myobj6.foo = NONSOURCE
SINK_F(myobj6.foo)
SINK_F(myobj6.foo)
# def test_getattr():
myobj7 = MyObj(NONSOURCE)
myobj7.foo = SOURCE
SINK(getattr(myobj7, "foo")) # $ flow="SOURCE, l:-1 -> getattr(..)"
# def test_setattr():
myobj8 = MyObj(NONSOURCE)
setattr(myobj8, "foo", SOURCE)
SINK(myobj8.foo) # $ flow="SOURCE, l:-1 -> myobj8.foo"
# def test_setattr_getattr():
myobj9 = MyObj(NONSOURCE)
setattr(myobj9, "foo", SOURCE)
SINK(getattr(myobj9, "foo")) # $ flow="SOURCE, l:-1 -> getattr(..)"
# def test_setattr_getattr_overwrite():
myobj10 = MyObj(NONSOURCE)
setattr(myobj10, "foo", SOURCE)
setattr(myobj10, "foo", NONSOURCE)
SINK_F(getattr(myobj10, "foo"))
# def test_constructor_assign():
obj2 = MyObj(SOURCE)
SINK(obj2.foo) # $ flow="SOURCE, l:-1 -> obj2.foo"
# def test_constructor_assign_kw():
obj3 = MyObj(foo=SOURCE)
SINK(obj3.foo) # $ flow="SOURCE, l:-1 -> obj3.foo"
def fields_with_local_flow(x):
obj0 = MyObj(x)
a0 = obj0.foo
return a0
# def test_fields():
SINK(fields_with_local_flow(SOURCE)) # $ flow="SOURCE -> fields_with_local_flow(..)"
# ------------------------------------------------------------------------------
# Nested Object
# ------------------------------------------------------------------------------
class NestedObj(object):
def __init__(self):
self.obj = MyObj("OK")
def getObj(self):
return self.obj
# def test_nested_obj():
x1 = SOURCE
a1 = NestedObj()
a1.obj.foo = x1
SINK(a1.obj.foo) # $ flow="SOURCE, l:-3 -> a1.obj.foo"
# def test_nested_obj_method():
x2 = SOURCE
a2 = NestedObj()
a2.getObj().foo = x2
SINK(a2.obj.foo) # $ flow="SOURCE, l:-3 -> a2.obj.foo"
# ------------------------------------------------------------------------------
# Global scope interaction
# ------------------------------------------------------------------------------
def func_defined_before():
SINK(global_obj.foo) # $ MISSING: flow="SOURCE, l:+3 -> global_obj.foo"
global_obj = MyObj(NONSOURCE)
global_obj.foo = SOURCE
SINK(global_obj.foo) # $ flow="SOURCE, l:-1 -> global_obj.foo"
def func_defined_after():
SINK(global_obj.foo) # $ MISSING: flow="SOURCE, l:-4 -> global_obj.foo"

View File

@@ -0,0 +1,2 @@
missingAnnotationOnSINK
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.NormalDataflowTest

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -1,13 +0,0 @@
import python
import experimental.dataflow.TestUtil.FlowTest
import experimental.dataflow.testConfig
class DataFlowTest extends FlowTest {
DataFlowTest() { this = "DataFlowTest" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
}
}

View File

@@ -3,7 +3,7 @@ import sys
import os
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
from testlib import *
from testlib import expects
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
@@ -48,8 +48,8 @@ def test_or_pattern():
# No flow for literal pattern
def test_literal_pattern():
match SOURCE:
case 42 as x:
SINK(x) #$ flow="SOURCE, l:-2 -> x" flow="42, l:-1 -> x"
case "source" as x:
SINK(x) #$ flow="SOURCE, l:-2 -> x" flow="'source', l:-1 -> x"
def test_capture_pattern():
match SOURCE:

View File

@@ -2,7 +2,7 @@ import sys #$ importTimeFlow="ImportExpr -> GSSA Variable sys"
import os #$ importTimeFlow="ImportExpr -> GSSA Variable os"
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
from testlib import *
from testlib import expects #$ importTimeFlow="ImportMember -> GSSA Variable expects"
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source" #$ importTimeFlow="'not a source' -> GSSA Variable NONSOURCE"

View File

@@ -0,0 +1,3 @@
Sometimes we accidentally re-export too much from `DataFlow` such that for example we can access `Add` from `DataFlow::Add` :disappointed:
This test should always FAIL to compile!

View File

@@ -0,0 +1 @@
ERROR: Could not resolve type DataFlow::Add (Test.ql:7,6-19)

View File

@@ -0,0 +1,8 @@
import python
private import semmle.python.dataflow.new.DataFlow
// Sometimes we accidentally re-export too much from `DataFlow` such that for example we can access `Add` from `DataFlow::Add` :(
//
// This test should always FAIL to compile!
from DataFlow::Add this_should_not_work
select this_should_not_work

View File

@@ -0,0 +1 @@
1+1

View File

@@ -0,0 +1,96 @@
While working on the field-flow tests, I encountered some very strange behavior. By moving some tests into a new file, they suddenly started working :O
This folder contains the artifacts from investigating this problem, so we can recall the facts (but besides that, don't have much value in itself).
The test files can be found in `src/`, and I have set of a bunch of different tests with different extractor options in the `test-*` folders.
The core of the problem is that in _some_ configuration of extractor options, after seeing the code below, points-to gives up trying to resolve calls :flushed:
```py
import os
cond = os.urandom(1)[0] > 128
if cond:
pass
if cond:
pass
```
This seems to have been caused by not allowing enough imports to be resolved. There is also some interaction with splitting, since turning that off also removes the problem.
But allowing our test to see more imports is more representative of what happens when analyzing real code, so that's the better approach :+1: (and going above 3 does not seem to change anything in this case).
I've thought about whether we can write a query to reliably cases such as this, but I don't see any solutions. However, we can easily try running all our tests with `--max-import-depth=100` and see if anything changes from this.
# Seeing the solutions work
Doing `diff -u -r test-1-normal/ test-5-max-import-depth-3/` shows that all the calls we should be able to resolve, are now resolved properly. and critically this line is added:
```diff
+| ../src/urandom_problem.py:43:6:43:8 | ControlFlowNode for foo | Fixed missing result:flow="SOURCE, l:-15 -> foo" |
```
<details>
<summary>full diff</summary>
```diff
diff '--color=auto' -u -r test-1-normal/NormalDataflowTest.expected test-5-max-import-depth-3/NormalDataflowTest.expected
--- test-1-normal/NormalDataflowTest.expected 2022-02-27 10:33:00.603882599 +0100
+++ test-5-max-import-depth-3/NormalDataflowTest.expected 2022-02-28 10:10:08.930743800 +0100
@@ -1,2 +1,3 @@
missingAnnotationOnSINK
failures
+| ../src/urandom_problem.py:43:6:43:8 | ControlFlowNode for foo | Fixed missing result:flow="SOURCE, l:-15 -> foo" |
diff '--color=auto' -u -r test-1-normal/options test-5-max-import-depth-3/options
--- test-1-normal/options 2022-02-27 10:36:51.124793909 +0100
+++ test-5-max-import-depth-3/options 2022-02-27 11:01:43.908098372 +0100
@@ -1 +1 @@
-semmle-extractor-options: --max-import-depth=1 -R ../src
+semmle-extractor-options: --max-import-depth=3 -R ../src
diff '--color=auto' -u -r test-1-normal/UnresolvedCalls.expected test-5-max-import-depth-3/UnresolvedCalls.expected
--- test-1-normal/UnresolvedCalls.expected 2022-02-28 10:09:19.213742437 +0100
+++ test-5-max-import-depth-3/UnresolvedCalls.expected 2022-02-28 10:10:08.638737921 +0100
@@ -0,0 +1,5 @@
+| ../src/isfile_no_problem.py:34:33:34:70 | Comment # $ unresolved_call=os.path.isfile(..) | Missing result:unresolved_call=os.path.isfile(..) |
+| ../src/urandom_no_if_no_problem.py:34:31:34:64 | Comment # $ unresolved_call=os.urandom(..) | Missing result:unresolved_call=os.urandom(..) |
+| ../src/urandom_problem.py:34:31:34:64 | Comment # $ unresolved_call=os.urandom(..) | Missing result:unresolved_call=os.urandom(..) |
+| ../src/urandom_problem.py:42:18:42:47 | Comment # $ unresolved_call=give_src() | Missing result:unresolved_call=give_src() |
+| ../src/urandom_problem.py:43:11:43:75 | Comment # $ unresolved_call=SINK(..) MISSING: flow="SOURCE, l:-15 -> foo" | Missing result:unresolved_call=SINK(..) |
diff '--color=auto' -u -r test-1-normal/UnresolvedPointsToCalls.expected test-5-max-import-depth-3/UnresolvedPointsToCalls.expected
--- test-1-normal/UnresolvedPointsToCalls.expected 2022-02-28 10:09:19.033738812 +0100
+++ test-5-max-import-depth-3/UnresolvedPointsToCalls.expected 2022-02-28 10:12:48.572752108 +0100
@@ -1,5 +1 @@
-| ../src/urandom_no_if_no_problem.py:34:8:34:20 | ../src/urandom_no_if_no_problem.py:34 | os.urandom(..) |
| ../src/urandom_no_import_no_problem.py:34:8:34:20 | ../src/urandom_no_import_no_problem.py:34 | os.urandom(..) |
-| ../src/urandom_problem.py:34:8:34:20 | ../src/urandom_problem.py:34 | os.urandom(..) |
-| ../src/urandom_problem.py:42:7:42:16 | ../src/urandom_problem.py:42 | give_src() |
-| ../src/urandom_problem.py:43:1:43:9 | ../src/urandom_problem.py:43 | SINK(..) |
```
</details>
There are no benefit in increasing import depth above 3 for this test-example:
```diff
$ diff -u -r test-4-max-import-depth-100/ test-5-max-import-depth-3/
--- test-4-max-import-depth-100/options 2022-02-28 10:02:09.269071781 +0100
+++ test-5-max-import-depth-3/options 2022-02-27 11:01:43.908098372 +0100
@@ -1 +1 @@
-semmle-extractor-options: --max-import-depth=100 -R ../src
+semmle-extractor-options: --max-import-depth=3 -R ../src
```
Also notice that using import depth 2 actually makes things worse, as we no longer handle the `isfile_no_problem.py` file properly :facepalm: :sweat_smile: NOTE: This was only for Python 3, for Python 2 there was no change :flushed:
```diff
diff '--color=auto' -u -r test-4-max-import-depth-100/NormalDataflowTest.expected test-6-max-import-depth-2/NormalDataflowTest.expected
--- test-4-max-import-depth-100/NormalDataflowTest.expected 2022-02-28 10:10:02.206608379 +0100
+++ test-6-max-import-depth-2/NormalDataflowTest.expected 2022-02-28 10:10:13.882716665 +0100
@@ -1,3 +1,5 @@
missingAnnotationOnSINK
+| ../src/isfile_no_problem.py:43:6:43:8 | ../src/isfile_no_problem.py:43 | ERROR, you should add `# $ MISSING: flow` annotation | foo |
failures
+| ../src/isfile_no_problem.py:43:11:43:41 | Comment # $ flow="SOURCE, l:-15 -> foo" | Missing result:flow="SOURCE, l:-15 -> foo" |
| ../src/urandom_problem.py:43:6:43:8 | ControlFlowNode for foo | Fixed missing result:flow="SOURCE, l:-15 -> foo" |
```

View File

@@ -0,0 +1,43 @@
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
def give_src():
return SOURCE
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-3 -> foo"
import os
cond = eval("False")
if cond:
pass
if cond:
pass
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-15 -> foo"

View File

@@ -0,0 +1,43 @@
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
def give_src():
return SOURCE
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-3 -> foo"
import os
cond = os.path.isfile(__file__) # $ unresolved_call=os.path.isfile(..)
if cond:
pass
if cond:
pass
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-15 -> foo"

View File

@@ -0,0 +1,43 @@
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
def give_src():
return SOURCE
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-3 -> foo"
import os
cond = 1 + 1 == 2
if cond:
pass
if cond:
pass
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-15 -> foo"

View File

@@ -0,0 +1,43 @@
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
def give_src():
return SOURCE
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-3 -> foo"
import os
cond = os.urandom(1)[0] > 128 # $ unresolved_call=os.urandom(..)
# if cond:
# pass
#
# if cond:
# pass
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-15 -> foo"

View File

@@ -0,0 +1,43 @@
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
def give_src():
return SOURCE
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-3 -> foo"
# import os
cond = os.urandom(1)[0] > 128 # $ unresolved_call=os.urandom(..)
# if cond:
# pass
#
# if cond:
# pass
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-15 -> foo"

View File

@@ -0,0 +1,43 @@
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# ------------------------------------------------------------------------------
# Actual tests
# ------------------------------------------------------------------------------
def give_src():
return SOURCE
foo = give_src()
SINK(foo) # $ flow="SOURCE, l:-3 -> foo"
import os
cond = os.urandom(1)[0] > 128 # $ unresolved_call=os.urandom(..)
if cond:
pass
if cond:
pass
foo = give_src() # $ unresolved_call=give_src()
SINK(foo) # $ unresolved_call=SINK(..) MISSING: flow="SOURCE, l:-15 -> foo"

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.NormalDataflowTest

View File

@@ -0,0 +1,6 @@
| ../src/eval_no_problem.py | has splitting |
| ../src/isfile_no_problem.py | has splitting |
| ../src/simple_no_problem.py | has splitting |
| ../src/urandom_no_if_no_problem.py | does not have splitting |
| ../src/urandom_no_import_no_problem.py | does not have splitting |
| ../src/urandom_problem.py | has splitting |

View File

@@ -0,0 +1,16 @@
import python
// this can be quick-eval to see which ones have splitting. But that's basically just
// anything from line 39 and further.
predicate exprWithSplitting(Expr e) {
exists(e.getLocation().getFile().getRelativePath()) and
1 < count(ControlFlowNode cfn | cfn.getNode() = e)
}
from File f, string msg
where
exists(f.getRelativePath()) and
if exists(Expr e | e.getLocation().getFile() = f and exprWithSplitting(e))
then msg = "has splitting"
else msg = "does not have splitting"
select f.toString(), msg

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.UnresolvedCalls

View File

@@ -0,0 +1,5 @@
| ../src/urandom_no_if_no_problem.py:34:8:34:20 | ../src/urandom_no_if_no_problem.py:34 | os.urandom(..) |
| ../src/urandom_no_import_no_problem.py:34:8:34:20 | ../src/urandom_no_import_no_problem.py:34 | os.urandom(..) |
| ../src/urandom_problem.py:34:8:34:20 | ../src/urandom_problem.py:34 | os.urandom(..) |
| ../src/urandom_problem.py:42:7:42:16 | ../src/urandom_problem.py:42 | give_src() |
| ../src/urandom_problem.py:43:1:43:9 | ../src/urandom_problem.py:43 | SINK(..) |

View File

@@ -0,0 +1,10 @@
import python
private import semmle.python.dataflow.new.internal.PrintNode
from CallNode call
where
exists(call.getLocation().getFile().getRelativePath()) and
not exists(Value value | call = value.getACall()) and
// somehow print is not resolved, but that is not the focus right now
not call.getFunction().(NameNode).getId() = "print"
select call.getLocation(), prettyExpr(call.getNode())

View File

@@ -0,0 +1 @@
semmle-extractor-options: --lang=3 --max-import-depth=1 -R ../src

View File

@@ -0,0 +1,3 @@
missingAnnotationOnSINK
failures
| ../src/urandom_problem.py:43:6:43:8 | ControlFlowNode for foo | Fixed missing result:flow="SOURCE, l:-15 -> foo" |

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.NormalDataflowTest

View File

@@ -0,0 +1,6 @@
| ../src/eval_no_problem.py | does not have splitting |
| ../src/isfile_no_problem.py | does not have splitting |
| ../src/simple_no_problem.py | does not have splitting |
| ../src/urandom_no_if_no_problem.py | does not have splitting |
| ../src/urandom_no_import_no_problem.py | does not have splitting |
| ../src/urandom_problem.py | does not have splitting |

View File

@@ -0,0 +1,16 @@
import python
// this can be quick-eval to see which ones have splitting. But that's basically just
// anything from line 39 and further.
predicate exprWithSplitting(Expr e) {
exists(e.getLocation().getFile().getRelativePath()) and
1 < count(ControlFlowNode cfn | cfn.getNode() = e)
}
from File f, string msg
where
exists(f.getRelativePath()) and
if exists(Expr e | e.getLocation().getFile() = f and exprWithSplitting(e))
then msg = "has splitting"
else msg = "does not have splitting"
select f.toString(), msg

View File

@@ -0,0 +1,2 @@
| ../src/urandom_problem.py:42:18:42:47 | Comment # $ unresolved_call=give_src() | Missing result:unresolved_call=give_src() |
| ../src/urandom_problem.py:43:11:43:75 | Comment # $ unresolved_call=SINK(..) MISSING: flow="SOURCE, l:-15 -> foo" | Missing result:unresolved_call=SINK(..) |

View File

@@ -0,0 +1,2 @@
import python
import experimental.dataflow.TestUtil.UnresolvedCalls

View File

@@ -0,0 +1,3 @@
| ../src/urandom_no_if_no_problem.py:34:8:34:20 | ../src/urandom_no_if_no_problem.py:34 | os.urandom(..) |
| ../src/urandom_no_import_no_problem.py:34:8:34:20 | ../src/urandom_no_import_no_problem.py:34 | os.urandom(..) |
| ../src/urandom_problem.py:34:8:34:20 | ../src/urandom_problem.py:34 | os.urandom(..) |

View File

@@ -0,0 +1,10 @@
import python
private import semmle.python.dataflow.new.internal.PrintNode
from CallNode call
where
exists(call.getLocation().getFile().getRelativePath()) and
not exists(Value value | call = value.getACall()) and
// somehow print is not resolved, but that is not the focus right now
not call.getFunction().(NameNode).getId() = "print"
select call.getLocation(), prettyExpr(call.getNode())

View File

@@ -0,0 +1 @@
semmle-extractor-options: --lang=3 --dont-split-graph --max-import-depth=1 -R ../src

View File

@@ -0,0 +1,3 @@
missingAnnotationOnSINK
failures
| ../src/urandom_problem.py:43:6:43:8 | ControlFlowNode for foo | Fixed missing result:flow="SOURCE, l:-15 -> foo" |

Some files were not shown because too many files have changed in this diff Show More