Skip to content

Commit 4091cf4

Browse files
author
Max Schaefer
committed
JavaScript: Improve detection of require calls.
1 parent 7aef8fa commit 4091cf4

File tree

6 files changed

+52
-20
lines changed

6 files changed

+52
-20
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,13 @@ predicate findNodeModulesFolder(Folder f, Folder nodeModules, int distance) {
132132
*/
133133
private class RequireVariable extends Variable {
134134
RequireVariable() {
135-
exists (ModuleScope m | this = m.getVariable("require"))
135+
this = any(ModuleScope m).getVariable("require")
136+
or
137+
// cover cases where we failed to detect Node.js code
138+
this.(GlobalVariable).getName() = "require"
139+
or
140+
// track through assignments to other variables
141+
this.getAnAssignedExpr().(VarAccess).getVariable() instanceof RequireVariable
136142
}
137143
}
138144

@@ -149,7 +155,9 @@ private predicate moduleInFile(Module m, File f) {
149155
class Require extends CallExpr, Import {
150156
Require() {
151157
exists (RequireVariable req |
152-
this.getCallee() = req.getAnAccess()
158+
this.getCallee() = req.getAnAccess() and
159+
// `mjs` files explicitly disallow `require`
160+
getFile().getExtension() != "mjs"
153161
)
154162
}
155163

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
| a.js:1:9:1:22 | require('./b') | ./b | b.js:1:1:8:0 | <toplevel> |
2-
| a.js:3:6:3:23 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
3-
| a.js:4:6:4:29 | require ... /d.js') | ./sub/../d.js | d.js:1:1:7:15 | <toplevel> |
4-
| a.js:7:1:7:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
5-
| a.js:10:1:10:18 | require(__dirname) | | index.js:1:1:3:0 | <toplevel> |
6-
| a.js:11:1:11:25 | require ... + '/e') | /e | e.js:1:1:7:0 | <toplevel> |
7-
| a.js:12:1:12:28 | require ... + 'c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
8-
| b.js:1:1:1:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
9-
| d.js:7:1:7:14 | require('foo') | foo | sub/f.js:1:1:4:17 | <toplevel> |
10-
| index.js:2:1:2:41 | require ... b.js")) | /index.js/../b.js | b.js:1:1:8:0 | <toplevel> |
11-
| mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') | ./depend-on-me | mjs-files/depend-on-me.mjs:1:1:7:1 | <toplevel> |
12-
| mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') | ./depend-on-me.js | mjs-files/depend-on-me.js:1:1:8:0 | <toplevel> |
13-
| mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') | ./depend-on-me.mjs | mjs-files/depend-on-me.mjs:1:1:7:1 | <toplevel> |
14-
| sub/c.js:1:1:1:15 | require('../a') | ../a | a.js:1:1:14:0 | <toplevel> |
1+
| a.js:1:9:1:22 | require('./b') |
2+
| a.js:2:7:2:19 | require('fs') |
3+
| a.js:3:6:3:23 | require('./sub/c') |
4+
| a.js:4:6:4:29 | require ... /d.js') |
5+
| a.js:7:1:7:18 | require('./sub/c') |
6+
| a.js:10:1:10:18 | require(__dirname) |
7+
| a.js:11:1:11:25 | require ... + '/e') |
8+
| a.js:12:1:12:28 | require ... + 'c') |
9+
| b.js:1:1:1:18 | require('./sub/c') |
10+
| d.js:1:1:1:38 | require ... s/ini') |
11+
| d.js:7:1:7:14 | require('foo') |
12+
| f.js:2:1:2:7 | r("fs") |
13+
| index.js:1:12:1:26 | require('path') |
14+
| index.js:2:1:2:41 | require ... b.js")) |
15+
| mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') |
16+
| mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') |
17+
| mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') |
18+
| sub/c.js:1:1:1:15 | require('../a') |
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import semmle.javascript.NodeJS
22

3-
from Require r, string fullpath, string prefix
4-
where fullpath = r.getImportedPath().getValue() and
5-
sourceLocationPrefix(prefix)
6-
select r, fullpath.replaceAll(prefix, ""), r.getImportedModule()
3+
from Require r
4+
select r
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
| a.js:1:9:1:22 | require('./b') | ./b | b.js:1:1:8:0 | <toplevel> |
2+
| a.js:3:6:3:23 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
3+
| a.js:4:6:4:29 | require ... /d.js') | ./sub/../d.js | d.js:1:1:7:15 | <toplevel> |
4+
| a.js:7:1:7:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
5+
| a.js:10:1:10:18 | require(__dirname) | | index.js:1:1:3:0 | <toplevel> |
6+
| a.js:11:1:11:25 | require ... + '/e') | /e | e.js:1:1:7:0 | <toplevel> |
7+
| a.js:12:1:12:28 | require ... + 'c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
8+
| b.js:1:1:1:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | <toplevel> |
9+
| d.js:7:1:7:14 | require('foo') | foo | sub/f.js:1:1:4:17 | <toplevel> |
10+
| index.js:2:1:2:41 | require ... b.js")) | /index.js/../b.js | b.js:1:1:8:0 | <toplevel> |
11+
| mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') | ./depend-on-me | mjs-files/depend-on-me.mjs:1:1:7:1 | <toplevel> |
12+
| mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') | ./depend-on-me.js | mjs-files/depend-on-me.js:1:1:8:0 | <toplevel> |
13+
| mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') | ./depend-on-me.mjs | mjs-files/depend-on-me.mjs:1:1:7:1 | <toplevel> |
14+
| sub/c.js:1:1:1:15 | require('../a') | ../a | a.js:1:1:14:0 | <toplevel> |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import semmle.javascript.NodeJS
2+
3+
from Require r, string fullpath, string prefix
4+
where fullpath = r.getImportedPath().getValue() and
5+
sourceLocationPrefix(prefix)
6+
select r, fullpath.replaceAll(prefix, ""), r.getImportedModule()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
var r = require;
2+
r("fs");

0 commit comments

Comments
 (0)