mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
This is a bit of an edge case, but allowed. Since we currently don't provide information on positional only arguments, we can't do much to solve it right now.
272 lines
6.7 KiB
Python
272 lines
6.7 KiB
Python
import sys
|
|
import os
|
|
import functools
|
|
|
|
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
|
|
from testlib import expects
|
|
|
|
arg = "source"
|
|
arg1 = "source1"
|
|
arg2 = "source2"
|
|
arg3 = "source3"
|
|
arg4 = "source4"
|
|
arg5 = "source5"
|
|
arg6 = "source6"
|
|
arg7 = "source7"
|
|
|
|
|
|
def SINK_TEST(x, test):
|
|
if test(x):
|
|
print("OK")
|
|
else:
|
|
print("Unexpected flow", x)
|
|
|
|
|
|
def SINK(x, expected=arg):
|
|
SINK_TEST(x, test=lambda x: x == expected)
|
|
|
|
|
|
def SINK_F(x, unexpected=arg):
|
|
SINK_TEST(x, test=lambda x: x != unexpected)
|
|
|
|
|
|
SINK1 = functools.partial(SINK, expected=arg1)
|
|
SINK2 = functools.partial(SINK, expected=arg2)
|
|
SINK3 = functools.partial(SINK, expected=arg3)
|
|
SINK4 = functools.partial(SINK, expected=arg4)
|
|
SINK5 = functools.partial(SINK, expected=arg5)
|
|
SINK6 = functools.partial(SINK, expected=arg6)
|
|
SINK7 = functools.partial(SINK, expected=arg7)
|
|
|
|
SINK1_F = functools.partial(SINK_F, unexpected=arg1)
|
|
SINK2_F = functools.partial(SINK_F, unexpected=arg2)
|
|
SINK3_F = functools.partial(SINK_F, unexpected=arg3)
|
|
SINK4_F = functools.partial(SINK_F, unexpected=arg4)
|
|
SINK5_F = functools.partial(SINK_F, unexpected=arg5)
|
|
SINK6_F = functools.partial(SINK_F, unexpected=arg6)
|
|
SINK7_F = functools.partial(SINK_F, unexpected=arg7)
|
|
|
|
|
|
def argument_passing(
|
|
a,
|
|
b,
|
|
/,
|
|
c,
|
|
d=arg4, #$ arg4 func=argument_passing
|
|
*,
|
|
e=arg5, #$ arg5 func=argument_passing
|
|
f,
|
|
**g,
|
|
):
|
|
SINK1(a)
|
|
SINK2(b)
|
|
SINK3(c)
|
|
SINK4(d)
|
|
SINK5(e)
|
|
SINK6(f)
|
|
try:
|
|
SINK7(g["g"])
|
|
except:
|
|
print("OK")
|
|
|
|
|
|
@expects(7)
|
|
def test_argument_passing1():
|
|
argument_passing(arg1, *(arg2, arg3, arg4), e=arg5, **{"f": arg6, "g": arg7}) #$ arg1 arg5 arg6 arg7 func=argument_passing MISSING: arg2 arg3 arg4
|
|
|
|
|
|
@expects(7)
|
|
def test_argument_passing2():
|
|
argument_passing(arg1, arg2, arg3, f=arg6) #$ arg1 arg2 arg3 arg6
|
|
|
|
|
|
def with_pos_only(a, /, b):
|
|
SINK1(a)
|
|
SINK2(b)
|
|
|
|
|
|
@expects(6)
|
|
def test_pos_only():
|
|
with_pos_only(arg1, arg2) #$ arg1 arg2
|
|
with_pos_only(arg1, b=arg2) #$ arg1 arg2
|
|
with_pos_only(arg1, *(arg2,)) #$ arg1 MISSING: arg2
|
|
|
|
|
|
def with_multiple_kw_args(a, b, c):
|
|
SINK1(a)
|
|
SINK2(b)
|
|
SINK3(c)
|
|
|
|
|
|
@expects(12)
|
|
def test_multiple_kw_args():
|
|
with_multiple_kw_args(b=arg2, c=arg3, a=arg1) #$ arg1 arg2 arg3
|
|
with_multiple_kw_args(arg1, *(arg2,), arg3) #$ arg1 MISSING: arg2 arg3
|
|
with_multiple_kw_args(arg1, **{"c": arg3}, b=arg2) #$ arg1 arg2 arg3 func=with_multiple_kw_args
|
|
with_multiple_kw_args(**{"b": arg2}, **{"c": arg3}, **{"a": arg1}) #$ arg1 arg2 arg3 func=with_multiple_kw_args
|
|
|
|
|
|
def with_default_arguments(a=arg1, b=arg2, c=arg3): #$ arg1 arg2 arg3 func=with_default_arguments
|
|
SINK1(a)
|
|
SINK2(b)
|
|
SINK3(c)
|
|
|
|
|
|
@expects(12)
|
|
def test_default_arguments():
|
|
with_default_arguments()
|
|
with_default_arguments(arg1) #$ arg1
|
|
with_default_arguments(b=arg2) #$ arg2
|
|
with_default_arguments(**{"c": arg3}) #$ arg3 func=with_default_arguments
|
|
|
|
|
|
# All combinations
|
|
def test_pos_pos():
|
|
def with_pos(a):
|
|
SINK1(a)
|
|
|
|
with_pos(arg1) #$ arg1 func=test_pos_pos.with_pos
|
|
|
|
|
|
def test_pos_pos_only():
|
|
def with_pos_only(a, /):
|
|
SINK1(a)
|
|
|
|
with_pos_only(arg1) #$ arg1 func=test_pos_pos_only.with_pos_only
|
|
|
|
|
|
def test_pos_star():
|
|
def with_star(*a):
|
|
if len(a) > 0:
|
|
SINK1(a[0])
|
|
|
|
with_star(arg1) #$ arg1 func=test_pos_star.with_star
|
|
|
|
|
|
def test_pos_kw():
|
|
def with_kw(a=""):
|
|
SINK1(a)
|
|
|
|
with_kw(arg1) #$ arg1 func=test_pos_kw.with_kw
|
|
|
|
|
|
def test_kw_pos():
|
|
def with_pos(a):
|
|
SINK1(a)
|
|
|
|
with_pos(a=arg1) #$ arg1 func=test_kw_pos.with_pos
|
|
|
|
|
|
def test_kw_kw():
|
|
def with_kw(a=""):
|
|
SINK1(a)
|
|
|
|
with_kw(a=arg1) #$ arg1 func=test_kw_kw.with_kw
|
|
|
|
|
|
def test_kw_doublestar():
|
|
def with_doublestar(**kwargs):
|
|
SINK1(kwargs["a"])
|
|
|
|
with_doublestar(a=arg1) #$ arg1 func=test_kw_doublestar.with_doublestar
|
|
|
|
|
|
def only_kwargs(**kwargs):
|
|
SINK1(kwargs["a"])
|
|
SINK2(kwargs["b"])
|
|
# testing precise content tracking, that content from `a` or `b` does not end up here.
|
|
SINK3_F(kwargs["c"])
|
|
|
|
@expects(3)
|
|
def test_kwargs():
|
|
args = {"a": arg1, "b": arg2, "c": "safe"} # $ arg1 arg2 func=only_kwargs
|
|
only_kwargs(**args)
|
|
|
|
|
|
def mixed(a, **kwargs):
|
|
SINK1(a)
|
|
try:
|
|
SINK1_F(kwargs["a"]) # since 'a' is a keyword argument, it cannot be part of **kwargs
|
|
except KeyError:
|
|
print("OK")
|
|
SINK2(kwargs["b"])
|
|
# testing precise content tracking, that content from `a` or `b` does not end up here.
|
|
SINK3_F(kwargs["c"])
|
|
|
|
@expects(4*3)
|
|
def test_mixed():
|
|
mixed(a=arg1, b=arg2, c="safe") # $ arg1 arg2
|
|
|
|
args = {"b": arg2, "c": "safe"} # $ arg2 func=mixed
|
|
mixed(a=arg1, **args) # $ arg1
|
|
|
|
args = {"a": arg1, "b": arg2, "c": "safe"} # $ arg1 arg2 func=mixed
|
|
mixed(**args)
|
|
|
|
|
|
def kwargs_same_name_as_positional_only(a, /, **kwargs):
|
|
SINK1(a)
|
|
SINK2(kwargs["a"])
|
|
|
|
@expects(2*2)
|
|
def test_kwargs_same_name_as_positional_only():
|
|
kwargs_same_name_as_positional_only(arg1, a=arg2) # $ arg1 SPURIOUS: bad1="arg2" MISSING: arg2
|
|
|
|
kwargs = {"a": arg2} # $ func=kwargs_same_name_as_positional_only SPURIOUS: bad1="arg2" MISSING: arg2
|
|
kwargs_same_name_as_positional_only(arg1, **kwargs) # $ arg1
|
|
|
|
|
|
def starargs_only(*args):
|
|
SINK1(args[0])
|
|
SINK2(args[1])
|
|
SINK3_F(args[2])
|
|
|
|
@expects(5*3)
|
|
def test_only_starargs():
|
|
starargs_only(arg1, arg2, "safe") # $ arg1 arg2 SPURIOUS: bad2,bad3="arg1" bad1,bad3="arg2"
|
|
|
|
args = (arg2, "safe") # $ MISSING: arg2
|
|
starargs_only(arg1, *args) # $ arg1 SPURIOUS: bad2,bad3="arg1"
|
|
|
|
args = (arg1, arg2, "safe") # $ arg1 arg2 func=starargs_only
|
|
starargs_only(*args)
|
|
|
|
empty_args = ()
|
|
|
|
args = (arg1, arg2, "safe") # $ arg1 arg2 func=starargs_only
|
|
starargs_only(*args, *empty_args)
|
|
args = (arg1, arg2, "safe") # $ MISSING: arg1 arg2 func=starargs_only
|
|
starargs_only(*empty_args, *args)
|
|
|
|
|
|
def starargs_mixed(a, *args):
|
|
SINK1(a)
|
|
SINK2(args[0])
|
|
SINK3_F(args[1])
|
|
|
|
@expects(3*8)
|
|
def test_stararg_mixed():
|
|
starargs_mixed(arg1, arg2, "safe") # $ arg1 arg2 SPURIOUS: bad3="arg2"
|
|
|
|
args = (arg2, "safe") # $ arg2 func=starargs_mixed
|
|
starargs_mixed(arg1, *args) # $ arg1
|
|
|
|
args = (arg1, arg2, "safe")
|
|
starargs_mixed(*args) # $ MISSING: arg1 arg2
|
|
|
|
args = (arg1, arg2, "safe")
|
|
more_args = ("foo", "bar")
|
|
starargs_mixed(*args, *more_args) # $ MISSING: arg1 arg2
|
|
|
|
empty_args = ()
|
|
|
|
# adding first/last
|
|
starargs_mixed(arg1, arg2, "safe", *empty_args) # $ arg1 arg2 SPURIOUS: bad3="arg2"
|
|
starargs_mixed(*empty_args, arg1, arg2, "safe") # $ MISSING: arg1 arg2
|
|
|
|
# adding before/after *args
|
|
args = (arg2, "safe") # $ arg2 func=starargs_mixed
|
|
starargs_mixed(arg1, *args, *empty_args) # $ arg1
|
|
args = (arg2, "safe")
|
|
starargs_mixed(arg1, *empty_args, *args) # $ arg1 MISSING: arg2
|