Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b10cf78

Browse files
committed
Python: start handling iterated unpacking
1 parent 4ee2f49 commit b10cf78

3 files changed

Lines changed: 29 additions & 6 deletions

File tree

python/ql/src/semmle/python/dataflow/new/internal/DataFlowPrivate.qll

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,15 @@ module EssaFlow {
126126
nodeFrom.(CfgNode).getNode() =
127127
nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue()
128128
or
129+
// Definition
130+
// `a, b = iterable`
131+
// nodeFrom = `iterable`, cfg node
132+
// nodeTo = `a, b`, cfg node
133+
exists(Assign assign, SequenceNode target | target.getNode() = assign.getATarget() |
134+
nodeFrom.asExpr() = assign.getValue() and
135+
nodeTo.asCfgNode() = target
136+
)
137+
or
129138
// With definition
130139
// `with f(42) as x:`
131140
// nodeFrom is `f(42)`, cfg node
@@ -1104,12 +1113,13 @@ module unpackinAssignment {
11041113
}
11051114

11061115
predicate unpackingAssignmentDirectFlowStep(CfgNode nodeFrom, CfgNode nodeTo) {
1107-
// `a, b = iterable`
1108-
// nodeFrom = `iterable`
1109-
// readNode = `a, b`
1116+
// `a, *b = iterable`
1117+
// nodeFrom = `a, b`
1118+
// nodeTo = `*b`
11101119
exists(Assign assign, SequenceNode target | target.getNode() = assign.getATarget() |
1111-
nodeFrom.asExpr() = assign.getValue() and
1112-
nodeTo.getNode() = target
1120+
nodeFrom.getNode() = target and
1121+
nodeTo.getNode() = target.getAnElement() and
1122+
nodeTo.asExpr() instanceof Starred
11131123
)
11141124
}
11151125

python/ql/test/experimental/dataflow/coverage/dataflow.expected

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,14 @@ edges
205205
| test.py:530:12:530:12 | SSA variable c | test.py:533:10:533:10 | ControlFlowNode for c |
206206
| test.py:546:10:546:15 | ControlFlowNode for SOURCE | test.py:546:10:546:34 | ControlFlowNode for Tuple [Tuple element at index 0] |
207207
| test.py:546:10:546:34 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:5:547:12 | ControlFlowNode for Tuple [Tuple element at index 0] |
208+
| test.py:546:10:546:34 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:8:547:9 | ControlFlowNode for Starred [Tuple element at index 0] |
208209
| test.py:547:5:547:5 | SSA variable a | test.py:548:10:548:10 | ControlFlowNode for a |
209210
| test.py:547:5:547:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:5:547:5 | SSA variable a |
211+
| test.py:547:5:547:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:8:547:9 | ControlFlowNode for Starred [Tuple element at index 0] |
212+
| test.py:547:5:547:12 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 0] | test.py:547:8:547:9 | SSA variable b [Tuple element at index 0] |
213+
| test.py:547:8:547:9 | ControlFlowNode for Starred [Tuple element at index 0] | test.py:547:5:547:12 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 0] |
214+
| test.py:547:8:547:9 | SSA variable b [Tuple element at index 0] | test.py:549:10:549:10 | ControlFlowNode for b [Tuple element at index 0] |
215+
| test.py:549:10:549:10 | ControlFlowNode for b [Tuple element at index 0] | test.py:549:10:549:13 | ControlFlowNode for Subscript |
210216
| test.py:555:10:555:61 | ControlFlowNode for List [List element, List element] | test.py:558:28:558:29 | ControlFlowNode for ll [List element, List element] |
211217
| test.py:555:10:555:61 | ControlFlowNode for List [List element, List element] | test.py:566:5:566:24 | ControlFlowNode for List [List element, List element] |
212218
| test.py:555:10:555:61 | ControlFlowNode for List [List element, List element] | test.py:566:28:566:29 | ControlFlowNode for ll [List element, List element] |
@@ -469,7 +475,12 @@ nodes
469475
| test.py:546:10:546:34 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
470476
| test.py:547:5:547:5 | SSA variable a | semmle.label | SSA variable a |
471477
| test.py:547:5:547:12 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
478+
| test.py:547:5:547:12 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 0] |
479+
| test.py:547:8:547:9 | ControlFlowNode for Starred [Tuple element at index 0] | semmle.label | ControlFlowNode for Starred [Tuple element at index 0] |
480+
| test.py:547:8:547:9 | SSA variable b [Tuple element at index 0] | semmle.label | SSA variable b [Tuple element at index 0] |
472481
| test.py:548:10:548:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
482+
| test.py:549:10:549:10 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] |
483+
| test.py:549:10:549:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
473484
| test.py:555:10:555:61 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
474485
| test.py:555:11:555:37 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
475486
| test.py:555:12:555:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
@@ -629,6 +640,8 @@ nodes
629640
| test.py:533:10:533:10 | ControlFlowNode for c | test.py:529:30:529:35 | ControlFlowNode for SOURCE | test.py:533:10:533:10 | ControlFlowNode for c | Flow found |
630641
| test.py:548:10:548:10 | ControlFlowNode for a | test.py:20:10:20:17 | ControlFlowNode for Str | test.py:548:10:548:10 | ControlFlowNode for a | Flow found |
631642
| test.py:548:10:548:10 | ControlFlowNode for a | test.py:546:10:546:15 | ControlFlowNode for SOURCE | test.py:548:10:548:10 | ControlFlowNode for a | Flow found |
643+
| test.py:549:10:549:13 | ControlFlowNode for Subscript | test.py:20:10:20:17 | ControlFlowNode for Str | test.py:549:10:549:13 | ControlFlowNode for Subscript | Flow found |
644+
| test.py:549:10:549:13 | ControlFlowNode for Subscript | test.py:546:10:546:15 | ControlFlowNode for SOURCE | test.py:549:10:549:13 | ControlFlowNode for Subscript | Flow found |
632645
| test.py:559:10:559:11 | ControlFlowNode for a1 | test.py:20:10:20:17 | ControlFlowNode for Str | test.py:559:10:559:11 | ControlFlowNode for a1 | Flow found |
633646
| test.py:559:10:559:11 | ControlFlowNode for a1 | test.py:555:12:555:17 | ControlFlowNode for SOURCE | test.py:559:10:559:11 | ControlFlowNode for a1 | Flow found |
634647
| test.py:559:10:559:11 | ControlFlowNode for a1 | test.py:555:31:555:36 | ControlFlowNode for SOURCE | test.py:559:10:559:11 | ControlFlowNode for a1 | Flow found |

python/ql/test/experimental/dataflow/coverage/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ def test_iterated_unpacking_assignment():
546546
t = (SOURCE, SOURCE, NONSOURCE)
547547
a, *b, c = t
548548
SINK(a)
549-
SINK(b[0]) # Flow not found
549+
SINK(b[0])
550550
SINK_F(c)
551551

552552

0 commit comments

Comments
 (0)