mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
Python: Remove absolute line numbers
- Use relative line numbers in flow test - Elide line numbers in routing test (new concept)
This commit is contained in:
@@ -26,8 +26,15 @@ abstract class FlowTest extends InlineExpectationsTest {
|
||||
|
||||
pragma[inline]
|
||||
private string lineStr(DataFlow::Node fromNode, DataFlow::Node toNode) {
|
||||
if fromNode.getLocation().getStartLine() = toNode.getLocation().getStartLine()
|
||||
then result = ""
|
||||
else result = ", l:" + fromNode.getLocation().getStartLine()
|
||||
exists(int delta |
|
||||
delta = fromNode.getLocation().getStartLine() - toNode.getLocation().getStartLine()
|
||||
|
|
||||
if delta = 0
|
||||
then result = ""
|
||||
else
|
||||
if delta > 0
|
||||
then result = ", l:+" + delta.toString()
|
||||
else result = ", l:" + delta.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import experimental.dataflow.TestUtil.PrintNode
|
||||
|
||||
/**
|
||||
* A routing test is designed to test that vlues are routed to the
|
||||
* correct arguments of the correct functions. It is assumed that
|
||||
* the functions tested sink their arguments sequentially, that is
|
||||
* `SINK1(arg1)`, etc.
|
||||
*/
|
||||
abstract class RoutingTest extends InlineExpectationsTest {
|
||||
bindingset[this]
|
||||
RoutingTest() { any() }
|
||||
|
||||
abstract string flowTag();
|
||||
|
||||
abstract predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode);
|
||||
|
||||
override string getARelevantTag() { result in ["func", this.flowTag()] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(DataFlow::Node fromNode, DataFlow::Node toNode | this.relevantFlow(fromNode, toNode) |
|
||||
location = fromNode.getLocation() and
|
||||
element = fromNode.toString() and
|
||||
(
|
||||
tag = this.flowTag() and
|
||||
value = "\"" + prettyNode(fromNode).replaceAll("\"", "'") + "\""
|
||||
or
|
||||
tag = "func" and
|
||||
value = toNode.getEnclosingCallable().getCallableValue().getScope().getQualifiedName() // TODO: More robust pretty printing?
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
def obfuscated_id(x): #$ step="FunctionExpr -> GSSA Variable obfuscated_id" step="x -> SSA variable x"
|
||||
y = x #$ step="x -> SSA variable y" step="SSA variable x, l:1 -> x"
|
||||
z = y #$ step="y -> SSA variable z" step="SSA variable y, l:2 -> y"
|
||||
return z #$ flow="42, l:6 -> z" step="SSA variable z, l:3 -> z"
|
||||
y = x #$ step="x -> SSA variable y" step="SSA variable x, l:-1 -> x"
|
||||
z = y #$ step="y -> SSA variable z" step="SSA variable y, l:-1 -> y"
|
||||
return z #$ flow="42, l:+2 -> z" step="SSA variable z, l:-1 -> z"
|
||||
|
||||
a = 42 #$ step="42 -> GSSA Variable a"
|
||||
b = obfuscated_id(a) #$ flow="42, l:6 -> GSSA Variable b" flow="FunctionExpr, l:1 -> obfuscated_id" step="obfuscated_id(..) -> GSSA Variable b" step="GSSA Variable obfuscated_id, l:1 -> obfuscated_id" step="GSSA Variable a, l:6 -> a"
|
||||
b = obfuscated_id(a) #$ flow="42, l:-1 -> GSSA Variable b" flow="FunctionExpr, l:-6 -> obfuscated_id" step="obfuscated_id(..) -> GSSA Variable b" step="GSSA Variable obfuscated_id, l:-6 -> obfuscated_id" step="GSSA Variable a, l:-1 -> a"
|
||||
|
||||
@@ -72,78 +72,78 @@ def argument_passing(
|
||||
f,
|
||||
**g,
|
||||
):
|
||||
SINK1(a) #$ arg1="arg1, l:89 -> a" arg1="arg1, l:94 -> a"
|
||||
SINK2(b) #$ arg2="arg2, l:94 -> b" MISSING:arg2="arg2, l:89 -> b"
|
||||
SINK3(c) #$ arg3="arg3, l:94 -> c" MISSING: arg3="arg3, l:89 -> c"
|
||||
SINK4(d) #$ MISSING: arg4="arg4, l:89 -> d"
|
||||
SINK5(e) #$ MISSING: arg5="arg5, l:89 -> e"
|
||||
SINK6(f) #$ MISSING: arg6="arg6, l:89 -> f"
|
||||
SINK1(a)
|
||||
SINK2(b)
|
||||
SINK3(c)
|
||||
SINK4(d)
|
||||
SINK5(e)
|
||||
SINK6(f)
|
||||
try:
|
||||
SINK7(g["g"]) #$ arg7="arg7, l:89 -> g['g']"
|
||||
SINK7(g["g"])
|
||||
except:
|
||||
print("OK")
|
||||
|
||||
|
||||
@expects(7)
|
||||
def test_argument_passing1():
|
||||
argument_passing(arg1, *(arg2, arg3, arg4), e=arg5, **{"f": arg6, "g": arg7})
|
||||
argument_passing(arg1, *(arg2, arg3, arg4), e=arg5, **{"f": arg6, "g": arg7}) #$ arg1="arg1" arg7="arg7" func=argument_passing MISSING: arg2="arg2" arg3="arg3 arg4="arg4" arg5="arg5" arg6="arg6"
|
||||
|
||||
|
||||
@expects(7)
|
||||
def test_argument_passing2():
|
||||
argument_passing(arg1, arg2, arg3, f=arg6)
|
||||
argument_passing(arg1, arg2, arg3, f=arg6) #$ arg1="arg1" arg2="arg2" arg3="arg3" func=argument_passing
|
||||
|
||||
|
||||
def with_pos_only(a, /, b):
|
||||
SINK1(a) #$ arg1="arg1, l:104 -> a" arg1="arg1, l:105 -> a" arg1="arg1, l:106 -> a"
|
||||
SINK2(b) #$ arg2="arg2, l:104 -> b" arg2="arg2, l:105 -> b" MISSING: arg2="arg2, l:106 -> b"
|
||||
SINK1(a)
|
||||
SINK2(b)
|
||||
|
||||
|
||||
@expects(6)
|
||||
def test_pos_only():
|
||||
with_pos_only(arg1, arg2)
|
||||
with_pos_only(arg1, b=arg2)
|
||||
with_pos_only(arg1, *(arg2,))
|
||||
with_pos_only(arg1, arg2) #$ arg1="arg1" arg2="arg2" func=with_pos_only
|
||||
with_pos_only(arg1, b=arg2) #$ arg1="arg1" arg2="arg2" func=with_pos_only
|
||||
with_pos_only(arg1, *(arg2,)) #$ arg1="arg1" func=with_pos_only MISSING: arg2="arg2"
|
||||
|
||||
|
||||
def with_multiple_kw_args(a, b, c):
|
||||
SINK1(a) #$ arg1="arg1, l:117 -> a" arg1="arg1, l:118 -> a" arg1="arg1, l:119 -> a" arg1="arg1, l:120 -> a"
|
||||
SINK2(b) #$ arg2="arg2, l:117 -> b" arg2="arg2, l:120 -> b" MISSING: arg2="arg2, l:118 -> b" arg2="arg2, l:119 -> b"
|
||||
SINK3(c) #$ arg3="arg3, l:117 -> c" arg3="arg3, l:119 -> c" arg3="arg3, l:120 -> c" MISSING: arg3="arg3, l:118 -> c"
|
||||
SINK1(a)
|
||||
SINK2(b)
|
||||
SINK3(c)
|
||||
|
||||
|
||||
@expects(9)
|
||||
def test_multiple_kw_args():
|
||||
with_multiple_kw_args(b=arg2, c=arg3, a=arg1)
|
||||
with_multiple_kw_args(arg1, *(arg2,), arg3)
|
||||
with_multiple_kw_args(arg1, **{"c": arg3}, b=arg2)
|
||||
with_multiple_kw_args(**{"b": arg2}, **{"c": arg3}, **{"a": arg1})
|
||||
with_multiple_kw_args(b=arg2, c=arg3, a=arg1) #$ arg1="arg1" arg2="arg2" arg3="arg3" func=with_multiple_kw_args
|
||||
with_multiple_kw_args(arg1, *(arg2,), arg3) #$ arg1="arg1" func=with_multiple_kw_args MISSING: arg2="arg2" arg3="arg3"
|
||||
with_multiple_kw_args(arg1, **{"c": arg3}, b=arg2) #$ arg1="arg1" arg3="arg3" func=with_multiple_kw_args MISSING: arg2="arg2"
|
||||
with_multiple_kw_args(**{"b": arg2}, **{"c": arg3}, **{"a": arg1}) #$ arg1="arg1" arg2="arg2" arg3="arg3" func=with_multiple_kw_args
|
||||
|
||||
|
||||
def with_default_arguments(a=arg1, b=arg2, c=arg3):
|
||||
SINK1(a) #$ arg1="arg1, l:132 -> a" MISSING:arg1="arg1, l:123 -> a"
|
||||
SINK2(b) #$ arg2="arg2, l:133 -> b" MISSING: arg2="arg2, l:123 -> b"
|
||||
SINK3(c) #$ arg3="arg3, l:134 -> c" MISSING: arg3="arg3, l:123 -> c"
|
||||
def with_default_arguments(a=arg1, b=arg2, c=arg3): # Need a mechanism to test default arguments
|
||||
SINK1(a)
|
||||
SINK2(b)
|
||||
SINK3(c)
|
||||
|
||||
|
||||
@expects(12)
|
||||
def test_default_arguments():
|
||||
with_default_arguments()
|
||||
with_default_arguments(arg1)
|
||||
with_default_arguments(b=arg2)
|
||||
with_default_arguments(**{"c": arg3})
|
||||
with_default_arguments(arg1) #$ arg1="arg1" func=with_default_arguments
|
||||
with_default_arguments(b=arg2) #$ arg2="arg2" func=with_default_arguments
|
||||
with_default_arguments(**{"c": arg3}) #$ arg3="arg3" func=with_default_arguments
|
||||
|
||||
|
||||
# Nested constructor pattern
|
||||
def grab_foo_bar_baz(foo, **kwargs):
|
||||
SINK1(foo) #$ arg1="arg1, l:160 -> foo"
|
||||
SINK1(foo)
|
||||
grab_bar_baz(**kwargs)
|
||||
|
||||
|
||||
# It is not possible to pass `bar` into `kwargs`,
|
||||
# since `bar` is a valid keyword argument.
|
||||
def grab_bar_baz(bar, **kwargs):
|
||||
SINK2(bar) #$ arg2="arg2, l:160 -> bar"
|
||||
SINK2(bar)
|
||||
try:
|
||||
SINK2_F(kwargs["bar"])
|
||||
except:
|
||||
@@ -152,60 +152,60 @@ def grab_bar_baz(bar, **kwargs):
|
||||
|
||||
|
||||
def grab_baz(baz):
|
||||
SINK3(baz) #$ arg3="arg3, l:160 -> baz"
|
||||
SINK3(baz)
|
||||
|
||||
|
||||
@expects(4)
|
||||
def test_grab():
|
||||
grab_foo_bar_baz(baz=arg3, bar=arg2, foo=arg1)
|
||||
grab_foo_bar_baz(baz=arg3, bar=arg2, foo=arg1) #$ arg1="arg1" arg2="arg2" arg3="arg3" func=grab_foo_bar_baz func=grab_bar_baz func=grab_baz
|
||||
|
||||
|
||||
# All combinations
|
||||
def test_pos_pos():
|
||||
def with_pos(a):
|
||||
SINK1(a) #$ arg1="arg1, l:168 -> a"
|
||||
SINK1(a)
|
||||
|
||||
with_pos(arg1)
|
||||
with_pos(arg1) #$ arg1="arg1" func=test_pos_pos.with_pos
|
||||
|
||||
|
||||
def test_pos_pos_only():
|
||||
def with_pos_only(a, /):
|
||||
SINK1(a) #$ arg1="arg1, l:175 -> a"
|
||||
SINK1(a)
|
||||
|
||||
with_pos_only(arg1)
|
||||
with_pos_only(arg1) #$ 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]) #$ arg1="arg1, l:183 -> a[0]"
|
||||
SINK1(a[0])
|
||||
|
||||
with_star(arg1)
|
||||
with_star(arg1) #$ arg1="arg1" func=test_pos_star.with_star
|
||||
|
||||
|
||||
def test_pos_kw():
|
||||
def with_kw(a=""):
|
||||
SINK1(a) #$ arg1="arg1, l:190 -> a"
|
||||
SINK1(a)
|
||||
|
||||
with_kw(arg1)
|
||||
with_kw(arg1) #$ arg1="arg1" func=test_pos_kw.with_kw
|
||||
|
||||
|
||||
def test_kw_pos():
|
||||
def with_pos(a):
|
||||
SINK1(a) #$ arg1="arg1, l:197 -> a"
|
||||
SINK1(a)
|
||||
|
||||
with_pos(a=arg1)
|
||||
with_pos(a=arg1) #$ arg1="arg1" func=test_kw_pos.with_pos
|
||||
|
||||
|
||||
def test_kw_kw():
|
||||
def with_kw(a=""):
|
||||
SINK1(a) #$ arg1="arg1, l:204 -> a"
|
||||
SINK1(a)
|
||||
|
||||
with_kw(a=arg1)
|
||||
with_kw(a=arg1) #$ arg1="arg1" func=test_kw_kw.with_kw
|
||||
|
||||
|
||||
def test_kw_doublestar():
|
||||
def with_doublestar(**a):
|
||||
SINK1(a["a"]) #$ arg1="arg1, l:211 -> a['a']"
|
||||
SINK1(a["a"])
|
||||
|
||||
with_doublestar(a=arg1)
|
||||
with_doublestar(a=arg1) #$ arg1="arg1" func=test_kw_doublestar.with_doublestar
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
|
||||
import experimental.dataflow.TestUtil.FlowTest
|
||||
import experimental.dataflow.TestUtil.RoutingTest
|
||||
|
||||
class Argument1RoutingTest extends FlowTest {
|
||||
class Argument1RoutingTest extends RoutingTest {
|
||||
Argument1RoutingTest() { this = "Argument1RoutingTest" }
|
||||
|
||||
override string flowTag() { result = "arg1" }
|
||||
@@ -46,7 +46,7 @@ class Argument1RoutingConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
class Argument2RoutingTest extends FlowTest {
|
||||
class Argument2RoutingTest extends RoutingTest {
|
||||
Argument2RoutingTest() { this = "Argument2RoutingTest" }
|
||||
|
||||
override string flowTag() { result = "arg2" }
|
||||
@@ -82,7 +82,7 @@ class Argument2RoutingConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
class Argument3RoutingTest extends FlowTest {
|
||||
class Argument3RoutingTest extends RoutingTest {
|
||||
Argument3RoutingTest() { this = "Argument3RoutingTest" }
|
||||
|
||||
override string flowTag() { result = "arg3" }
|
||||
@@ -118,7 +118,7 @@ class Argument3RoutingConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
class Argument4RoutingTest extends FlowTest {
|
||||
class Argument4RoutingTest extends RoutingTest {
|
||||
Argument4RoutingTest() { this = "Argument4RoutingTest" }
|
||||
|
||||
override string flowTag() { result = "arg4" }
|
||||
@@ -154,7 +154,7 @@ class Argument4RoutingConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
class Argument5RoutingTest extends FlowTest {
|
||||
class Argument5RoutingTest extends RoutingTest {
|
||||
Argument5RoutingTest() { this = "Argument5RoutingTest" }
|
||||
|
||||
override string flowTag() { result = "arg5" }
|
||||
@@ -190,7 +190,7 @@ class Argument5RoutingConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
class Argument6RoutingTest extends FlowTest {
|
||||
class Argument6RoutingTest extends RoutingTest {
|
||||
Argument6RoutingTest() { this = "Argument6RoutingTest" }
|
||||
|
||||
override string flowTag() { result = "arg6" }
|
||||
@@ -226,7 +226,7 @@ class Argument6RoutingConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
class Argument7RoutingTest extends FlowTest {
|
||||
class Argument7RoutingTest extends RoutingTest {
|
||||
Argument7RoutingTest() { this = "Argument7RoutingTest" }
|
||||
|
||||
override string flowTag() { result = "arg7" }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -153,7 +153,7 @@ class Customized:
|
||||
|
||||
# testing __new__ and __init__
|
||||
customized = Customized()
|
||||
SINK(Customized.a)
|
||||
SINK(Customized.a) #$ MISSING:flow="SOURCE, l:-8 -> customized.a"
|
||||
SINK_F(Customized.b)
|
||||
SINK(customized.a)
|
||||
SINK(customized.b) #$ flow="SOURCE, l:152 -> customized.b"
|
||||
SINK(customized.a) #$ MISSING:flow="SOURCE, l:-10 -> customized.a"
|
||||
SINK(customized.b) #$ flow="SOURCE, l:-7 -> customized.b"
|
||||
|
||||
@@ -41,7 +41,7 @@ def SINK_F(x):
|
||||
def test_tuple_with_local_flow():
|
||||
x = (NONSOURCE, SOURCE)
|
||||
y = x[1]
|
||||
SINK(y) #$ flow="SOURCE, l:42 -> y"
|
||||
SINK(y) #$ flow="SOURCE, l:-2 -> y"
|
||||
|
||||
|
||||
def test_tuple_negative():
|
||||
@@ -53,45 +53,45 @@ def test_tuple_negative():
|
||||
# 6.2.1. Identifiers (Names)
|
||||
def test_names():
|
||||
x = SOURCE
|
||||
SINK(x) #$ flow="SOURCE, l:55 -> x"
|
||||
SINK(x) #$ flow="SOURCE, l:-1 -> x"
|
||||
|
||||
|
||||
# 6.2.2. Literals
|
||||
def test_string_literal():
|
||||
x = "source"
|
||||
SINK(x) #$ flow="'source', l:61 -> x"
|
||||
SINK(x) #$ flow="'source', l:-1 -> x"
|
||||
|
||||
|
||||
def test_bytes_literal():
|
||||
x = b"source"
|
||||
SINK(x) #$ flow="b'source', l:66 -> x"
|
||||
SINK(x) #$ flow="b'source', l:-1 -> x"
|
||||
|
||||
|
||||
def test_integer_literal():
|
||||
x = 42
|
||||
SINK(x) #$ flow="42, l:71 -> x"
|
||||
SINK(x) #$ flow="42, l:-1 -> x"
|
||||
|
||||
|
||||
def test_floatnumber_literal():
|
||||
x = 42.0
|
||||
SINK(x) #$ flow="42.0, l:76 -> x"
|
||||
SINK(x) #$ flow="42.0, l:-1 -> x"
|
||||
|
||||
|
||||
def test_imagnumber_literal():
|
||||
x = 42j
|
||||
SINK(x) #$ MISSING:flow="42j, l:81 -> x"
|
||||
SINK(x) #$ MISSING:flow="42j, l:-1 -> x"
|
||||
|
||||
|
||||
# 6.2.3. Parenthesized forms
|
||||
def test_parenthesized_form():
|
||||
x = (SOURCE)
|
||||
SINK(x) #$ flow="SOURCE, l:87 -> x"
|
||||
SINK(x) #$ flow="SOURCE, l:-1 -> x"
|
||||
|
||||
|
||||
# 6.2.5. List displays
|
||||
def test_list_display():
|
||||
x = [SOURCE]
|
||||
SINK(x[0]) #$ flow="SOURCE, l:93 -> x[0]"
|
||||
SINK(x[0]) #$ flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
def test_list_display_negative():
|
||||
@@ -101,103 +101,103 @@ def test_list_display_negative():
|
||||
|
||||
def test_list_comprehension():
|
||||
x = [SOURCE for y in [NONSOURCE]]
|
||||
SINK(x[0]) #$ flow="SOURCE, l:103 -> x[0]"
|
||||
SINK(x[0]) #$ flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
def test_list_comprehension_flow():
|
||||
x = [y for y in [SOURCE]]
|
||||
SINK(x[0]) #$ flow="SOURCE, l:108 -> x[0]"
|
||||
SINK(x[0]) #$ flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
def test_list_comprehension_inflow():
|
||||
l = [SOURCE]
|
||||
x = [y for y in l]
|
||||
SINK(x[0]) #$ flow="SOURCE, l:113 -> x[0]"
|
||||
SINK(x[0]) #$ flow="SOURCE, l:-2 -> x[0]"
|
||||
|
||||
|
||||
def test_nested_list_display():
|
||||
x = [*[SOURCE]]
|
||||
SINK(x[0]) #$ MISSING:flow="SOURCE, l:119 -> x[0]"
|
||||
SINK(x[0]) #$ MISSING:flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
# 6.2.6. Set displays
|
||||
def test_set_display():
|
||||
x = {SOURCE}
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:125 -> x.pop()"
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()"
|
||||
|
||||
|
||||
def test_set_comprehension():
|
||||
x = {SOURCE for y in [NONSOURCE]}
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:130 -> x.pop()"
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()"
|
||||
|
||||
|
||||
def test_set_comprehension_flow():
|
||||
x = {y for y in [SOURCE]}
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:135 -> x.pop()"
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()"
|
||||
|
||||
|
||||
def test_set_comprehension_inflow():
|
||||
l = {SOURCE}
|
||||
x = {y for y in l}
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:140 -> x.pop()"
|
||||
SINK(x.pop()) #$ flow="SOURCE, l:-2 -> x.pop()"
|
||||
|
||||
|
||||
def test_nested_set_display():
|
||||
x = {*{SOURCE}}
|
||||
SINK(x.pop()) #$ MISSING:flow="SOURCE, l:146 -> x.pop()"
|
||||
SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()"
|
||||
|
||||
|
||||
# 6.2.7. Dictionary displays
|
||||
def test_dict_display():
|
||||
x = {"s": SOURCE}
|
||||
SINK(x["s"]) #$ flow="SOURCE, l:152 -> x['s']"
|
||||
SINK(x["s"]) #$ flow="SOURCE, l:-1 -> x['s']"
|
||||
|
||||
|
||||
def test_dict_display_pop():
|
||||
x = {"s": SOURCE}
|
||||
SINK(x.pop("s")) #$ flow="SOURCE, l:157 -> x.pop(..)"
|
||||
SINK(x.pop("s")) #$ flow="SOURCE, l:-1 -> x.pop(..)"
|
||||
|
||||
|
||||
def test_dict_comprehension():
|
||||
x = {y: SOURCE for y in ["s"]}
|
||||
SINK(x["s"]) #$ MISSING:flow="SOURCE, l:152 -> x['s']"
|
||||
SINK(x["s"]) #$ MISSING:flow="SOURCE, l:-1 -> x['s']"
|
||||
|
||||
|
||||
def test_dict_comprehension_pop():
|
||||
x = {y: SOURCE for y in ["s"]}
|
||||
SINK(x.pop("s")) #$ MISSING:flow="SOURCE, l:167 -> x.pop()"
|
||||
SINK(x.pop("s")) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()"
|
||||
|
||||
|
||||
def test_nested_dict_display():
|
||||
x = {**{"s": SOURCE}}
|
||||
SINK(x["s"]) #$ MISSING:flow="SOURCE, l:172 -> x['s']"
|
||||
SINK(x["s"]) #$ MISSING:flow="SOURCE, l:-1 -> x['s']"
|
||||
|
||||
|
||||
def test_nested_dict_display_pop():
|
||||
x = {**{"s": SOURCE}}
|
||||
SINK(x.pop("s")) #$ MISSING:flow="SOURCE, l:177 -> x.pop()"
|
||||
SINK(x.pop("s")) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()"
|
||||
|
||||
|
||||
# Nested comprehensions
|
||||
def test_nested_comprehension():
|
||||
x = [y for z in [[SOURCE]] for y in z]
|
||||
SINK(x[0]) #$ flow="SOURCE, l:183 -> x[0]"
|
||||
SINK(x[0]) #$ flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
def test_nested_comprehension_deep_with_local_flow():
|
||||
x = [y for v in [[[[SOURCE]]]] for u in v for z in u for y in z]
|
||||
SINK(x[0]) #$ flow="SOURCE, l:188 -> x[0]"
|
||||
SINK(x[0]) #$ flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
def test_nested_comprehension_dict():
|
||||
d = {"s": [SOURCE]}
|
||||
x = [y for k, v in d.items() for y in v]
|
||||
SINK(x[0]) #$ MISSING:flow="SOURCE, l:193 -> x[0]"
|
||||
SINK(x[0]) #$ MISSING:flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
def test_nested_comprehension_paren():
|
||||
x = [y for y in (z for z in [SOURCE])]
|
||||
SINK(x[0]) #$ flow="SOURCE, l:199 -> x[0]"
|
||||
SINK(x[0]) #$ flow="SOURCE, l:-1 -> x[0]"
|
||||
|
||||
|
||||
# 6.2.8. Generator expressions
|
||||
@@ -228,7 +228,7 @@ def test_yield_from():
|
||||
# a statement rather than an expression, but related to generators
|
||||
def test_for():
|
||||
for x in gen(SOURCE):
|
||||
SINK(x) #$ MISSING:flow="SOURCE, l:230 -> x"
|
||||
SINK(x) #$ MISSING:flow="SOURCE, l:-1 -> x"
|
||||
|
||||
|
||||
# 6.2.9.1. Generator-iterator methods
|
||||
@@ -508,12 +508,12 @@ def test_lambda_extra_keyword_flow():
|
||||
def test_swap():
|
||||
a = SOURCE
|
||||
b = NONSOURCE
|
||||
SINK(a) #$ flow="SOURCE, l:509 -> a"
|
||||
SINK(a) #$ flow="SOURCE, l:-2 -> a"
|
||||
SINK_F(b)
|
||||
|
||||
a, b = b, a
|
||||
SINK_F(a)
|
||||
SINK(b) #$ flow="SOURCE, l:509 -> b"
|
||||
SINK(b) #$ flow="SOURCE, l:-7 -> b"
|
||||
|
||||
|
||||
def test_deep_callgraph():
|
||||
@@ -538,7 +538,7 @@ def test_deep_callgraph():
|
||||
return f5(arg)
|
||||
|
||||
x = f6(SOURCE)
|
||||
SINK(x) #$ MISSING:flow="SOURCE, l:540 -> x"
|
||||
SINK(x) #$ MISSING:flow="SOURCE, l:-1 -> x"
|
||||
|
||||
|
||||
@expects(2)
|
||||
|
||||
Reference in New Issue
Block a user