Skip to content

Commit 7891f86

Browse files
authored
Merge pull request github#2982 from esbena/js/request-model-with-chaining
Approved by asgerf
2 parents ddc2f97 + db335ae commit 7891f86

File tree

4 files changed

+40
-16
lines changed

4 files changed

+40
-16
lines changed

change-notes/1.24/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [http2](https://nodejs.org/api/http2.html)
3333
- [lazy-cache](https://www.npmjs.com/package/lazy-cache)
3434
- [react](https://www.npmjs.com/package/react)
35+
- [request](https://www.npmjs.com/package/request)
3536
- [send](https://www.npmjs.com/package/send)
3637
- [typeahead.js](https://www.npmjs.com/package/typeahead.js)
3738
- [ws](https://github.com/websockets/ws)

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

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -110,29 +110,37 @@ module ClientRequest {
110110
*/
111111
private string httpMethodName() { result = any(HTTP::RequestMethodName m).toLowerCase() }
112112

113+
/**
114+
* Gets a model of an instance of the `request` library, or one of
115+
* its wrappers, `promise` is true if the instance uses promises
116+
* rather than callbacks.
117+
*/
118+
private DataFlow::SourceNode getRequestLibrary(boolean promise) {
119+
exists(string moduleName | result = DataFlow::moduleImport(moduleName) |
120+
promise = false and
121+
moduleName = "request"
122+
or
123+
promise = true and
124+
(
125+
moduleName = "request-promise" or
126+
moduleName = "request-promise-any" or
127+
moduleName = "request-promise-native"
128+
)
129+
)
130+
or
131+
result = getRequestLibrary(promise).getAMethodCall("defaults")
132+
}
133+
113134
/**
114135
* A model of a URL request made using the `request` library.
115136
*/
116137
class RequestUrlRequest extends ClientRequest::Range, DataFlow::CallNode {
117138
boolean promise;
118139

119140
RequestUrlRequest() {
120-
exists(string moduleName, DataFlow::SourceNode callee | this = callee.getACall() |
121-
(
122-
promise = false and
123-
moduleName = "request"
124-
or
125-
promise = true and
126-
(
127-
moduleName = "request-promise" or
128-
moduleName = "request-promise-any" or
129-
moduleName = "request-promise-native"
130-
)
131-
) and
132-
(
133-
callee = DataFlow::moduleImport(moduleName) or
134-
callee = DataFlow::moduleMember(moduleName, httpMethodName())
135-
)
141+
exists(DataFlow::SourceNode callee | this = callee.getACall() |
142+
callee = getRequestLibrary(promise) or
143+
callee = getRequestLibrary(promise).getAPropertyRead(httpMethodName())
136144
)
137145
}
138146

javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ test_ClientRequest
5252
| tst.js:147:5:147:19 | got.stream(url) |
5353
| tst.js:151:5:151:23 | superagent.get(url) |
5454
| tst.js:160:5:160:17 | xhr.send(url) |
55+
| tst.js:171:2:171:10 | base(url) |
56+
| tst.js:172:2:172:14 | variant1(url) |
57+
| tst.js:173:2:173:14 | variant2(url) |
5558
test_getADataNode
5659
| tst.js:53:5:53:23 | axios({data: data}) | tst.js:53:18:53:21 | data |
5760
| tst.js:57:5:57:39 | axios.p ... data2}) | tst.js:57:19:57:23 | data1 |
@@ -144,6 +147,9 @@ test_getUrl
144147
| tst.js:147:5:147:19 | got.stream(url) | tst.js:147:16:147:18 | url |
145148
| tst.js:151:5:151:23 | superagent.get(url) | tst.js:151:20:151:22 | url |
146149
| tst.js:160:5:160:17 | xhr.send(url) | tst.js:160:14:160:16 | url |
150+
| tst.js:171:2:171:10 | base(url) | tst.js:171:7:171:9 | url |
151+
| tst.js:172:2:172:14 | variant1(url) | tst.js:172:11:172:13 | url |
152+
| tst.js:173:2:173:14 | variant2(url) | tst.js:173:11:173:13 | url |
147153
test_getAResponseDataNode
148154
| tst.js:19:5:19:23 | requestPromise(url) | tst.js:19:5:19:23 | requestPromise(url) | text | true |
149155
| tst.js:21:5:21:23 | superagent.get(url) | tst.js:21:5:21:23 | superagent.get(url) | stream | true |

javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,12 @@ import {ClientRequest, net} from 'electron';
163163
xhr.getResponseHeaders();
164164
});
165165
})
166+
167+
(function() {
168+
let base = request;
169+
let variant1 = base.defaults({});
170+
let variant2 = variant1.defaults({});
171+
base(url);
172+
variant1(url);
173+
variant2(url);
174+
});

0 commit comments

Comments
 (0)