Skip to content

Commit 97b3ebe

Browse files
authored
Merge pull request #14380 from asgerf/js/amd-range
JS: Add AmdModuleDefinition::Range
2 parents b231b1c + 3152728 commit 97b3ebe

File tree

5 files changed

+45
-15
lines changed

5 files changed

+45
-15
lines changed

Diff for: javascript/ql/lib/semmle/javascript/AMD.qll

+29-15
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,34 @@ import javascript
77
private import semmle.javascript.internal.CachedStages
88
private import Expressions.ExprHasNoEffect
99

10+
/**
11+
* Companion module to the `AmdModuleDefinition` class.
12+
*/
13+
module AmdModuleDefinition {
14+
/**
15+
* A class that can be extended to treat calls as instances of `AmdModuleDefinition`.
16+
*
17+
* Subclasses should not depend on imports or `DataFlow::Node`.
18+
*/
19+
abstract class Range extends CallExpr { }
20+
21+
private class DefaultRange extends Range {
22+
DefaultRange() {
23+
inVoidContext(this) and
24+
this.getCallee().(GlobalVarAccess).getName() = "define" and
25+
exists(int n | n = this.getNumArgument() |
26+
n = 1
27+
or
28+
n = 2 and this.getArgument(0) instanceof ArrayExpr
29+
or
30+
n = 3 and
31+
this.getArgument(0) instanceof ConstantString and
32+
this.getArgument(1) instanceof ArrayExpr
33+
)
34+
}
35+
}
36+
}
37+
1038
/**
1139
* An AMD `define` call.
1240
*
@@ -25,21 +53,7 @@ private import Expressions.ExprHasNoEffect
2553
* where the first argument is the module name, the second argument an
2654
* array of dependencies, and the third argument a factory method or object.
2755
*/
28-
class AmdModuleDefinition extends CallExpr {
29-
AmdModuleDefinition() {
30-
inVoidContext(this) and
31-
this.getCallee().(GlobalVarAccess).getName() = "define" and
32-
exists(int n | n = this.getNumArgument() |
33-
n = 1
34-
or
35-
n = 2 and this.getArgument(0) instanceof ArrayExpr
36-
or
37-
n = 3 and
38-
this.getArgument(0) instanceof ConstantString and
39-
this.getArgument(1) instanceof ArrayExpr
40-
)
41-
}
42-
56+
class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range {
4357
/** Gets the array of module dependencies, if any. */
4458
ArrayExpr getDependencies() {
4559
result = this.getArgument(0) or
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added the `AmdModuleDefinition::Range` class, making it possible to define custom aliases for the AMD `define` function.

Diff for: javascript/ql/test/library-tests/AMD/test_range.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
test.amd.range(function() {
2+
return { foo: 42 };
3+
});

Diff for: javascript/ql/test/library-tests/AMD/tests.expected

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ amoModule_exports
44
| lib/a.js:1:1:3:3 | <toplevel> | foo | lib/a.js:2:19:2:20 | 42 |
55
| lib/foo.js:1:1:4:0 | <toplevel> | foo | lib/foo.js:2:10:2:11 | 23 |
66
| lib/nested/a.js:1:1:3:3 | <toplevel> | foo | lib/nested/a.js:2:19:2:20 | 42 |
7+
| test_range.js:1:1:4:0 | <toplevel> | foo | test_range.js:2:19:2:20 | 42 |
78
| tst2.js:1:1:3:3 | <toplevel> | foo | tst2.js:2:19:2:20 | 42 |
89
| tst3.js:1:1:3:3 | <toplevel> | foo | tst3.js:2:43:2:44 | 42 |
910
| tst4.js:1:1:11:3 | <toplevel> | bar | tst4.js:9:14:9:18 | b.bar |
@@ -22,6 +23,7 @@ amdModule
2223
| lib/a.js:1:1:3:3 | <toplevel> | lib/a.js:1:1:3:2 | define( ... 2 };\\n}) |
2324
| lib/foo.js:1:1:4:0 | <toplevel> | lib/foo.js:1:1:3:2 | define( ... : 23\\n}) |
2425
| lib/nested/a.js:1:1:3:3 | <toplevel> | lib/nested/a.js:1:1:3:2 | define( ... 2 };\\n}) |
26+
| test_range.js:1:1:4:0 | <toplevel> | test_range.js:1:1:3:2 | test.am ... 2 };\\n}) |
2527
| tst2.js:1:1:3:3 | <toplevel> | tst2.js:1:1:3:2 | define( ... 42;\\n}) |
2628
| tst3.js:1:1:3:3 | <toplevel> | tst3.js:1:1:3:2 | define( ... 42;\\n}) |
2729
| tst4.js:1:1:11:3 | <toplevel> | tst4.js:1:1:11:2 | define( ... };\\n}) |
@@ -48,6 +50,7 @@ amdModuleDefinition
4850
| lib/a.js:1:1:3:2 | define( ... 2 };\\n}) | lib/a.js:1:8:3:1 | functio ... 42 };\\n} |
4951
| lib/foo.js:1:1:3:2 | define( ... : 23\\n}) | lib/foo.js:1:8:3:1 | {\\n foo: 23\\n} |
5052
| lib/nested/a.js:1:1:3:2 | define( ... 2 };\\n}) | lib/nested/a.js:1:8:3:1 | functio ... 42 };\\n} |
53+
| test_range.js:1:1:3:2 | test.am ... 2 };\\n}) | test_range.js:1:16:3:1 | functio ... 42 };\\n} |
5154
| tst2.js:1:1:3:2 | define( ... 42;\\n}) | tst2.js:1:21:3:1 | functio ... = 42;\\n} |
5255
| tst3.js:1:1:3:2 | define( ... 42;\\n}) | tst3.js:1:8:3:1 | functio ... = 42;\\n} |
5356
| tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:6:11:11:1 | functio ... };\\n} |
@@ -78,6 +81,7 @@ amdModuleExportedSymbol
7881
| lib/a.js:1:1:3:3 | <toplevel> | foo |
7982
| lib/foo.js:1:1:4:0 | <toplevel> | foo |
8083
| lib/nested/a.js:1:1:3:3 | <toplevel> | foo |
84+
| test_range.js:1:1:4:0 | <toplevel> | foo |
8185
| tst2.js:1:1:3:3 | <toplevel> | foo |
8286
| tst3.js:1:1:3:3 | <toplevel> | foo |
8387
| tst4.js:1:1:11:3 | <toplevel> | bar |
@@ -96,6 +100,7 @@ amdModuleExpr
96100
| lib/a.js:1:1:3:2 | define( ... 2 };\\n}) | lib/a.js:2:12:2:22 | { foo: 42 } | lib/a.js:2:12:2:22 | { foo: 42 } |
97101
| lib/foo.js:1:1:3:2 | define( ... : 23\\n}) | lib/foo.js:1:8:3:1 | {\\n foo: 23\\n} | lib/foo.js:1:8:3:1 | {\\n foo: 23\\n} |
98102
| lib/nested/a.js:1:1:3:2 | define( ... 2 };\\n}) | lib/nested/a.js:2:12:2:22 | { foo: 42 } | lib/nested/a.js:2:12:2:22 | { foo: 42 } |
103+
| test_range.js:1:1:3:2 | test.am ... 2 };\\n}) | test_range.js:2:12:2:22 | { foo: 42 } | test_range.js:2:12:2:22 | { foo: 42 } |
99104
| tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:7:12:10:5 | {\\n ... r\\n } | tst4.js:7:12:10:5 | {\\n ... r\\n } |
100105
| tst5.js:1:1:6:2 | define( ... };\\n}) | tst5.js:2:12:5:5 | {\\n ... r\\n } | tst5.js:2:12:5:5 | {\\n ... r\\n } |
101106
| tst.js:1:1:6:2 | define( ... };\\n}) | tst.js:2:12:5:5 | {\\n ... r\\n } | tst.js:2:12:5:5 | {\\n ... r\\n } |

Diff for: javascript/ql/test/library-tests/AMD/tests.ql

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import javascript
22

3+
class TestAmdModuleRange extends AmdModuleDefinition::Range {
4+
TestAmdModuleRange() { this.getCallee().(PropAccess).getQualifiedName() = "test.amd.range" }
5+
}
6+
37
query predicate amoModule_exports(Module m, string name, DataFlow::Node exportValue) {
48
exportValue = m.getAnExportedValue(name)
59
}

0 commit comments

Comments
 (0)