Skip to content

Commit 84252fd

Browse files
committed
JS: Factor into parameterised module, show test failures
1 parent 1230200 commit 84252fd

4 files changed

Lines changed: 25 additions & 23 deletions

File tree

javascript/ql/lib/semmle/javascript/Modules.qll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import javascript
88
private import semmle.javascript.internal.CachedStages
9-
private import semmle.javascript.internal.paths.PathExprResolver as PathExprResolver
9+
private import semmle.javascript.internal.paths.PathExprResolver
1010

1111
/**
1212
* A module, which may either be an ECMAScript 2015-style module,
@@ -115,6 +115,10 @@ abstract class Module extends TopLevel {
115115
}
116116
}
117117

118+
private predicate shouldResolveExpr(Expr e) { e = any(Import imprt).getImportedPath() }
119+
120+
private module Resolver = ResolveExpr<shouldResolveExpr/1>;
121+
118122
/**
119123
* An import in a module, which may be an ECMAScript 2015-style
120124
* `import` statement, a CommonJS-style `require` import, or an AMD dependency.
@@ -139,9 +143,7 @@ abstract class Import extends AstNode {
139143
/**
140144
* Gets the module the path of this import resolves to.
141145
*/
142-
Module resolveImportedPath() {
143-
result.getFile() = PathExprResolver::resolvePathExpr(this.getImportedPath())
144-
}
146+
Module resolveImportedPath() { result.getFile() = Resolver::resolveExpr(this.getImportedPath()) }
145147

