Skip to content

Commit 4297c11

Browse files
committed
JS: Parameterise the module (still only one instantiation)
1 parent 2594bc4 commit 4297c11

File tree

1 file changed

+49
-20
lines changed

1 file changed

+49
-20
lines changed

javascript/ql/lib/semmle/javascript/ApiGraphs.qll

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,17 @@ module API {
794794
hasSemantics(imp)
795795
}
796796

797+
private signature module StageInputSig {
798+
predicate isAdditionalUseRoot(Node node);
799+
800+
predicate isAdditionalDefRoot(Node node);
801+
802+
bindingset[node]
803+
predicate inScope(DataFlow::Node node);
804+
}
805+
797806
cached
798-
private module Stage {
807+
private module Stage<StageInputSig S> {
799808
/**
800809
* Holds if `rhs` is the right-hand side of a definition of a node that should have an
801810
* incoming edge from `base` labeled `lbl` in the API graph.
@@ -988,9 +997,11 @@ module API {
988997
*/
989998
cached
990999
predicate rhs(TApiNode nd, DataFlow::Node rhs) {
1000+
(S::inScope(rhs) or S::isAdditionalDefRoot(nd)) and
9911001
exists(string m | nd = MkModuleExport(m) | exports(m, rhs))
9921002
or
9931003
rhs(_, _, rhs) and
1004+
S::inScope(rhs) and
9941005
nd = MkDef(rhs)
9951006
}
9961007

@@ -1218,30 +1229,37 @@ module API {
12181229
*/
12191230
cached
12201231
predicate use(TApiNode nd, DataFlow::Node ref) {
1221-
exists(string m, Module mod | nd = MkModuleDef(m) and mod = importableModule(m) |
1222-
ref = DataFlow::moduleVarNode(mod)
1223-
)
1224-
or
1225-
exists(string m, Module mod | nd = MkModuleExport(m) and mod = importableModule(m) |
1226-
ref = DataFlow::exportsVarNode(mod)
1232+
(S::inScope(ref) or S::isAdditionalUseRoot(nd)) and
1233+
(
1234+
exists(string m, Module mod | nd = MkModuleDef(m) and mod = importableModule(m) |
1235+
ref = DataFlow::moduleVarNode(mod)
1236+
)
12271237
or
1228-
exists(DataFlow::Node base | use(MkModuleDef(m), base) |
1229-
ref = trackUseNode(base).getAPropertyRead("exports")
1238+
exists(string m, Module mod | nd = MkModuleExport(m) and mod = importableModule(m) |
1239+
ref = DataFlow::exportsVarNode(mod)
1240+
or
1241+
exists(DataFlow::Node base | use(MkModuleDef(m), base) |
1242+
ref = trackUseNode(base).getAPropertyRead("exports")
1243+
)
1244+
)
1245+
or
1246+
exists(string m |
1247+
nd = MkModuleImport(m) and
1248+
ref = DataFlow::moduleImport(m)
12301249
)
1231-
)
1232-
or
1233-
exists(string m |
1234-
nd = MkModuleImport(m) and
1235-
ref = DataFlow::moduleImport(m)
1236-
)
1237-
or
1238-
exists(DataFlow::ClassNode cls | nd = MkClassInstance(cls) |
1239-
ref = cls.getAReceiverNode()
12401250
or
1241-
ref = cls.(DataFlow::ClassNode).getAPrototypeReference()
1251+
exists(DataFlow::ClassNode cls | nd = MkClassInstance(cls) |
1252+
ref = cls.getAReceiverNode()
1253+
or
1254+
ref = cls.(DataFlow::ClassNode).getAPrototypeReference()
1255+
)
12421256
)
12431257
or
12441258
use(_, _, ref) and
1259+
S::inScope(ref) and
1260+
nd = MkUse(ref)
1261+
or
1262+
S::isAdditionalUseRoot(nd) and
12451263
nd = MkUse(ref)
12461264
}
12471265

@@ -1481,7 +1499,18 @@ module API {
14811499
}
14821500
}
14831501

1484-
import Stage
1502+
private module Stage1Input implements StageInputSig {
1503+
pragma[inline]
1504+
predicate isAdditionalUseRoot(Node node) { none() }
1505+
1506+
pragma[inline]
1507+
predicate isAdditionalDefRoot(Node node) { none() }
1508+
1509+
bindingset[node]
1510+
predicate inScope(DataFlow::Node node) { any() }
1511+
}
1512+
1513+
import Stage<Stage1Input>
14851514

14861515
/**
14871516
* Holds if there is an edge from `pred` to `succ` in the API graph.

0 commit comments

Comments
 (0)