Skip to content

Commit ef1bde5

Browse files
committed
Fixed issue where streams would not be tracked via chainable methods
1 parent f39bf62 commit ef1bde5

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

javascript/ql/src/Quality/UnhandledStreamPipe.ql

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,40 @@ class PipeCall extends DataFlow::MethodCallNode {
3030
*/
3131
string getEventHandlerMethodName() { result = ["on", "once", "addListener"] }
3232

33+
/**
34+
* Gets the method names that are chainable on Node.js streams.
35+
*/
36+
string getChainableStreamMethodName() {
37+
result =
38+
[
39+
"setEncoding", "pause", "resume", "unpipe", "destroy", "cork", "uncork", "setDefaultEncoding",
40+
"off", "removeListener", getEventHandlerMethodName()
41+
]
42+
}
43+
3344
/**
3445
* A call to register an event handler on a Node.js stream.
3546
* This includes methods like `on`, `once`, and `addListener`.
3647
*/
3748
class StreamEventRegistration extends DataFlow::MethodCallNode {
3849
StreamEventRegistration() { this.getMethodName() = getEventHandlerMethodName() }
39-
40-
/** Gets the stream (receiver of the event handler). */
41-
DataFlow::Node getStream() { result = this.getReceiver() }
4250
}
4351

4452
/**
4553
* Models flow relationships between streams and related operations.
4654
* Connects destination streams to their corresponding pipe call nodes.
47-
* Connects streams to their event handler registration nodes.
55+
* Connects streams to their chainable methods.
4856
*/
4957
predicate streamFlowStep(DataFlow::Node streamNode, DataFlow::Node relatedNode) {
5058
exists(PipeCall pipe |
5159
streamNode = pipe.getDestinationStream() and
5260
relatedNode = pipe
5361
)
5462
or
55-
exists(StreamEventRegistration handler |
56-
streamNode = handler.getStream() and
57-
relatedNode = handler
63+
exists(DataFlow::MethodCallNode chainable |
64+
chainable.getMethodName() = getChainableStreamMethodName() and
65+
streamNode = chainable.getReceiver() and
66+
relatedNode = chainable
5867
)
5968
}
6069

javascript/ql/test/query-tests/Quality/UnhandledStreamPipe/test.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
| test.js:109:26:109:37 | s.pipe(dest) | Stream pipe without error handling on the source stream. Errors won't propagate downstream and may be silently dropped. |
99
| test.js:116:5:116:21 | stream.pipe(dest) | Stream pipe without error handling on the source stream. Errors won't propagate downstream and may be silently dropped. |
1010
| test.js:125:5:125:26 | getStre ... e(dest) | Stream pipe without error handling on the source stream. Errors won't propagate downstream and may be silently dropped. |
11-
| test.js:139:5:139:87 | stream. ... itable) | Stream pipe without error handling on the source stream. Errors won't propagate downstream and may be silently dropped. |
1211
| test.js:143:5:143:62 | stream. ... itable) | Stream pipe without error handling on the source stream. Errors won't propagate downstream and may be silently dropped. |
1312
| test.js:147:5:147:28 | notStre ... itable) | Stream pipe without error handling on the source stream. Errors won't propagate downstream and may be silently dropped. |
1413
| test.js:151:20:151:43 | notStre ... itable) | Stream pipe without error handling on the source stream. Errors won't propagate downstream and may be silently dropped. |

javascript/ql/test/query-tests/Quality/UnhandledStreamPipe/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ function test() {
136136
}
137137
{ // Long chained pipe with error handler
138138
const stream = getStream();
139-
stream.pause().on('error', handleError).setEncoding('utf8').resume().pipe(writable); // $SPURIOUS:Alert
139+
stream.pause().on('error', handleError).setEncoding('utf8').resume().pipe(writable);
140140
}
141141
{ // Long chained pipe without error handler
142142
const stream = getStream();

0 commit comments

Comments
 (0)