mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge branch 'main' into py/CsvInjection
This commit is contained in:
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
135
python/ql/test/TestUtilities/VerifyApiGraphs.qll
Normal file
135
python/ql/test/TestUtilities/VerifyApiGraphs.qll
Normal 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() }
|
||||
2
python/ql/test/experimental/attrs/AttrReads.expected
Normal file
2
python/ql/test/experimental/attrs/AttrReads.expected
Normal 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 |
|
||||
5
python/ql/test/experimental/attrs/AttrReads.ql
Normal file
5
python/ql/test/experimental/attrs/AttrReads.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::AttrRead read
|
||||
select read, read.getObject(), read.getAttributeName()
|
||||
4
python/ql/test/experimental/attrs/AttrWrites.expected
Normal file
4
python/ql/test/experimental/attrs/AttrWrites.expected
Normal 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 |
|
||||
5
python/ql/test/experimental/attrs/AttrWrites.ql
Normal file
5
python/ql/test/experimental/attrs/AttrWrites.ql
Normal 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()
|
||||
13
python/ql/test/experimental/attrs/test.py
Normal file
13
python/ql/test/experimental/attrs/test.py
Normal 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")
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
foo = 42
|
||||
@@ -1 +0,0 @@
|
||||
pass
|
||||
@@ -1 +0,0 @@
|
||||
pass
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
37
python/ql/test/experimental/dataflow/calls/test.py
Normal file
37
python/ql/test/experimental/dataflow/calls/test.py
Normal 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
|
||||
@@ -0,0 +1,2 @@
|
||||
missingAnnotationOnSINK
|
||||
failures
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.NormalDataflowTest
|
||||
@@ -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(
|
||||
|
||||
@@ -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 |
|
||||
@@ -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"
|
||||
@@ -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 |
|
||||
@@ -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"
|
||||
@@ -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 |
|
||||
@@ -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"
|
||||
@@ -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 |
|
||||
@@ -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"
|
||||
@@ -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 |
|
||||
@@ -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"
|
||||
@@ -1,4 +0,0 @@
|
||||
edges
|
||||
nodes
|
||||
subpaths
|
||||
#select
|
||||
@@ -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"
|
||||
@@ -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 |
|
||||
@@ -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"
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
missingAnnotationOnSINK
|
||||
failures
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.NormalDataflowTest
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.UnresolvedCalls
|
||||
@@ -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 |
|
||||
@@ -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
|
||||
@@ -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 |
|
||||
@@ -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"
|
||||
@@ -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))
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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 |
|
||||
@@ -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
|
||||
1
python/ql/test/experimental/dataflow/fieldflow/options
Normal file
1
python/ql/test/experimental/dataflow/fieldflow/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --max-import-depth=3
|
||||
@@ -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 |
|
||||
@@ -1,4 +0,0 @@
|
||||
import experimental.dataflow.testConfig
|
||||
|
||||
from DataFlow::PostUpdateNode pun
|
||||
select pun, pun.getPreUpdateNode()
|
||||
@@ -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"
|
||||
|
||||
179
python/ql/test/experimental/dataflow/fieldflow/test_global.py
Normal file
179
python/ql/test/experimental/dataflow/fieldflow/test_global.py
Normal 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"
|
||||
@@ -0,0 +1,2 @@
|
||||
missingAnnotationOnSINK
|
||||
failures
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.NormalDataflowTest
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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!
|
||||
@@ -0,0 +1 @@
|
||||
ERROR: Could not resolve type DataFlow::Add (Test.ql:7,6-19)
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
1+1
|
||||
@@ -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" |
|
||||
```
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -0,0 +1,2 @@
|
||||
missingAnnotationOnSINK
|
||||
failures
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.NormalDataflowTest
|
||||
@@ -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 |
|
||||
@@ -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
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.UnresolvedCalls
|
||||
@@ -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(..) |
|
||||
@@ -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())
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=3 --max-import-depth=1 -R ../src
|
||||
@@ -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" |
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.NormalDataflowTest
|
||||
@@ -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 |
|
||||
@@ -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
|
||||
@@ -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(..) |
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.UnresolvedCalls
|
||||
@@ -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(..) |
|
||||
@@ -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())
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=3 --dont-split-graph --max-import-depth=1 -R ../src
|
||||
@@ -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
Reference in New Issue
Block a user