Skip to content

Commit 46af77c

Browse files
committed
Python: Include all assignments in data flow paths
Like Ruby did in github#12566
1 parent 9bd5694 commit 46af77c

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -513,15 +513,21 @@ class CastNode extends Node {
513513
* explanations.
514514
*/
515515
predicate neverSkipInPathGraph(Node n) {
516-
// We include read- and store steps here to force them to be
517-
// shown in path explanations.
518-
// This hack is necessary, because we have included some of these
519-
// steps as default taint steps, making them be suppressed in path
520-
// explanations.
521-
// We should revert this once, we can remove this steps from the
522-
// default taint steps; this should be possible once we have
523-
// implemented flow summaries and recursive content.
524-
readStep(_, _, n) or storeStep(_, _, n)
516+
// NOTE: We could use RHS of a definition, but since we have use-use flow, in an
517+
// example like
518+
// ```py
519+
// x = SOURCE()
520+
// if <cond>:
521+
// y = x
522+
// SINK(x)
523+
// ```
524+
// we would end up saying that the path MUST not skip the x in `y = x`, which is just
525+
// annoying and doesn't help the path explanation become clearer.
526+
n.asVar() instanceof EssaDefinition and
527+
// For a parameter we have flow from ControlFlowNode to SSA node, and then onwards
528+
// with use-use flow, and since the CFN is already part of the path graph, we don't
529+
// want to force showing the SSA node as well.
530+
not n.asVar() instanceof ParameterDefinition
525531
}
526532

527533
/**

python/ql/test/experimental/dataflow/path-graph/test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
def assign():
22
x = SOURCE # $ path-node
33

4-
y = x
4+
y = x # $ path-node
55

66
SINK(y) # $ path-node
77

@@ -10,7 +10,7 @@ def aug_assign():
1010
x = SOURCE # $ path-node
1111
z = ""
1212

13-
z += x
13+
z += x # $ path-node
1414

1515
SINK(z) # $ path-node
1616

@@ -41,7 +41,7 @@ class X: pass
4141
x = X()
4242
x.attr = SOURCE # $ path-node
4343

44-
y = x
44+
y = x # $ path-node
4545

4646
SINK(y.attr) # $ path-node
4747

@@ -81,7 +81,7 @@ def test_tuple():
8181
def test_with():
8282
x = SOURCE # $ path-node
8383

84-
with x as y:
84+
with x as y: # $ path-node
8585

8686
SINK(y) # $ path-node
8787

@@ -91,6 +91,6 @@ def test_match():
9191

9292
match x:
9393

94-
case y:
94+
case y: # $ path-node
9595

9696
SINK(y) # $ path-node

0 commit comments

Comments
 (0)