mirror of
https://github.com/github/codeql.git
synced 2026-05-03 20:58:03 +02:00
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:
@@ -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
|
||||
@@ -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()
|
||||
|
||||
26
python/ql/test/experimental/dataflow/typetracking/tracked.ql
Normal file
26
python/ql/test/experimental/dataflow/typetracking/tracked.ql
Normal 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()
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user