Skip to content

Commit 7cfe3da

Browse files
committed
JS: Port step for dynamic imports
1 parent 379952f commit 7cfe3da

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

javascript/ql/lib/semmle/javascript/Promises.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,6 @@ private module DynamicImportSteps {
705705
*/
706706
class DynamicImportStep extends LegacyPreCallGraphStep {
707707
override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
708-
// TODO: this step needs to be ported to dataflow2
709708
exists(DynamicImportExpr imprt |
710709
pred = imprt.getImportedModule().getAnExportedValue("default") and
711710
succ = imprt.flow() and

javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ private import Maps
99
private import Promises
1010
private import Sets
1111
private import Strings
12+
private import DynamicImportStep
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Contains flow steps to model flow from a module into a dynamic `import()` expression.
3+
*/
4+
5+
private import javascript
6+
private import semmle.javascript.dataflow.internal.DataFlowNode
7+
private import semmle.javascript.dataflow.internal.AdditionalFlowInternal
8+
private import semmle.javascript.dataflow.internal.DataFlowPrivate
9+
10+
/**
11+
* Flow steps for dynamic import expressions.
12+
*
13+
* The default export of the imported module must be boxed in a promise, so we pass
14+
* it through a synthetic node.
15+
*/
16+
class DynamicImportStep extends AdditionalFlowInternal {
17+
override predicate needsSynthesizedNode(AstNode node, string tag, DataFlowCallable container) {
18+
node instanceof DynamicImportExpr and
19+
tag = "imported-value" and
20+
container.asSourceCallable() = node.getContainer()
21+
}
22+
23+
override predicate jumpStep(DataFlow::Node pred, DataFlow::Node succ) {
24+
exists(DynamicImportExpr expr |
25+
pred = expr.getImportedModule().getAnExportedValue("default") and
26+
succ = getSynthesizedNode(expr, "imported-value")
27+
)
28+
}
29+
30+
override predicate storeStep(
31+
DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ
32+
) {
33+
exists(DynamicImportExpr expr |
34+
pred = getSynthesizedNode(expr, "imported-value") and
35+
contents = DataFlow::ContentSet::promiseValue() and
36+
succ = TValueNode(expr)
37+
)
38+
}
39+
}

0 commit comments

Comments
 (0)