Skip to content

Commit 479d81f

Browse files
committed
Python: fix nonlocal captured variables
This depends on the extractor fix
1 parent 38e0321 commit 479d81f

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ module LocalFlow {
299299
nodeTo.(CfgNode).getNode() = def.getDefiningNode()
300300
)
301301
or
302+
// General definition
303+
// TODO: remove other cases that are now redundant
304+
nodeFrom.(CfgNode).getNode() = nodeTo.(CfgNode).getNode().(DefinitionNode).getValue() and
305+
// remove jump steps (such as assignment of parameter default values)
306+
nodeFrom.getEnclosingCallable() = nodeTo.getEnclosingCallable()
307+
or
302308
// With definition
303309
// `with f(42) as x:`
304310
// nodeFrom is `f(42)`

python/ql/test/experimental/dataflow/variable-capture/nonlocal.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def captureOut1():
3838
nonlocal sinkO1
3939
sinkO1 = SOURCE
4040
captureOut1()
41-
SINK(sinkO1) #$ MISSING:captured
41+
SINK(sinkO1) #$ captured
4242

4343
sinkO2 = ""
4444
def captureOut2():
@@ -47,7 +47,7 @@ def m():
4747
sinkO2 = SOURCE
4848
m()
4949
captureOut2()
50-
SINK(sinkO2) #$ MISSING:captured
50+
SINK(sinkO2) #$ captured
5151

5252
nonSink1 = ""
5353
def captureOut1NotCalled():
@@ -74,7 +74,7 @@ def captureOut1():
7474
nonlocal sinkO1
7575
sinkO1 = tainted
7676
captureOut1()
77-
SINK(sinkO1) #$ MISSING:captured
77+
SINK(sinkO1) #$ captured
7878

7979
sinkO2 = ""
8080
def captureOut2():
@@ -83,7 +83,7 @@ def m():
8383
sinkO2 = tainted
8484
m()
8585
captureOut2()
86-
SINK(sinkO2) #$ MISSING:captured
86+
SINK(sinkO2) #$ captured
8787

8888
nonSink1 = ""
8989
def captureOut1NotCalled():

0 commit comments

Comments
 (0)