mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Fixed issue where streams would not be tracked via chainable methods
This commit is contained in:
@@ -30,21 +30,29 @@ class PipeCall extends DataFlow::MethodCallNode {
|
||||
*/
|
||||
string getEventHandlerMethodName() { result = ["on", "once", "addListener"] }
|
||||
|
||||
/**
|
||||
* Gets the method names that are chainable on Node.js streams.
|
||||
*/
|
||||
string getChainableStreamMethodName() {
|
||||
result =
|
||||
[
|
||||
"setEncoding", "pause", "resume", "unpipe", "destroy", "cork", "uncork", "setDefaultEncoding",
|
||||
"off", "removeListener", getEventHandlerMethodName()
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to register an event handler on a Node.js stream.
|
||||
* This includes methods like `on`, `once`, and `addListener`.
|
||||
*/
|
||||
class StreamEventRegistration extends DataFlow::MethodCallNode {
|
||||
StreamEventRegistration() { this.getMethodName() = getEventHandlerMethodName() }
|
||||
|
||||
/** Gets the stream (receiver of the event handler). */
|
||||
DataFlow::Node getStream() { result = this.getReceiver() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Models flow relationships between streams and related operations.
|
||||
* Connects destination streams to their corresponding pipe call nodes.
|
||||
* Connects streams to their event handler registration nodes.
|
||||
* Connects streams to their chainable methods.
|
||||
*/
|
||||
predicate streamFlowStep(DataFlow::Node streamNode, DataFlow::Node relatedNode) {
|
||||
exists(PipeCall pipe |
|
||||
@@ -52,9 +60,10 @@ predicate streamFlowStep(DataFlow::Node streamNode, DataFlow::Node relatedNode)
|
||||
relatedNode = pipe
|
||||
)
|
||||
or
|
||||
exists(StreamEventRegistration handler |
|
||||
streamNode = handler.getStream() and
|
||||
relatedNode = handler
|
||||
exists(DataFlow::MethodCallNode chainable |
|
||||
chainable.getMethodName() = getChainableStreamMethodName() and
|
||||
streamNode = chainable.getReceiver() and
|
||||
relatedNode = chainable
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
|
||||
@@ -136,7 +136,7 @@ function test() {
|
||||
}
|
||||
{ // Long chained pipe with error handler
|
||||
const stream = getStream();
|
||||
stream.pause().on('error', handleError).setEncoding('utf8').resume().pipe(writable); // $SPURIOUS:Alert
|
||||
stream.pause().on('error', handleError).setEncoding('utf8').resume().pipe(writable);
|
||||
}
|
||||
{ // Long chained pipe without error handler
|
||||
const stream = getStream();
|
||||
|
||||
Reference in New Issue
Block a user