Skip to content

Commit 4d24be0

Browse files
authored
Merge pull request github#6688 from RasmusWL/small-fix
Python: Fix `globals() == locals()` FP
2 parents 3bdc92b + f402475 commit 4d24be0

File tree

4 files changed

+27
-16
lines changed

4 files changed

+27
-16
lines changed

python/ql/src/Statements/ModificationOfLocals.ql

+7-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,11 @@ predicate modification_of_locals(ControlFlowNode f) {
3030
}
3131

3232
from AstNode a, ControlFlowNode f
33-
where modification_of_locals(f) and a = f.getNode()
33+
where
34+
modification_of_locals(f) and
35+
a = f.getNode() and
36+
// in module level scope `locals() == globals()`
37+
// see https://docs.python.org/3/library/functions.html#locals
38+
// FP report in https://github.com/github/codeql/issues/6674
39+
not a.getScope() instanceof ModuleScope
3440
select a, "Modification of the locals() dictionary will have no effect on the local variables."
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
| test.py:109:5:109:8 | cond | Parenthesized condition in 'if' statement. |
2-
| test.py:112:8:112:11 | cond | Parenthesized condition in 'while' statement. |
3-
| test.py:115:9:115:12 | test | Parenthesized test in 'assert' statement. |
4-
| test.py:118:13:118:13 | x | Parenthesized value in 'return' statement. |
1+
| test.py:115:5:115:8 | cond | Parenthesized condition in 'if' statement. |
2+
| test.py:118:8:118:11 | cond | Parenthesized condition in 'while' statement. |
3+
| test.py:121:9:121:12 | test | Parenthesized test in 'assert' statement. |
4+
| test.py:124:13:124:13 | x | Parenthesized value in 'return' statement. |
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| test.py:162:9:162:17 | Attribute() | Instance of context-manager class $@ is closed in a finally block. Consider using 'with' statement. | test.py:145:1:145:17 | class CM | CM |
1+
| test.py:168:9:168:17 | Attribute() | Instance of context-manager class $@ is closed in a finally block. Consider using 'with' statement. | test.py:151:1:151:17 | class CM | CM |

python/ql/test/query-tests/Statements/general/test.py

+15-10
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def return_in_finally(seq, x):
1818
finally:
1919
return 1
2020
return 0
21-
21+
2222
#Break in loop in finally
2323
#This is OK
2424
def return_in_loop_in_finally(f, seq):
@@ -27,7 +27,7 @@ def return_in_loop_in_finally(f, seq):
2727
finally:
2828
for i in seq:
2929
break
30-
30+
3131
#But this is not
3232
def return_in_loop_in_finally(f, seq):
3333
try:
@@ -49,7 +49,7 @@ def __init__(self):
4949

5050
for x in NonIterator():
5151
do_something(x)
52-
52+
5353
#None in for loop
5454

5555
def dodgy_iter(x):
@@ -91,8 +91,8 @@ class D(dict): pass
9191

9292

9393

94-
95-
94+
95+
9696
def modification_of_locals():
9797
x = 0
9898
locals()['x'] = 1
@@ -104,6 +104,12 @@ def modification_of_locals():
104104
return x
105105

106106

107+
globals()['foo'] = 42 # OK
108+
# in module-level scope `locals() == globals()`
109+
# FP report from https://github.com/github/codeql/issues/6674
110+
locals()['foo'] = 43 # technically OK
111+
112+
107113
#C-style things
108114

109115
if (cond):
@@ -128,7 +134,7 @@ def __get__(self, instance, instance_type):
128134
return self.getter(instance_type)
129135

130136
class WithClassProperty(object):
131-
137+
132138
@classproperty
133139
def x(self):
134140
return [0]
@@ -143,13 +149,13 @@ def x(self):
143149
#Should use context mamager
144150

145151
class CM(object):
146-
152+
147153
def __enter__(self):
148154
pass
149-
155+
150156
def __exit__(self, ex, cls, tb):
151157
pass
152-
158+
153159
def write(self, data):
154160
pass
155161

@@ -168,4 +174,3 @@ def assert_ok(seq):
168174
# False positive. ODASA-8042. Fixed in PR #2401.
169175
class false_positive:
170176
e = (x for x in [])
171-

0 commit comments

Comments
 (0)