Skip to content

Commit 3801a15

Browse files
committed
remove module exporst nodes from API graphs
1 parent c3f4a85 commit 3801a15

File tree

4 files changed

+4
-67
lines changed

4 files changed

+4
-67
lines changed

python/ql/lib/semmle/python/ApiGraphs.qll

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -388,14 +388,13 @@ module API {
388388
// The `builtins` module should always be implicitly available
389389
name = "builtins"
390390
} or
391-
MkModuleExport(Module mod) or
392391
/** A use of an API member at the node `nd`. */
393392
MkUse(DataFlow::Node nd) { use(_, _, nd) } or
394393
MkDef(DataFlow::Node nd) { rhs(_, _, nd) }
395394

396395
class TUse = MkModuleImport or MkUse;
397396

398-
class TDef = MkDef or MkModuleExport;
397+
class TDef = MkDef;
399398

400399
/**
401400
* Holds if the dotted module name `sub` refers to the `member` member of `base`.
@@ -455,12 +454,6 @@ module API {
455454
*/
456455
cached
457456
predicate rhs(TApiNode base, Label::ApiLabel lbl, DataFlow::Node rhs) {
458-
exists(Module mod, string prop |
459-
base = MkModuleExport(mod) and
460-
exports(mod, prop, rhs) and
461-
lbl = Label::member(prop)
462-
)
463-
or
464457
exists(DataFlow::Node def, DataFlow::LocalSourceNode pred |
465458
rhs(base, def) and pred = trackDefNode(def)
466459
|
@@ -649,12 +642,7 @@ module API {
649642
* Holds if `rhs` is the right-hand side of a definition of node `nd`.
650643
*/
651644
cached
652-
predicate rhs(TApiNode nd, DataFlow::Node rhs) {
653-
// TODO: There are no "default" exports in python, right? E.g. in `import foo`, `foo` cannot be a function.
654-
// exists(string m | nd = MkModuleExport(m) | exports(m, rhs))
655-
// or
656-
nd = MkDef(rhs)
657-
}
645+
predicate rhs(TApiNode nd, DataFlow::Node rhs) { nd = MkDef(rhs) }
658646

659647
/**
660648
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
@@ -665,12 +653,9 @@ module API {
665653
exists(string m |
666654
pred = MkRoot() and
667655
lbl = Label::mod(m) and
656+
succ = MkModuleImport(m) and
668657
// Only allow undotted names to count as base modules.
669658
not m.matches("%.%")
670-
|
671-
succ = MkModuleImport(m)
672-
or
673-
succ = MkModuleExport(any(Module mod | mod.getName() = m and mod.isPackage()))
674659
)
675660
or
676661
/* Step from the dotted module name `foo.bar` to `foo.bar.baz` along an edge labeled `baz` */
@@ -685,14 +670,6 @@ module API {
685670
succ = MkUse(ref)
686671
)
687672
or
688-
exists(Module parentMod, Module childMod, string edge |
689-
pred = MkModuleExport(parentMod) and
690-
succ = MkModuleExport(childMod) and
691-
// TODO: __init__.py shows up here, maybe add some shortcut. Example code: https://stackoverflow.com/questions/38927979/default-export-in-python-3
692-
parentMod.getSubModule(edge) = childMod and
693-
lbl = Label::member(edge)
694-
)
695-
or
696673
exists(DataFlow::Node rhs |
697674
rhs(pred, lbl, rhs) and
698675
succ = MkDef(rhs)
@@ -725,20 +702,14 @@ module API {
725702

726703
newtype TLabel =
727704
MkLabelModule(string mod) {
728-
(
729-
exists(Impl::MkModuleImport(mod))
730-
or
731-
exists(Module m | exists(Impl::MkModuleExport(m)) | mod = m.getName())
732-
) and
705+
exists(Impl::MkModuleImport(mod)) and
733706
not mod.matches("%.%") // only top level modules count as base modules
734707
} or
735708
MkLabelMember(string member) {
736709
member = any(DataFlow::AttrRef pr).getAttributeName() or
737710
exists(Builtins::likelyBuiltin(member)) or
738711
ImportStar::namePossiblyDefinedInImportStar(_, member, _) or
739712
Impl::prefix_member(_, member, _) or
740-
exists(any(Module mod).getSubModule(member)) or
741-
exports(_, member, _) or
742713
member = any(Dict d).getAnItem().(KeyValuePair).getKey().(StrConst).getS()
743714
} or
744715
MkLabelUnknownMember() or
@@ -866,22 +837,3 @@ module API {
866837
LabelAwait await() { any() }
867838
}
868839
}
869-
870-
/** Holds if module `mod` exports `rhs` under the name `prop`. */
871-
private predicate exports(Module mod, string prop, DataFlow::Node rhs) {
872-
exists(Assign assign |
873-
assign = mod.getAStmt() and
874-
rhs.asExpr() = assign.getValue() and
875-
exists(Variable v | assign.defines(v) and prop = v.getId())
876-
)
877-
or
878-
// `from foo import *`, just forward directly.
879-
exists(ImportStar star, Module subMod |
880-
star.getEnclosingModule() = mod and
881-
mod.getPackage().getName() + "." + star.getImportedModuleName() = subMod.getName() and
882-
exports(subMod, prop, rhs)
883-
)
884-
// TODO: There should be a better way to do this, I'm just missing it.
885-
// TODO: named imports, which should probably be an edge, unless there is some way imports are just magically "handled".
886-
// TODO: use this predicate with __init__.py?
887-
}

python/ql/test/library-tests/ApiGraphs/py3/mypkg/__init__.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

python/ql/test/library-tests/ApiGraphs/py3/mypkg/bar.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

python/ql/test/library-tests/ApiGraphs/py3/mypkg/foo.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)