diff --git a/javascript/ql/lib/semmle/javascript/AMD.qll b/javascript/ql/lib/semmle/javascript/AMD.qll index 20b1c26275a..b28dd5b9b72 100644 --- a/javascript/ql/lib/semmle/javascript/AMD.qll +++ b/javascript/ql/lib/semmle/javascript/AMD.qll @@ -61,7 +61,13 @@ class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range } /** Gets the `i`th dependency of this module definition. */ - PathExpr getDependency(int i) { result = this.getDependencies().getElement(i) } + PathExpr getDependency(int i) { + exists(Expr expr | + expr = this.getDependencies().getElement(i) and + not isPseudoDependency(expr.getStringValue()) and + result = expr + ) + } /** Gets a dependency of this module definition. */ PathExpr getADependency() { @@ -102,9 +108,10 @@ class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range /** * Holds if `p` is the parameter corresponding to dependency `dep`. */ - predicate dependencyParameter(PathExpr dep, Parameter p) { + predicate dependencyParameter(Expr dep, Parameter p) { exists(int i | - dep = this.getDependency(i) and + // Note: to avoid spurious recursion, do not depend on PathExpr here + dep = this.getDependencies().getElement(i) and p = this.getFactoryParameter(i) ) } @@ -122,9 +129,9 @@ class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range * `dep1` and `dep2`. */ Parameter getDependencyParameter(string name) { - exists(PathExpr dep | + exists(Expr dep | this.dependencyParameter(dep, result) and - dep.getValue() = name + name = dep.getStringValue() ) } @@ -202,11 +209,15 @@ class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range } } +private predicate isPseudoDependency(string s) { s = ["exports", "require", "module"] } + /** An AMD dependency, considered as a path expression. */ private class AmdDependencyPath extends PathExprCandidate { AmdDependencyPath() { exists(AmdModuleDefinition amd | - this = amd.getDependencies().getAnElement() or + this = amd.getDependencies().getAnElement() and + not isPseudoDependency(this.getStringValue()) + or this = amd.getARequireCall().getAnArgument() ) } diff --git a/javascript/ql/test/library-tests/AMD/tests.expected b/javascript/ql/test/library-tests/AMD/tests.expected index 265a7f291df..ce9d6f60f5d 100644 --- a/javascript/ql/test/library-tests/AMD/tests.expected +++ b/javascript/ql/test/library-tests/AMD/tests.expected @@ -61,7 +61,6 @@ amdModuleDefinition | umd.js:4:9:4:43 | define( ... actory) | umd.js:1:18:1:24 | factory | | umd.js:4:9:4:43 | define( ... actory) | umd.js:9:9:14:1 | functio ... };\\n} | amdModuleDependencies -| tst2.js:1:1:3:2 | define( ... 42;\\n}) | tst2.js:1:9:1:17 | 'exports' | | tst3.js:1:1:3:2 | define( ... 42;\\n}) | tst3.js:2:21:2:25 | './a' | | tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:2:9:2:14 | 'a.js' | | tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:3:9:3:13 | 'foo' |