Skip to content

Commit a254a84

Browse files
authored
Merge pull request #1489 from markshannon/python-fix-nested-import-stars
Python: fix nested import stars
2 parents 1c91b92 + 9bf67e1 commit a254a84

File tree

7 files changed

+30
-8
lines changed

7 files changed

+30
-8
lines changed

python/ql/src/semmle/python/objects/Modules.qll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,8 @@ class PackageObjectInternal extends ModuleObjectInternal, TPackageObject {
177177
or
178178
exists(Module init |
179179
init = this.getSourceModule() and
180-
(
181-
/* There is no variable shadowing the name of the child module */
182-
not exists(EssaVariable var | var.getAUse() = init.getANormalExit() and var.getSourceVariable().getName() = name)
183-
or
184-
/* The variable shadowing the name of the child module is undefined at exit */
185-
ModuleAttributes::pointsToAtExit(init, name, ObjectInternal::undefined(), _)
186-
) and
180+
/* The variable shadowing the name of the child module is undefined at exit */
181+
ModuleAttributes::pointsToAtExit(init, name, ObjectInternal::undefined(), _) and
187182
not name = "__init__" and
188183
value = this.submodule(name) and
189184
origin = CfgOrigin::fromObject(value)
@@ -249,6 +244,7 @@ class PythonModuleObjectInternal extends ModuleObjectInternal, TPythonModule {
249244
}
250245

251246
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
247+
value != ObjectInternal::undefined() and
252248
ModuleAttributes::pointsToAtExit(this.getSourceModule(), name, value, origin)
253249
}
254250

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| nested/__init__.py:1:6:1:12 | ControlFlowNode for ImportExpr | import | nested/nested.py:0:0:0:0 | Module nested.nested |
2+
| nested/nested.py:1:1:1:13 | ControlFlowNode for FunctionExpr | import | nested/nested.py:1:1:1:13 | Function nested |
3+
| test.py:1:6:1:11 | ControlFlowNode for ImportExpr | import | file://:0:0:0:0 | Package nested |
4+
| test.py:2:1:2:6 | ControlFlowNode for nested | import | nested/nested.py:1:1:1:13 | Function nested |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
import python
3+
4+
from ControlFlowNode f, Context ctx, Value v, ControlFlowNode origin
5+
where
6+
f.pointsTo(ctx, v, origin)
7+
select f, ctx, v
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .nested import *
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def nested():
2+
pass
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from nested import *
2+
nested

python/ql/test/library-tests/PointsTo/new/Sanity.ql

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,17 @@ predicate ssa_sanity(string clsname, string problem, string what) {
109109
)
110110
}
111111

112+
predicate undefined_sanity(string clsname, string problem, string what) {
113+
/* Variables may be undefined, but values cannot be */
114+
exists(ControlFlowNode f |
115+
PointsToInternal::pointsTo(f, _, ObjectInternal::undefined(), _) and
116+
clsname = f.getAQlClass() and not clsname = "AnyNode" and
117+
problem = " points-to an undefined variable" and
118+
what = f.toString()
119+
)
120+
}
121+
112122
from string clsname, string problem, string what
113-
where ssa_sanity(clsname, problem, what)
123+
where ssa_sanity(clsname, problem, what) or undefined_sanity(clsname, problem, what)
114124
select clsname, what, problem
115125

0 commit comments

Comments
 (0)