Skip to content

Commit

Permalink
Avoid invalid Python syntaxes in Pysa tests
Browse files Browse the repository at this point in the history
Reviewed By: dkgi

Differential Revision: D32125147

fbshipit-source-id: 4fec216553b3f3ddd1921e116afff27300026ea9
  • Loading branch information
grievejia authored and facebook-github-bot committed Nov 4, 2021
1 parent 2199177 commit d3cbb71
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 139 deletions.
111 changes: 0 additions & 111 deletions source/interprocedural/test/decoratorHelperTest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -726,60 +726,6 @@ let test_inline_decorators context =

return _inlined_with_logging_source(y)
|};
(* Decorator factory. *)
assert_inlined
{|
from typing import Callable
from builtins import _test_sink

def with_named_logger(logger_name: str) -> Callable[[Callable], Callable]:

def _inner_decorator(f: Callable) -> Callable:

def inner( *args: object, **kwargs: object) -> None:
print(logger_name)
_test_sink(args)
f( *args, **kwargs)

return inner

return _inner_decorator

@with_named_logger("foo_logger")
def foo(x: str) -> None:
print(x)
|}
{|
from typing import Callable
from builtins import _test_sink

def with_named_logger(logger_name: str) -> Callable[[Callable], Callable]:

def _inner_decorator(f: Callable) -> Callable:

def inner( *args: object, **kwargs: object) -> None:
print(logger_name)
_test_sink(args)
f( *args, **kwargs)

return inner

return _inner_decorator

def foo(x: str) -> None:
def _original_function(x: str) -> None:
print(x)

def _inlined_with_named_logger(x: str) -> None:
_args = (x, )
_kwargs = {"x": x}

print($parameter$logger_name)
_test_sink(_args)
_original_function(x)

return _inlined_with_named_logger(x)
|};
(* Decorator that uses helper functions. *)
assert_inlined
{|
Expand Down Expand Up @@ -1297,63 +1243,6 @@ let test_inline_decorators context =

return _inlined_with_logging2(y)
|};
(* Decorator that passes in a local variable to the original function.
Note: This is a bit of a weird edge case because the `@wraps` says that the signature is the
same as the original function, but in reality it takes in one less parameter. I'm reconciling
this by keeping the original signature (for the sake of model-writing and typechecking) but
only storing the remaining parameters in `_args` and `_kwargs`. *)
assert_inlined
{|
from typing import Callable
from builtins import _test_sink
from functools import wraps

def with_logging(f: Callable) -> Callable:

@wraps(f)
def inner(request: str, *args, **kwargs) -> None:
_test_sink(args)
x = 42
f(request, x, *args, **kwargs)

return inner

@with_logging
def foo(request: str, x: int, y: int) -> None:
print(x)
|}
{|
from typing import Callable
from builtins import _test_sink
from functools import wraps

def with_logging(f: Callable) -> Callable:

@wraps(f)
def inner(request: str, *args, **kwargs) -> None:
_test_sink(args)
x = 42
f(request, x, *args, **kwargs)

return inner

def foo(request: str, x: int, y: int) -> None:

def _original_function(request: str, x: int, y: int) -> None:
print(x)

def _inlined_with_logging(request: str, x: int, y: int) -> None:
_args = (y, )
_kwargs = {"y": y}
_test_sink(_args)

# Need to explicitly qualify this local variable because `x` is also a parameter.
$local_test?foo?_inlined_with_logging$x = 42
_original_function(request, $local_test?foo?_inlined_with_logging$x, y)

return _inlined_with_logging(request, x, y)
|};
(* Decorator that passes in a local variable but doesn't use @wraps. We fall back to having *args,
**kwargs in the outer signature. *)
assert_inlined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ let test_walrus context =
~context
{|
def sink_in_walrus(arg):
x := _test_sink(arg)
(x := _test_sink(arg))

def tito_via_walrus(arg):
return (x := arg)
Expand Down
15 changes: 11 additions & 4 deletions source/interprocedural_analyses/taint/test/forwardAnalysisTest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ open Taint
open Interprocedural
open TestHelper

let assert_taint ?models ~context source expect =
let assert_taint ?models ?models_source ~context source expect =
let handle = "qualifier.py" in
let qualifier = Ast.Reference.create "qualifier" in
let sources =
match models with
| Some models -> [handle, source; "models.py", models]
match models_source with
| Some models_source -> [handle, source; "models.py", models_source]
| None -> [handle, source]
in
let { Test.ScratchProject.BuiltTypeEnvironment.type_environment = environment; _ } =
Expand Down Expand Up @@ -108,6 +108,7 @@ let test_simple_source context =
~models:{|
def models.custom_source() -> TaintSource[Test]: ...
|}
~models_source:"def custom_source() -> int: ..."
{|
def simple_source():
return models.custom_source()
Expand Down Expand Up @@ -960,7 +961,7 @@ let test_parameter_default_values context =
assert_taint
~context
{|
def source_in_default(tainted=_test_source(), benign):
def source_in_default(benign, tainted=_test_source()):
return benign
|}
[outcome ~kind:`Function ~returns:[] "qualifier.source_in_default"]
Expand Down Expand Up @@ -1027,6 +1028,7 @@ let test_composed_models context =
def models.composed_model(x: TaintSink[Test], y, z) -> TaintSource[UserControlled]: ...
def models.composed_model(x, y: TaintSink[Demo], z: TaintInTaintOut): ...
|}
~models_source:"def composed_model(x, y, z): ..."
{|
|}
[
Expand All @@ -1052,6 +1054,11 @@ let test_tito_side_effects context =
def models.change_arg1(arg0: TaintInTaintOut[Updates[arg1]], arg1): ...
def qualifier.MyList.append(self, arg: TaintInTaintOut[Updates[self]]): ...
|}
~models_source:
{|
def change_arg0(arg0, arg1): ...
def change_arg1(arg0, arg1): ...
|}
{|
def test_from_1_to_0():
x = 0
Expand Down
45 changes: 22 additions & 23 deletions source/interprocedural_analyses/taint/test/modelTest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ let assert_invalid_model ?path ?source ?(sources = []) ~context ~model_source ~e
| None ->
{|
unannotated_global = source()
def test.sink(parameter) -> None: pass
def test.sink_with_optional(parameter, firstOptional=1, secondOptional=2) -> None: pass
def test.source() -> None: pass
def test.taint(x, y) -> None: pass
def test.partial_sink(x, y) -> None: pass
def sink(parameter) -> None: pass
def sink_with_optional(parameter, firstOptional=1, secondOptional=2) -> None: pass
def source() -> None: pass
def taint(x, y) -> None: pass
def partial_sink(x, y) -> None: pass
def function_with_args(normal_arg, __anonymous_arg, *args) -> None: pass
def function_with_kwargs(normal_arg, **kwargs) -> None: pass
def anonymous_only(__arg1, __arg2, __arg3) -> None: pass
Expand Down Expand Up @@ -1521,8 +1521,8 @@ let test_class_models context =
~source:
{|
class Sink:
def Sink.method(parameter): ...
def Sink.method_with_multiple_parameters(first, second): ...
def method(parameter): ...
def method_with_multiple_parameters(first, second): ...
|}
~model_source:"class test.Sink(TaintSink[TestSink]): ..."
~expect:
Expand All @@ -1545,8 +1545,8 @@ let test_class_models context =
~source:
{|
class Sink:
def Sink.method(parameter): ...
def Sink.method_with_multiple_parameters(first, second): ...
def method(parameter): ...
def method_with_multiple_parameters(first, second): ...
|}
~model_source:"class test.Sink(TaintSink[TestSink], TaintSink[OtherSink]): ..."
~expect:
Expand All @@ -1572,10 +1572,9 @@ let test_class_models context =
]
();
assert_model
~source:
{|
~source:{|
class SinkAndSource:
def SinkAndSource.method(parameter): ...
def method(parameter): ...
|}
~model_source:"class test.SinkAndSource(TaintSink[TestSink], TaintSource[TestTest]): ..."
~expect:
Expand All @@ -1592,8 +1591,8 @@ let test_class_models context =
~source:
{|
class Source:
def Source.method(parameter): ...
def Source.method_with_multiple_parameters(first, second): ...
def method(parameter): ...
def method_with_multiple_parameters(first, second): ...
Source.attribute = ...
|}
~model_source:{|
Expand All @@ -1612,7 +1611,7 @@ let test_class_models context =
~source:
{|
class AnnotatedSink:
def AnnotatedSink.method(parameter: int) -> None: ...
def method(parameter: int) -> None: ...
|}
~model_source:"class test.AnnotatedSink(TaintSink[TestSink]): ..."
~expect:
Expand All @@ -1627,7 +1626,7 @@ let test_class_models context =
~source:
{|
class AnnotatedSource:
def AnnotatedSource.method(parameter: int) -> None: ...
def method(parameter: int) -> None: ...
|}
~model_source:"class test.AnnotatedSource(TaintSource[UserControlled]): ..."
~expect:
Expand All @@ -1642,7 +1641,7 @@ let test_class_models context =
~source:
{|
class SourceWithDefault:
def SourceWithDefault.method(parameter: int = 1) -> None: ...
def method(parameter: int = 1) -> None: ...
|}
~model_source:"class test.SourceWithDefault(TaintSink[Test]): ..."
~expect:
Expand All @@ -1658,7 +1657,7 @@ let test_class_models context =
{|
class Source:
@classmethod
def Source.method(cls, parameter: int) -> None: ...
def method(cls, parameter: int) -> None: ...
|}
~model_source:"class test.Source(TaintSource[UserControlled]): ..."
~expect:
Expand All @@ -1669,7 +1668,7 @@ let test_class_models context =
{|
class Source:
@property
def Source.prop(self) -> int: ...
def prop(self) -> int: ...
|}
~model_source:"class test.Source(TaintSource[UserControlled]): ..."
~expect:
Expand All @@ -1679,8 +1678,8 @@ let test_class_models context =
~source:
{|
class SkipMe:
def SkipMe.method(parameter): ...
def SkipMe.method_with_multiple_parameters(first, second): ...
def method(parameter): ...
def method_with_multiple_parameters(first, second): ...
|}
~model_source:"class test.SkipMe(SkipAnalysis): ..."
~expect:
Expand All @@ -1700,8 +1699,8 @@ let test_class_models context =
~source:
{|
class SkipMe:
def SkipMe.method(parameter): ...
def SkipMe.method_with_multiple_parameters(first, second): ...
def method(parameter): ...
def method_with_multiple_parameters(first, second): ...
|}
~model_source:"class test.SkipMe(SkipOverrides): ..."
~expected_skipped_overrides:
Expand Down

0 comments on commit d3cbb71

Please sign in to comment.