Merge pull request #3961 from tausbn/python-add-typetracker

Python: Add type tracker and step summary implementation.
This commit is contained in:
Calum Grant
2020-09-02 09:42:14 +01:00
committed by GitHub
6 changed files with 455 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
class SomeClass:
pass
def simple_read_write():
x = SomeClass() # $tracked=foo
x.foo = tracked # $tracked $tracked=foo
y = x.foo # $tracked=foo $tracked
do_stuff(y) # $tracked
def foo():
x = SomeClass() # $tracked=attr
bar(x) # $tracked=attr
x.attr = tracked # $tracked=attr $tracked
baz(x) # $tracked=attr
def bar(x): # $tracked=attr
z = x.attr # $tracked $tracked=attr
do_stuff(z) # $tracked
def expects_int(x): # $int=field $f+:str=field
do_int_stuff(x.field) # $int $f+:str $int=field $f+:str=field
def expects_string(x): # $f+:int=field $str=field
do_string_stuff(x.field) # $f+:int $str $f+:int=field $str=field
def test_incompatible_types():
x = SomeClass() # $int,str=field
x.field = int(5) # $int=field $f+:str=field $int $f+:str
expects_int(x) # $int=field $f+:str=field
x.field = str("Hello") # $f+:int=field $str=field $f+:int $str
expects_string(x) # $f+:int=field $str=field

View File

@@ -0,0 +1,61 @@
def get_tracked():
x = tracked # $tracked
return x # $tracked
def use_tracked_foo(x): # $tracked
do_stuff(x) # $tracked
def foo():
use_tracked_foo(
get_tracked() # $tracked
)
def use_tracked_bar(x): # $tracked
do_stuff(x) # $tracked
def bar():
x = get_tracked() # $tracked
use_tracked_bar(x) # $tracked
def use_tracked_baz(x): # $tracked
do_stuff(x) # $tracked
def baz():
x = tracked # $tracked
use_tracked_baz(x) # $tracked
def id(x): # $tracked
return x # $tracked
def use_tracked_quux(x): # $f-:tracked
do_stuff(y) # call after return -- not tracked in here.
def quux():
x = tracked # $tracked
y = id(x) # $tracked
use_tracked_quux(y) # not tracked out of call to id.
g = None
def write_g(x): # $tracked
g = x # $tracked
def use_g():
do_stuff(g) # $f-:tracked // no global flow for now.
def global_var_write_test():
x = tracked # $tracked
write_g(x) # $tracked
use_g()
def expects_int(x): # $int
do_int_stuff(x) # $int
def expects_string(x): # $str
do_string_stuff(x) # $str
def redefine_test():
x = int(5) # $int
expects_int(x) # $int
x = str("Hello") # $str
expects_string(x) # $str

View File

@@ -0,0 +1,72 @@
import python
import experimental.dataflow.TypeTracker
import TestUtilities.InlineExpectationsTest
Node tracked(TypeTracker t) {
t.start() and
result.asCfgNode() = any(NameNode n | n.getId() = "tracked")
or
exists(TypeTracker t2 | result = tracked(t2).track(t2, t))
}
class TrackedTest extends InlineExpectationsTest {
TrackedTest() { this = "TrackedTest" }
override string getARelevantTag() { result = "tracked" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node e, TypeTracker t |
e = tracked(t) and
tag = "tracked" and
location = e.getLocation() and
value = t.getAttr() and
element = e.toString()
)
}
}
Node int_type(TypeTracker t) {
t.start() and
result.asCfgNode() = any(CallNode c | c.getFunction().(NameNode).getId() = "int")
or
exists(TypeTracker t2 | result = int_type(t2).track(t2, t))
}
Node string_type(TypeTracker t) {
t.start() and
result.asCfgNode() = any(CallNode c | c.getFunction().(NameNode).getId() = "str")
or
exists(TypeTracker t2 | result = string_type(t2).track(t2, t))
}
class TrackedIntTest extends InlineExpectationsTest {
TrackedIntTest() { this = "TrackedIntTest" }
override string getARelevantTag() { result = "int" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node e, TypeTracker t |
e = int_type(t) and
tag = "int" and
location = e.getLocation() and
value = t.getAttr() and
element = e.toString()
)
}
}
class TrackedStringTest extends InlineExpectationsTest {
TrackedStringTest() { this = "TrackedStringTest" }
override string getARelevantTag() { result = "str" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node e, TypeTracker t |
e = string_type(t) and
tag = "str" and
location = e.getLocation() and
value = t.getAttr() and
element = e.toString()
)
}
}