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.
This commit is contained in:
Taus Brock-Nannestad
2020-08-28 19:55:52 +02:00
parent fbe8b64dd4
commit 8b78b6b1dc
4 changed files with 81 additions and 12 deletions

View File

@@ -0,0 +1,15 @@
def simple_read_write():
x = object() # $tracked=foo
x.foo = tracked # $tracked $tracked=foo
y = x.foo # $tracked=foo $tracked
do_stuff(y) # $tracked
def foo():
x = object() # $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

View File

@@ -1,21 +1,49 @@
def get_tracked():
x = tracked
return x
x = tracked # $tracked
return x # $tracked
def use_tracked(x):
do_stuff(x)
def use_tracked_foo(x): # $tracked
do_stuff(x) # $tracked
def foo():
use_tracked(get_tracked())
use_tracked_foo(
get_tracked() # $tracked
)
def use_tracked_bar(x): # $tracked
do_stuff(x) # $tracked
def bar():
x = get_tracked()
use_tracked(x)
x = get_tracked() # $tracked
use_tracked_bar(x) # $tracked
def use_tracked_baz(x): # $tracked
do_stuff(x) # $tracked
def baz():
x = tracked
use_tracked(x)
x = tracked # $tracked
use_tracked_baz(x) # $tracked
foo()
bar()
baz()
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()

View File

@@ -0,0 +1,26 @@
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.getProp() and
element = e.toString()
)
}
}