Skip to content

Commit f74653b

Browse files
author
Esben Sparre Andreasen
committed
JS: extract getDefaultNode from DefaultRange
1 parent d2fa7aa commit f74653b

File tree

7 files changed

+37
-31
lines changed

7 files changed

+37
-31
lines changed

javascript/ql/src/semmle/javascript/AMD.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ private class AmdDependencyImport extends Import {
263263
not exists(super.getImportedModule()) and
264264
result = resolveByAbsolutePath()
265265
}
266+
267+
override DataFlow::Node getDefaultNode() {
268+
exists(Parameter param |
269+
any(AmdModuleDefinition def).dependencyParameter(this, param) and
270+
result = DataFlow::parameterNode(param)
271+
)
272+
}
266273
}
267274

268275
/**

javascript/ql/src/semmle/javascript/ES2015Modules.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ class ImportDeclaration extends Stmt, Import, @importdeclaration {
4343

4444
/** Gets an import specifier of this import declaration. */
4545
ImportSpecifier getASpecifier() { result = getSpecifier(_) }
46+
47+
override DataFlow::Node getDefaultNode() {
48+
// `import * as http from 'http'` or `import http from `http`'
49+
exists(ImportSpecifier is |
50+
is = getASpecifier() and
51+
result = DataFlow::ssaDefinitionNode(SSA::definition(is))
52+
|
53+
is instanceof ImportNamespaceSpecifier and
54+
count(getASpecifier()) = 1
55+
or
56+
is.getImportedName() = "default"
57+
)
58+
or
59+
// `import { createServer } from 'http'`
60+
result = DataFlow::destructuredModuleImportNode(this)
61+
}
4662
}
4763

4864
/** A literal path expression appearing in an `import` declaration. */

javascript/ql/src/semmle/javascript/Expr.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,8 @@ class DynamicImportExpr extends @dynamicimport, Expr, Import {
15621562
override PathExpr getImportedPath() { result = getSource() }
15631563

15641564
override Module getEnclosingModule() { result = getTopLevel() }
1565+
1566+
override DataFlow::Node getDefaultNode() { result = DataFlow::valueNode(this) }
15651567
}
15661568

15671569
/** A literal path expression appearing in a dynamic import. */

javascript/ql/src/semmle/javascript/Modules.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ abstract class Import extends ASTNode {
160160
result = resolveFromTypeRoot()
161161
)
162162
}
163+
164+
/**
165+
* Gets the data flow node that the default import of this import is available at.
166+
*/
167+
abstract DataFlow::Node getDefaultNode();
163168
}
164169

165170
/**

javascript/ql/src/semmle/javascript/NodeJS.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ class Require extends CallExpr, Import {
234234
priority - (prioritiesPerCandidate() * r + numberOfExtensions() + 1))
235235
)
236236
}
237+
238+
override DataFlow::Node getDefaultNode() { result = DataFlow::valueNode(this) }
237239
}
238240

239241
/** An argument to `require` or `require.resolve`, considered as a path expression. */

javascript/ql/src/semmle/javascript/TypeScript.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ class ExternalModuleReference extends Expr, Import, @externalmodulereference {
212212
override ControlFlowNode getFirstControlFlowNode() {
213213
result = getExpression().getFirstControlFlowNode()
214214
}
215+
216+
override DataFlow::Node getDefaultNode() { result = DataFlow::valueNode(this) }
215217
}
216218

217219
/** A literal path expression appearing in an external module reference. */

javascript/ql/src/semmle/javascript/dataflow/Nodes.qll

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -461,37 +461,9 @@ module ModuleImportNode {
461461
string path;
462462

463463
DefaultRange() {
464-
// `require("http")`
465-
exists(Require req | req.getImportedPath().getValue() = path |
466-
this = DataFlow::valueNode(req)
467-
)
468-
or
469-
// `import http = require("http")`
470-
exists(ExternalModuleReference req | req.getImportedPath().getValue() = path |
471-
this = DataFlow::valueNode(req)
472-
)
473-
or
474-
// `import * as http from 'http'` or `import http from `http`'
475-
exists(ImportDeclaration id, ImportSpecifier is |
476-
id.getImportedPath().getValue() = path and
477-
is = id.getASpecifier() and
478-
this = DataFlow::ssaDefinitionNode(SSA::definition(is))
479-
|
480-
is instanceof ImportNamespaceSpecifier and
481-
count(id.getASpecifier()) = 1
482-
or
483-
is.getImportedName() = "default"
484-
)
485-
or
486-
// `import { createServer } from 'http'`
487-
exists(ImportDeclaration id |
488-
this = DataFlow::destructuredModuleImportNode(id) and
489-
id.getImportedPath().getValue() = path
490-
)
491-
or
492-
// declared AMD dependency
493-
exists(AmdModuleDefinition amd |
494-
this = DataFlow::parameterNode(amd.getDependencyParameter(path))
464+
exists(Import i |
465+
this = i.getDefaultNode() and
466+
i.getImportedPath().getValue() = path
495467
)
496468
or
497469
// AMD require

0 commit comments

Comments
 (0)