diff --git a/source/interprocedural_analyses/taint/test/integration/heap_alias.py b/source/interprocedural_analyses/taint/test/integration/heap_alias.py new file mode 100644 index 0000000000..e60b7fb3f8 --- /dev/null +++ b/source/interprocedural_analyses/taint/test/integration/heap_alias.py @@ -0,0 +1,21 @@ +from builtins import _test_sink, _test_source + +class Node: + def __init__(self, val=None): + self.val = val + self.next = None + +def linked_list_pattern(x): + b = Node(x) + c = Node() + d = Node() + + d.next = c + c.next = b + e = d.next.next.val + + _test_sink(e) # false negative + + # Pysa treats memory as flat and doesn't understand aliases. + # It fails to recognize that `d.next` -> `c` and `c.next` -> `b`, + # so it misses that `e` (i.e., `d.next.next.val`) is derived from `x`. diff --git a/source/interprocedural_analyses/taint/test/integration/heap_alias.py.pysa b/source/interprocedural_analyses/taint/test/integration/heap_alias.py.pysa new file mode 100644 index 0000000000..af7c95aa85 --- /dev/null +++ b/source/interprocedural_analyses/taint/test/integration/heap_alias.py.pysa @@ -0,0 +1,3 @@ +def _test_sink(arg: TaintSink[Test, Via[special_sink]]): ... + +def _test_source() -> TaintSource[Test, Via[special_source]]: ...