From 09de1bcf44b2d308dbbd82142c3693844f1847fe Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 8 Jun 2021 18:51:37 +0200 Subject: [PATCH 1/5] Python: Add tests for type-tracking attrs on instances --- .../dataflow/typetracking/attribute_tests.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py index af8fe9bd4e3..41eecb591a5 100644 --- a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py +++ b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py @@ -99,3 +99,39 @@ def dunder_dict_indirect_read(): do_stuff(y) # $ MISSING: tracked +# ------------------------------------------------------------------------------ +# Tracking of attribute on class instance +# ------------------------------------------------------------------------------ + +# attribute set in method +# inspired by https://github.com/github/codeql/pull/6023 +class MyClass2(object): + def __init__(self): # $ tracked=foo + self.foo = tracked # $ tracked=foo tracked + + def print_foo(self): # $ MISSING: tracked=foo + print(self.foo) # $ MISSING: tracked=foo tracked + + def possibly_uncalled_method(self): + print(self.foo) # $ MISSING: tracked + +instance = MyClass2() +print(instance.foo) # $ MISSING: tracked=foo tracked +instance.print_foo() # $ MISSING: tracked=foo + + +# attribute set from outside of class +class MyClass3(object): + def print_self(self): # $ tracked=foo + print(self) # $ tracked=foo + + def print_foo(self): # $ tracked=foo + print(self.foo) # $ tracked=foo tracked + + def possibly_uncalled_method(self): + print(self.foo) # $ MISSING: tracked + +instance = MyClass3() # $ tracked=foo +instance.print_self() # $ tracked=foo +instance.foo = tracked # $ tracked=foo tracked +instance.print_foo() # $ tracked=foo From dcd448b7430bfa32ea35149882cae0eaf5151f8c Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 8 Jun 2021 18:57:54 +0200 Subject: [PATCH 2/5] Python: Refactor formatting --- .../dataflow/typetracking/attribute_tests.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py index 41eecb591a5..b8487e22ee3 100644 --- a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py +++ b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py @@ -30,8 +30,9 @@ def test_incompatible_types(): x.field = str("Hello") # $str=field str SPURIOUS: int=field int expects_string(x) # $ str=field SPURIOUS: int=field - +# ------------------------------------------------------------------------------ # Attributes assigned statically to a class +# ------------------------------------------------------------------------------ class MyClass: # $tracked=field field = tracked # $tracked @@ -40,7 +41,9 @@ lookup = MyClass.field # $tracked tracked=field instance = MyClass() # $tracked=field lookup2 = instance.field # MISSING: tracked -## Dynamic attribute access +# ------------------------------------------------------------------------------ +# Dynamic attribute access +# ------------------------------------------------------------------------------ # Via `getattr`/`setattr` @@ -105,6 +108,7 @@ def dunder_dict_indirect_read(): # attribute set in method # inspired by https://github.com/github/codeql/pull/6023 + class MyClass2(object): def __init__(self): # $ tracked=foo self.foo = tracked # $ tracked=foo tracked @@ -121,6 +125,7 @@ instance.print_foo() # $ MISSING: tracked=foo # attribute set from outside of class + class MyClass3(object): def print_self(self): # $ tracked=foo print(self) # $ tracked=foo From 3d2de03674adff646bccec2d47dd641507a42be6 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 8 Jun 2021 19:03:24 +0200 Subject: [PATCH 3/5] Python: Add type-tracking test for attr set in function --- .../dataflow/typetracking/attribute_tests.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py index b8487e22ee3..c1240bd92b9 100644 --- a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py +++ b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py @@ -30,6 +30,15 @@ def test_incompatible_types(): x.field = str("Hello") # $str=field str SPURIOUS: int=field int expects_string(x) # $ str=field SPURIOUS: int=field +# set in different function +def set_foo(some_class_instance): # $ tracked=foo + some_class_instance.foo = tracked # $ tracked=foo tracked + +def test_set_x(): + x = SomeClass() + set_foo(x) + print(x.foo) # MISSING: tracked + # ------------------------------------------------------------------------------ # Attributes assigned statically to a class # ------------------------------------------------------------------------------ From 89cba216ca6086832756428675a4badcd652dc7e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 9 Jun 2021 14:15:59 +0200 Subject: [PATCH 4/5] Python: Apply suggestions from code review Co-authored-by: Taus --- .../dataflow/typetracking/attribute_tests.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py index c1240bd92b9..351ba6397fd 100644 --- a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py +++ b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py @@ -35,9 +35,9 @@ def set_foo(some_class_instance): # $ tracked=foo some_class_instance.foo = tracked # $ tracked=foo tracked def test_set_x(): - x = SomeClass() - set_foo(x) - print(x.foo) # MISSING: tracked + x = SomeClass() # $ MISSING: tracked=foo + set_foo(x) # $ MISSING: tracked=foo + print(x.foo) # $ MISSING: tracked=foo tracked # ------------------------------------------------------------------------------ # Attributes assigned statically to a class @@ -125,8 +125,8 @@ class MyClass2(object): def print_foo(self): # $ MISSING: tracked=foo print(self.foo) # $ MISSING: tracked=foo tracked - def possibly_uncalled_method(self): - print(self.foo) # $ MISSING: tracked + def possibly_uncalled_method(self): # $ MISSING: tracked=foo + print(self.foo) # $ MISSING: tracked=foo tracked instance = MyClass2() print(instance.foo) # $ MISSING: tracked=foo tracked @@ -142,8 +142,8 @@ class MyClass3(object): def print_foo(self): # $ tracked=foo print(self.foo) # $ tracked=foo tracked - def possibly_uncalled_method(self): - print(self.foo) # $ MISSING: tracked + def possibly_uncalled_method(self): # $ MISSING: tracked=foo + print(self.foo) # $ MISSING: tracked=foo tracked instance = MyClass3() # $ tracked=foo instance.print_self() # $ tracked=foo From aaddd3623644926c02c693ca7727d77494971706 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 9 Jun 2021 14:20:50 +0200 Subject: [PATCH 5/5] Python: Add another type-tracking attr test This one just works out of the box :muscle: --- .../dataflow/typetracking/attribute_tests.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py index 351ba6397fd..617fae422cb 100644 --- a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py +++ b/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py @@ -39,6 +39,16 @@ def test_set_x(): set_foo(x) # $ MISSING: tracked=foo print(x.foo) # $ MISSING: tracked=foo tracked +# return from a different function +def create_with_foo(): + x = SomeClass() # $ tracked=foo + x.foo = tracked # $ tracked=foo tracked + return x # $ tracked=foo + +def test_create_with_foo(): + x = create_with_foo() # $ tracked=foo + print(x.foo) # $ tracked=foo tracked + # ------------------------------------------------------------------------------ # Attributes assigned statically to a class # ------------------------------------------------------------------------------