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

Skip to content

Commit 77a4d81

Browse files
committed
Python: Improve import * handling
1 parent ec38464 commit 77a4d81

1 file changed

Lines changed: 19 additions & 13 deletions

File tree

python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
private import python
99
private import semmle.python.dataflow.new.DataFlow
10+
private import semmle.python.dataflow.new.internal.ImportResolution
1011
private import semmle.python.ApiGraphs
1112
private import semmle.python.filters.Tests
1213

@@ -85,7 +86,8 @@ module NotExposed {
8586
or
8687
newDirectAlias(spec, newModelFullyQualified, ast, mod, loc)
8788
or
88-
newImportStar(spec, newModelFullyQualified, ast, mod, _, _, loc)
89+
newImportAlias(spec, newModelFullyQualified, mod, _, _, loc) and
90+
ast = mod
8991
)
9092
}
9193

@@ -177,18 +179,22 @@ module NotExposed {
177179
isAllowedModule(mod)
178180
}
179181

180-
/** same as `newDirectAlias` predicate, but handling `from <module> import *`, considering all `<member>`, where `<module>.<member>` belongs to `spec`. */
181-
predicate newImportStar(
182-
FindSubclassesSpec spec, string newAliasFullyQualified, ImportStar importStar, Module mod,
183-
API::Node relevantClass, string relevantName, Location loc
182+
/**
183+
* same as `newDirectAlias` predicate, but written in a generic way to handle any import (also import *).
184+
*
185+
* it might be safe to delete `newDirectAlias` with this in place, but have not done the testing yet.
186+
*/
187+
predicate newImportAlias(
188+
FindSubclassesSpec spec, string newAliasFullyQualified, Module mod, DataFlow::Node def,
189+
string relevantName, Location loc
184190
) {
185-
relevantClass = newOrExistingModeling(spec) and
186-
loc = importStar.getLocation() and
187-
importStar.getScope() = mod and
188-
// WHAT A HACK :D :D
189-
relevantClass.getPath() =
190-
relevantClass.getAPredecessor().getPath() + ".getMember(\"" + relevantName + "\")" and
191-
relevantClass.getAPredecessor().getAValueReachableFromSource().asExpr() = importStar.getModule() and
191+
loc = mod.getLocation() and
192+
exists(API::Node relevantClass, ClassExpr classExpr |
193+
relevantClass = newOrExistingModeling(spec).getASubclass*() and
194+
ImportResolution::module_export(mod, relevantName, def) and
195+
classExpr = relevantClass.asSource().asExpr() and
196+
classExpr = def.asVar().getDefinition().(AssignmentDefinition).getValue().getNode()
197+
) and
192198
(
193199
mod.isPackageInit() and
194200
newAliasFullyQualified = mod.getPackageName() + "." + relevantName
@@ -202,7 +208,7 @@ module NotExposed {
202208
mod.declaredInAll(relevantName)
203209
) and
204210
not alreadyExplicitlyModeled(spec, newAliasFullyQualified) and
205-
not isTestCode(importStar) and
211+
not isTestCode(mod) and
206212
isAllowedModule(mod)
207213
}
208214

0 commit comments

Comments
 (0)