From fcd346c2af90efe2a82f87003cb3da0adbb62ad3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 1 Jul 2021 15:20:17 +0200 Subject: [PATCH 1/3] Python: Add flow from default values to their parameters. This creates data-flow inconsistencies, probably because the default values have incorrect enclosing callables --- .../dataflow/new/internal/DataFlowPrivate.qll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 074289b00fd..69a46a9e354 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -209,6 +209,9 @@ module EssaFlow { nodeTo = TKwOverflowNode(call, callable) and nodeFrom.asCfgNode() = call.getNode().getKwargs().getAFlowNode() ) + or + // Default value for parameter flows to that parameter + defaultValueFlowStep(nodeFrom, nodeTo) } predicate useToNextUse(NameNode nodeFrom, NameNode nodeTo) { @@ -1033,6 +1036,19 @@ predicate kwOverflowStoreStep(CfgNode nodeFrom, DictionaryElementContent c, Node ) } +predicate defaultValueFlowStep(CfgNode nodeFrom, CfgNode nodeTo) { + exists(Function f, Parameter p, ParameterDefinition def | + // `getArgByName` supports, unlike `getAnArg`, keyword-only parameters + p = f.getArgByName(_) and + nodeFrom.asExpr() = p.getDefault() and + // The following expresses + // nodeTo.(ParameterNode).getParameter() = p + // without non-monotonic recursion + def.getParameter() = p and + nodeTo.getNode() = def.getDefiningNode() + ) +} + /** * Holds if data can flow from `nodeFrom` to `nodeTo` via a read of content `c`. */ From 4a5f70e6c8e5a38a69ab156051f22e461f61a651 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 8 Sep 2021 10:05:31 +0200 Subject: [PATCH 2/3] Python: Reclassify `defaultValueFlowStep` as a `jumpStep`. --- .../2021-09-08-add-flow-from-default-values.md | 2 ++ .../dataflow/new/internal/DataFlowPrivate.qll | 6 +++--- .../dataflow/coverage/argumentPassing.py | 6 +++--- .../coverage/argumentRouting1.expected | 5 +++++ .../coverage/argumentRouting2.expected | 5 +++++ .../coverage/argumentRouting3.expected | 5 +++++ .../coverage/argumentRouting4.expected | 6 ++++++ .../coverage/argumentRouting5.expected | 6 ++++++ .../dataflow/coverage/dataflow.expected | 18 ++++++++++++++++++ .../experimental/dataflow/coverage/test.py | 6 +++--- 10 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 python/change-notes/2021-09-08-add-flow-from-default-values.md diff --git a/python/change-notes/2021-09-08-add-flow-from-default-values.md b/python/change-notes/2021-09-08-add-flow-from-default-values.md new file mode 100644 index 00000000000..8a65028216c --- /dev/null +++ b/python/change-notes/2021-09-08-add-flow-from-default-values.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Function parameters with default values will now see flow from those values. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 69a46a9e354..44c64234b75 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -209,9 +209,6 @@ module EssaFlow { nodeTo = TKwOverflowNode(call, callable) and nodeFrom.asCfgNode() = call.getNode().getKwargs().getAFlowNode() ) - or - // Default value for parameter flows to that parameter - defaultValueFlowStep(nodeFrom, nodeTo) } predicate useToNextUse(NameNode nodeFrom, NameNode nodeTo) { @@ -872,6 +869,9 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) { module_export(mv.getScope(), r.getAttributeName(), nodeFrom) and nodeTo = r ) + or + // Default value for parameter flows to that parameter + defaultValueFlowStep(nodeFrom, nodeTo) } /** diff --git a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py b/python/ql/test/experimental/dataflow/coverage/argumentPassing.py index cbbac6c0d68..94a9e512313 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py +++ b/python/ql/test/experimental/dataflow/coverage/argumentPassing.py @@ -66,9 +66,9 @@ def argument_passing( b, /, c, - d=arg4, + d=arg4, #$ arg4 func=argument_passing *, - e=arg5, + e=arg5, #$ arg5 func=argument_passing f, **g, ): @@ -120,7 +120,7 @@ def test_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): # Need a mechanism to test default arguments +def with_default_arguments(a=arg1, b=arg2, c=arg3): #$ arg1 arg2 arg3 func=with_default_arguments SINK1(a) SINK2(b) SINK3(c) diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected index ea80fa74c96..78b27fa507b 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected @@ -14,6 +14,8 @@ edges | argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | argumentPassing.py:120:5:120:70 | KwUnpacked a | | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | +| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | +| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | | argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | argumentPassing.py:139:11:139:13 | ControlFlowNode for foo | | argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | @@ -102,6 +104,8 @@ nodes | argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | semmle.label | ControlFlowNode for Dict [Dictionary element at key a] | | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 | | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | +| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | +| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 | | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 | | argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | @@ -206,6 +210,7 @@ nodes | argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found | +| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:139:11:139:13 | ControlFlowNode for foo | Flow found | | argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | argumentPassing.py:166:15:166:15 | ControlFlowNode for a | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected index b5188b55a9e..fb8b9f03785 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected @@ -10,6 +10,8 @@ edges | argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | argumentPassing.py:120:5:120:70 | KwUnpacked b | | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | +| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | +| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | | argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key bar] | argumentPassing.py:140:20:140:25 | ControlFlowNode for kwargs [Dictionary element at key bar] | | argumentPassing.py:140:5:140:26 | KwUnpacked bar | argumentPassing.py:145:18:145:20 | ControlFlowNode for bar | @@ -64,6 +66,8 @@ nodes | argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] | | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 | | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 | | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 | | argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key bar] | semmle.label | ControlFlowNode for kwargs [Dictionary element at key bar] | @@ -127,6 +131,7 @@ nodes | argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | argumentPassing.py:99:11:99:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | argumentPassing.py:111:11:111:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:111:11:111:11 | ControlFlowNode for b | Flow found | +| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | argumentPassing.py:146:11:146:13 | ControlFlowNode for bar | Flow found | | classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:556:15:556:17 | ControlFlowNode for key | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected index 0d359646a7e..9a222aa1752 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected @@ -10,6 +10,8 @@ edges | argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | argumentPassing.py:120:5:120:70 | KwUnpacked c | | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | +| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | +| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | | argumentPassing.py:134:5:134:41 | KwUnpacked c | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | | argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | argumentPassing.py:134:5:134:41 | KwUnpacked c | | argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | @@ -37,6 +39,8 @@ nodes | argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | semmle.label | ControlFlowNode for Dict [Dictionary element at key c] | | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 | | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | +| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | +| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 | | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | | argumentPassing.py:134:5:134:41 | KwUnpacked c | semmle.label | KwUnpacked c | | argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | semmle.label | ControlFlowNode for Dict [Dictionary element at key c] | @@ -58,6 +62,7 @@ nodes | argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found | +| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:155:11:155:13 | ControlFlowNode for baz | Flow found | | classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:571:15:571:19 | ControlFlowNode for value | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected index 58e3dda0964..f900e73321f 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected @@ -1,3 +1,9 @@ edges +| argumentPassing.py:69:5:69:5 | ControlFlowNode for d | argumentPassing.py:78:11:78:11 | ControlFlowNode for d | +| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:69:5:69:5 | ControlFlowNode for d | nodes +| argumentPassing.py:69:5:69:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | semmle.label | ControlFlowNode for arg4 | +| argumentPassing.py:78:11:78:11 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | #select +| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:78:11:78:11 | ControlFlowNode for d | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected index 58e3dda0964..34faff92a78 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected @@ -1,3 +1,9 @@ edges +| argumentPassing.py:71:5:71:5 | ControlFlowNode for e | argumentPassing.py:79:11:79:11 | ControlFlowNode for e | +| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:71:5:71:5 | ControlFlowNode for e | nodes +| argumentPassing.py:71:5:71:5 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | +| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | semmle.label | ControlFlowNode for arg5 | +| argumentPassing.py:79:11:79:11 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | #select +| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:79:11:79:11 | ControlFlowNode for e | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/dataflow.expected b/python/ql/test/experimental/dataflow/coverage/dataflow.expected index a98fc0b5e2a..7839b46e382 100644 --- a/python/ql/test/experimental/dataflow/coverage/dataflow.expected +++ b/python/ql/test/experimental/dataflow/coverage/dataflow.expected @@ -347,6 +347,12 @@ edges | test.py:686:43:686:48 | ControlFlowNode for SOURCE | test.py:686:3:686:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | | test.py:686:51:686:51 | ControlFlowNode for s | test.py:686:3:686:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | | test.py:757:16:757:21 | ControlFlowNode for SOURCE | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | +| test.py:795:35:795:35 | ControlFlowNode for x | test.py:796:10:796:10 | ControlFlowNode for x | +| test.py:795:37:795:42 | ControlFlowNode for SOURCE | test.py:795:35:795:35 | ControlFlowNode for x | +| test.py:795:48:795:48 | ControlFlowNode for y | test.py:797:10:797:10 | ControlFlowNode for y | +| test.py:795:50:795:55 | ControlFlowNode for SOURCE | test.py:795:48:795:48 | ControlFlowNode for y | +| test.py:795:61:795:61 | ControlFlowNode for z | test.py:798:10:798:10 | ControlFlowNode for z | +| test.py:795:63:795:68 | ControlFlowNode for SOURCE | test.py:795:61:795:61 | ControlFlowNode for z | nodes | datamodel.py:38:6:38:17 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() | | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | @@ -758,6 +764,15 @@ nodes | test.py:686:51:686:51 | ControlFlowNode for s | semmle.label | ControlFlowNode for s | | test.py:757:16:757:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | semmle.label | ControlFlowNode for return_from_inner_scope() | +| test.py:795:35:795:35 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:795:37:795:42 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:795:48:795:48 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| test.py:795:50:795:55 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:795:61:795:61 | ControlFlowNode for z | semmle.label | ControlFlowNode for z | +| test.py:795:63:795:68 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:796:10:796:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:797:10:797:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| test.py:798:10:798:10 | ControlFlowNode for z | semmle.label | ControlFlowNode for z | #select | datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | Flow found | | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | Flow found | @@ -865,3 +880,6 @@ nodes | test.py:680:10:680:12 | ControlFlowNode for arg | test.py:685:7:685:12 | ControlFlowNode for SOURCE | test.py:680:10:680:12 | ControlFlowNode for arg | Flow found | | test.py:680:10:680:12 | ControlFlowNode for arg | test.py:686:43:686:48 | ControlFlowNode for SOURCE | test.py:680:10:680:12 | ControlFlowNode for arg | Flow found | | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | test.py:757:16:757:21 | ControlFlowNode for SOURCE | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | Flow found | +| test.py:796:10:796:10 | ControlFlowNode for x | test.py:795:37:795:42 | ControlFlowNode for SOURCE | test.py:796:10:796:10 | ControlFlowNode for x | Flow found | +| test.py:797:10:797:10 | ControlFlowNode for y | test.py:795:50:795:55 | ControlFlowNode for SOURCE | test.py:797:10:797:10 | ControlFlowNode for y | Flow found | +| test.py:798:10:798:10 | ControlFlowNode for z | test.py:795:63:795:68 | ControlFlowNode for SOURCE | test.py:798:10:798:10 | ControlFlowNode for z | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/test.py b/python/ql/test/experimental/dataflow/coverage/test.py index c7d5f063eb9..906ece07952 100644 --- a/python/ql/test/experimental/dataflow/coverage/test.py +++ b/python/ql/test/experimental/dataflow/coverage/test.py @@ -793,6 +793,6 @@ def test_reverse_read_subscript_cls(): @expects(3) def test_with_default_param_value(x=SOURCE, /, y=SOURCE, *, z=SOURCE): - SINK(x) #$ MISSING:flow="SOURCE, l:-1 -> x" - SINK(y) #$ MISSING:flow="SOURCE, l:-2 -> y" - SINK(z) #$ MISSING:flow="SOURCE, l:-3 -> z" + SINK(x) #$ flow="SOURCE, l:-1 -> x" + SINK(y) #$ flow="SOURCE, l:-2 -> y" + SINK(z) #$ flow="SOURCE, l:-3 -> z" From 5d137ce9c5cf354eedc299b997d98103622ccd1d Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 10 Sep 2021 13:35:49 +0200 Subject: [PATCH 3/3] Python: Update test expectations --- .../ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected b/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected index 1043b6003f2..abc90874349 100644 --- a/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected +++ b/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected @@ -1,7 +1,5 @@ | code/h_classes.py:3:1:3:16 | ControlFlowNode for ClassExpr | code/h_classes.py:10:1:10:9 | ControlFlowNode for type() | | code/h_classes.py:3:1:3:16 | ControlFlowNode for ClassExpr | code/h_classes.py:15:5:15:13 | ControlFlowNode for type() | -| code/l_calls.py:3:13:3:14 | ControlFlowNode for List | code/l_calls.py:4:12:4:12 | ControlFlowNode for x | -| code/l_calls.py:6:13:6:14 | ControlFlowNode for List | code/l_calls.py:7:16:7:16 | ControlFlowNode for x | | code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:16:16:16:18 | ControlFlowNode for cls | | code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:24:13:24:22 | ControlFlowNode for Attribute() | | code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:25:16:25:16 | ControlFlowNode for a |