Skip to content

Commit 3547c70

Browse files
committed
Python: Add tests with redefinition of fields/variables
1 parent 06103f4 commit 3547c70

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed
Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
1+
class SomeClass:
2+
pass
3+
14
def simple_read_write():
2-
x = object() # $tracked=foo
5+
x = SomeClass() # $tracked=foo
36
x.foo = tracked # $tracked $tracked=foo
47
y = x.foo # $tracked=foo $tracked
58
do_stuff(y) # $tracked
69

710
def foo():
8-
x = object() # $tracked=attr
11+
x = SomeClass() # $tracked=attr
912
bar(x) # $tracked=attr
1013
x.attr = tracked # $tracked=attr $tracked
1114
baz(x) # $tracked=attr
1215

1316
def bar(x): # $tracked=attr
1417
z = x.attr # $tracked $tracked=attr
15-
do_stuff(z) # $tracked
18+
do_stuff(z) # $tracked
19+
20+
def expects_int(x): # $int=field $f+:str=field
21+
do_int_stuff(x.field) # $int $f+:str $int=field $f+:str=field
22+
23+
def expects_string(x): # $f+:int=field $str=field
24+
do_string_stuff(x.field) # $f+:int $str $f+:int=field $str=field
25+
26+
def test_incompatible_types():
27+
x = SomeClass() # $int,str=field
28+
x.field = int(5) # $int=field $f+:str=field $int $f+:str
29+
expects_int(x) # $int=field $f+:str=field
30+
x.field = str("Hello") # $f+:int=field $str=field $f+:int $str
31+
expects_string(x) # $f+:int=field $str=field

python/ql/test/experimental/dataflow/typetracking/test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,15 @@ def global_var_write_test():
4747
x = tracked # $tracked
4848
write_g(x) # $tracked
4949
use_g()
50+
51+
def expects_int(x): # $int
52+
do_int_stuff(x) # $int
53+
54+
def expects_string(x): # $str
55+
do_string_stuff(x) # $str
56+
57+
def redefine_test():
58+
x = int(5) # $int
59+
expects_int(x) # $int
60+
x = str("Hello") # $str
61+
expects_string(x) # $str

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,53 @@ class TrackedTest extends InlineExpectationsTest {
1919
e = tracked(t) and
2020
tag = "tracked" and
2121
location = e.getLocation() and
22-
value = t.getProp() and
22+
value = t.getAttr() and
23+
element = e.toString()
24+
)
25+
}
26+
}
27+
28+
Node int_type(TypeTracker t) {
29+
t.start() and
30+
result.asCfgNode() = any(CallNode c | c.getFunction().(NameNode).getId() = "int")
31+
or
32+
exists(TypeTracker t2 | result = int_type(t2).track(t2, t))
33+
}
34+
35+
Node string_type(TypeTracker t) {
36+
t.start() and
37+
result.asCfgNode() = any(CallNode c | c.getFunction().(NameNode).getId() = "str")
38+
or
39+
exists(TypeTracker t2 | result = string_type(t2).track(t2, t))
40+
}
41+
42+
class TrackedIntTest extends InlineExpectationsTest {
43+
TrackedIntTest() { this = "TrackedIntTest" }
44+
45+
override string getARelevantTag() { result = "int" }
46+
47+
override predicate hasActualResult(Location location, string element, string tag, string value) {
48+
exists(Node e, TypeTracker t |
49+
e = int_type(t) and
50+
tag = "int" and
51+
location = e.getLocation() and
52+
value = t.getAttr() and
53+
element = e.toString()
54+
)
55+
}
56+
}
57+
58+
class TrackedStringTest extends InlineExpectationsTest {
59+
TrackedStringTest() { this = "TrackedStringTest" }
60+
61+
override string getARelevantTag() { result = "str" }
62+
63+
override predicate hasActualResult(Location location, string element, string tag, string value) {
64+
exists(Node e, TypeTracker t |
65+
e = string_type(t) and
66+
tag = "str" and
67+
location = e.getLocation() and
68+
value = t.getAttr() and
2369
element = e.toString()
2470
)
2571
}

0 commit comments

Comments
 (0)