146148
/**
147149
* Gets a module with a `@providesModule` JSDoc tag that matches

javascript/ql/lib/semmle/javascript/internal/paths/PathExprResolver.qll

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ private import semmle.javascript.TSConfig
33
private import semmle.javascript.internal.paths.PackageJsonEx
44
private import semmle.javascript.internal.paths.JSPaths
55

6-
final private class FinalPathExpr = PathExpr;
76
File getFileFromFolderImport(Folder folder) {
87
result = folder.getJavaScriptFileOrTypings("index")
98
or
@@ -15,10 +14,16 @@ File getFileFromFolderImport(Folder folder) {
1514
)
1615
}
1716

17+
private signature predicate exprSig(Expr e);
1818

19-
private class RelevantPathExpr extends FinalPathExpr {
20-
pragma[nomagic]
21-
RelevantPathExpr() { this = any(Import imprt).getImportedPath() }
19+
module ResolveExpr<exprSig/1 shouldResolveExpr> {
20+
21+
private final class FinalExpr = Expr;
22+
23+
private class RelevantPathExpr extends FinalExpr {
24+
RelevantPathExpr() { shouldResolveExpr(this) }
25+
26+
string getValue() { result = this.getStringValue() }
2227
}
2328

2429
/**
@@ -65,7 +70,7 @@ private string getPackagePrefixFromPathExpr(RelevantPathExpr expr) {
6570
private Variable dirname() { result.getName() = "__dirname" }
6671

6772
/** Holds if `add` is a relevant path expression of form `__dirname + expr`. */
68-
private predicate prefixedByDirname(PathExpr expr) {
73+
private predicate prefixedByDirname(Expr expr) {
6974
expr = dirname().getAnAccess()
7075
or
7176
prefixedByDirname(expr.(AddExpr).getLeftOperand())
@@ -175,7 +180,7 @@ private Container resolvePathExpr1(RelevantPathExpr expr) {
175180
)
176181
}
177182

178-
File resolvePathExpr(PathExpr expr) {
183+
File resolveExpr(RelevantPathExpr expr) {
179184
result = resolvePathExpr1(expr)
180185
or
181186
result = getFileFromFolderImport(resolvePathExpr1(expr))
@@ -206,7 +211,7 @@ module Debug {
206211

207212
query Container resolvePathExpr1_(PathExprToDebug expr) { result = resolvePathExpr1(expr) }
208213

209-
query File resolvePathExpr_(PathExprToDebug expr) { result = resolvePathExpr(expr) }
214+
query File resolveExpr_(PathExprToDebug expr) { result = resolveExpr(expr) }
210215

211216
// Some predicates that are usually small enough that they don't need restriction
212217
query File getPackageMainFile(PackageJsonEx pkg) { result = pkg.getMainFile() }
@@ -217,3 +222,4 @@ module Debug {
217222

218223
query predicate getFileFromFolderImport_ = getFileFromFolderImport/1;
219224
}
225+
}

javascript/ql/test/library-tests/PathResolution/DirnameImports/main.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
const path = require('path');
33

44
// Using __dirname directly
5-
const direct = require(__dirname + '/target.js'); // $ importTarget=DirnameImports/target.js
5+
const direct = require(__dirname + '/target.js'); // $ MISSING: importTarget=DirnameImports/target.js
66

77
// Using __dirname with path.join
8-
const withPathJoin = require(path.join(__dirname, 'target.js')); // $ importTarget=DirnameImports/target.js
8+
const withPathJoin = require(path.join(__dirname, 'target.js')); // $ MISSING: importTarget=DirnameImports/target.js
99

1010
// Using __dirname with nested path
11-
const nested = require(__dirname + '/nested/target.js'); // $ importTarget=DirnameImports/nested/target.js
11+
const nested = require(__dirname + '/nested/target.js'); // $ MISSING: importTarget=DirnameImports/nested/target.js
1212

1313
// Using __dirname with parent directory
14-
const parent = require(__dirname + '/../import-packages.ts'); // $ importTarget=import-packages.ts
14+
const parent = require(__dirname + '/../import-packages.ts'); // $ MISSING: importTarget=import-packages.ts
1515

1616
// Using __dirname with path concat and variable
1717
const subdir = 'nested';
18-
const dynamic = require(__dirname + '/' + subdir + '/target.js'); // $ importTarget=DirnameImports/nested/target.js
18+
const dynamic = require(__dirname + '/' + subdir + '/target.js'); // $ MISSING: importTarget=DirnameImports/nested/target.js
1919

2020
// Using __dirname in an AddExpr chain
21-
const chainedAdd = require(__dirname + '/' + 'target.js'); // $ importTarget=DirnameImports/target.js
21+
const chainedAdd = require(__dirname + '/' + 'target.js'); // $ MISSING: importTarget=DirnameImports/target.js

javascript/ql/test/library-tests/PathResolution/test.expected

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,6 @@
4040
| DeclarationFiles/src/main.ts:5:1:5:27 | import ... cript"; | DeclarationFiles/lib/typescript.ts |
4141
| DeclarationFiles/src/main.ts:6:1:6:30 | import ... pt.js"; | DeclarationFiles/lib/typescript.ts |
4242
| DeclarationFiles/src/main.ts:7:1:7:32 | import ... .d.ts"; | DeclarationFiles/lib/typescript.d.ts |
43-
| DirnameImports/main.js:5:16:5:48 | require ... et.js') | DirnameImports/target.js |
44-
| DirnameImports/main.js:8:22:8:63 | require ... t.js')) | DirnameImports/target.js |
45-
| DirnameImports/main.js:11:16:11:55 | require ... et.js') | DirnameImports/nested/target.js |
46-
| DirnameImports/main.js:14:16:14:60 | require ... es.ts') | import-packages.ts |
47-
| DirnameImports/main.js:18:17:18:64 | require ... et.js') | DirnameImports/nested/target.js |
48-
| DirnameImports/main.js:21:20:21:57 | require ... et.js') | DirnameImports/target.js |
4943
| Extended/src/main.ts:2:1:2:21 | import ... /file"; | Extended/lib/file.ts |
5044
| Extended/src/main.ts:3:1:3:24 | import ... le.ts"; | Extended/lib/file.ts |
5145
| Extended/src/main.ts:4:1:4:24 | import ... le.js"; | Extended/lib/file.ts |

0 commit comments

Comments
 (0)