Skip to content

Commit 8b78b6b

Browse files
committed
Python: Add inline tests
Nodes to which we track type tracking flow from the source (any identifier named `tracked`) are indicated with a `$tracked` tag, and `$tracked=attr_name` if the attribute is for the specified attribute of the given node. For nodes that do have flow from `tracked`, I indicate this in one of two ways: - If it's expected due to the design of type tracking, I omit the `$tracked tag. - If it's flow that _ought_ to be there, I indicate it as a false negative: `$f-:tracked` Currently, only an instance of global flow is in the latter category.
1 parent fbe8b64 commit 8b78b6b

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
def simple_read_write():
2+
x = object() # $tracked=foo
3+
x.foo = tracked # $tracked $tracked=foo
4+
y = x.foo # $tracked=foo $tracked
5+
do_stuff(y) # $tracked
6+
7+
def foo():
8+
x = object() # $tracked=attr
9+
bar(x) # $tracked=attr
10+
x.attr = tracked # $tracked=attr $tracked
11+
baz(x) # $tracked=attr
12+
13+
def bar(x): # $tracked=attr
14+
z = x.attr # $tracked $tracked=attr
15+
do_stuff(z) # $tracked
Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,49 @@
11
def get_tracked():
2-
x = tracked
3-
return x
2+
x = tracked # $tracked
3+
return x # $tracked
44

5-
def use_tracked(x):
6-
do_stuff(x)
5+
def use_tracked_foo(x): # $tracked
6+
do_stuff(x) # $tracked
77

88
def foo():
9-
use_tracked(get_tracked())
9+
use_tracked_foo(
10+
get_tracked() # $tracked
11+
)
12+
13+
def use_tracked_bar(x): # $tracked
14+
do_stuff(x) # $tracked
1015

1116
def bar():
12-
x = get_tracked()
13-
use_tracked(x)
17+
x = get_tracked() # $tracked
18+
use_tracked_bar(x) # $tracked
19+
20+
def use_tracked_baz(x): # $tracked
21+
do_stuff(x) # $tracked
1422

1523
def baz():
16-
x = tracked
17-
use_tracked(x)
24+
x = tracked # $tracked
25+
use_tracked_baz(x) # $tracked
26+
27+
def id(x): # $tracked
28+
return x # $tracked
29+
30+
def use_tracked_quux(x): # $f-:tracked
31+
do_stuff(y) # call after return -- not tracked in here.
32+
33+
def quux():
34+
x = tracked # $tracked
35+
y = id(x) # $tracked
36+
use_tracked_quux(y) # not tracked out of call to id.
37+
38+
g = None
39+
40+
def write_g(x): # $tracked
41+
g = x # $tracked
42+
43+
def use_g():
44+
do_stuff(g) # $f-:tracked // no global flow for now.
1845

19-
foo()
20-
bar()
21-
baz()
46+
def global_var_write_test():
47+
x = tracked # $tracked
48+
write_g(x) # $tracked
49+
use_g()

python/ql/test/experimental/dataflow/typetracking/tracked.expected

Whitespace-only changes.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import python
2+
import experimental.dataflow.TypeTracker
3+
import TestUtilities.InlineExpectationsTest
4+
5+
Node tracked(TypeTracker t) {
6+
t.start() and
7+
result.asCfgNode() = any(NameNode n | n.getId() = "tracked")
8+
or
9+
exists(TypeTracker t2 | result = tracked(t2).track(t2, t))
10+
}
11+
12+
class TrackedTest extends InlineExpectationsTest {
13+
TrackedTest() { this = "TrackedTest" }
14+
15+
override string getARelevantTag() { result = "tracked" }
16+
17+
override predicate hasActualResult(Location location, string element, string tag, string value) {
18+
exists(Node e, TypeTracker t |
19+
e = tracked(t) and
20+
tag = "tracked" and
21+
location = e.getLocation() and
22+
value = t.getProp() and
23+
element = e.toString()
24+
)
25+
}
26+
}

0 commit comments

Comments
 (0)