Skip to content

Commit 066568e

Browse files
committed
add promise tracking to Files.qll
1 parent a24bc56 commit 066568e

2 files changed

Lines changed: 22 additions & 9 deletions

File tree

javascript/ql/src/semmle/javascript/frameworks/Files.qll

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ private class GlobFileNameSource extends FileNameSource {
5959

6060
/**
6161
* Gets a file name or an array of file names from the `globby` library.
62+
* The predicate uses type-tracking. However, type-tracking is only used to track a step out of a promise.
6263
*/
6364
private DataFlow::SourceNode globbyFileNameSource(DataFlow::TypeTracker t) {
6465
exists(string moduleName | moduleName = "globby" |
@@ -67,13 +68,14 @@ private DataFlow::SourceNode globbyFileNameSource(DataFlow::TypeTracker t) {
6768
result = DataFlow::moduleMember(moduleName, "sync").getACall()
6869
or
6970
// `files` in `require('globby')(_).then(files => ...)`
70-
t.start() and
71-
result =
72-
DataFlow::moduleImport(moduleName)
73-
.getACall()
74-
.getAMethodCall("then")
75-
.getCallback(0)
76-
.getParameter(0)
71+
t = PromiseTypeTracking::valueInPromiseTracker() and
72+
result = DataFlow::moduleImport(moduleName).getACall()
73+
)
74+
or
75+
// Tracking out of a promise
76+
exists(DataFlow::TypeTracker t2, DataFlow::StepSummary summary |
77+
result = PromiseTypeTracking::promiseStep(globbyFileNameSource(t2), summary) and
78+
t = t2.append(summary)
7779
)
7880
}
7981

@@ -86,6 +88,7 @@ private class GlobbyFileNameSource extends FileNameSource {
8688

8789
/**
8890
* Gets a file name or an array of file names from the `fast-glob` library.
91+
* The predicate uses type-tracking. However, type-tracking is only used to track a step out of a promise.
8992
*/
9093
private DataFlow::Node fastGlobFileNameSource(DataFlow::TypeTracker t) {
9194
exists(string moduleName | moduleName = "fast-glob" |
@@ -100,8 +103,8 @@ private DataFlow::Node fastGlobFileNameSource(DataFlow::TypeTracker t) {
100103
|
101104
// `files` in `require('fast-glob')(_).then(files => ...)` and
102105
// `files` in `require('fast-glob').async(_).then(files => ...)`
103-
t.start() and
104-
result = f.getACall().getAMethodCall("then").getCallback(0).getParameter(0)
106+
t = PromiseTypeTracking::valueInPromiseTracker() and
107+
result = f.getACall()
105108
)
106109
or
107110
// `file` in `require('fast-glob').stream(_).on(_, file => ...)`
@@ -113,6 +116,12 @@ private DataFlow::Node fastGlobFileNameSource(DataFlow::TypeTracker t) {
113116
.getCallback(1)
114117
.getParameter(0)
115118
)
119+
or
120+
// Tracking out of a promise
121+
exists(DataFlow::TypeTracker t2, DataFlow::StepSummary summary |
122+
result = PromiseTypeTracking::promiseStep(fastGlobFileNameSource(t2), summary) and
123+
t = t2.append(summary)
124+
)
116125
}
117126

118127
/**

javascript/ql/test/library-tests/frameworks/Concepts/FileNameSource.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@
1010
| tst-file-names.js:25:18:25:22 | files |
1111
| tst-file-names.js:27:24:27:28 | files |
1212
| tst-file-names.js:29:27:29:30 | file |
13+
| tst-file-names.js:32:34:32:38 | files |
14+
| tst-file-names.js:34:15:34:29 | await globby(_) |
15+
| tst-file-names.js:36:16:36:38 | await f ... sync(_) |
16+
| tst-file-names.js:38:16:38:57 | await f ... => {}) |

0 commit comments

Comments
 (0)