Skip to content

Commit 803aacf

Browse files
authored
Merge pull request #19068 from Napalys/js/superagent
JS: `superagent` modeling
2 parents b452479 + d61d038 commit 803aacf

File tree

6 files changed

+61
-3
lines changed

6 files changed

+61
-3
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Improved support for `superagent` to handle the case where the package is directly called as a function, or via the `.del()` or `.agent()` method.

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,17 +513,36 @@ module ClientRequest {
513513
}
514514
}
515515

516+
/**
517+
* Gets the name of a superagent request method.
518+
*/
519+
private string getSuperagentRequestMethodName() {
520+
result = [httpMethodName(), any(Http::RequestMethodName m), "del", "DEL"]
521+
}
522+
516523
/**
517524
* A model of a URL request made using the `superagent` library.
518525
*/
519526
class SuperAgentUrlRequest extends ClientRequest::Range {
520527
DataFlow::Node url;
521528

522529
SuperAgentUrlRequest() {
523-
exists(string moduleName, DataFlow::SourceNode callee | this = callee.getACall() |
524-
moduleName = "superagent" and
525-
callee = DataFlow::moduleMember(moduleName, httpMethodName()) and
530+
exists(string moduleName | moduleName = "superagent" |
531+
// Handle method calls like superagent.get(url)
532+
this = API::moduleImport(moduleName).getMember(getSuperagentRequestMethodName()).getACall() and
526533
url = this.getArgument(0)
534+
or
535+
// Handle direct calls like superagent('GET', url)
536+
this = API::moduleImport(moduleName).getACall() and
537+
this.getArgument(0).mayHaveStringValue(getSuperagentRequestMethodName()) and
538+
url = this.getArgument(1)
539+
or
540+
// Handle agent calls like superagent.agent().get(url)
541+
exists(DataFlow::SourceNode agent |
542+
agent = API::moduleImport(moduleName).getMember("agent").getACall() and
543+
this = agent.getAMethodCall(httpMethodName()) and
544+
url = this.getArgument(0)
545+
)
527546
)
528547
}
529548

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ test_ClientRequest
1010
| puppeteer.ts:6:11:6:42 | page.go ... e.com') |
1111
| puppeteer.ts:8:5:8:61 | page.ad ... css" }) |
1212
| puppeteer.ts:18:30:18:50 | page.go ... estUrl) |
13+
| superagent.js:4:5:4:26 | superag ... ', url) |
14+
| superagent.js:5:5:5:23 | superagent.del(url) |
15+
| superagent.js:6:5:6:32 | superag ... st(url) |
1316
| tst.js:11:5:11:16 | request(url) |
1417
| tst.js:13:5:13:20 | request.get(url) |
1518
| tst.js:15:5:15:23 | request.delete(url) |
@@ -91,9 +94,13 @@ test_ClientRequest
9194
| tst.js:286:20:286:55 | new Web ... :8080') |
9295
| tst.js:296:5:299:6 | axios({ ... \\n }) |
9396
| tst.js:312:12:312:36 | fetchPo ... o/bar') |
97+
| tst.js:319:5:319:26 | superag ... ', url) |
98+
| tst.js:320:5:320:23 | superagent.del(url) |
99+
| tst.js:321:5:321:32 | superag ... st(url) |
94100
test_getADataNode
95101
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } |
96102
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} |
103+
| superagent.js:6:5:6:32 | superag ... st(url) | superagent.js:6:39:6:42 | data |
97104
| tst.js:53:5:53:23 | axios({data: data}) | tst.js:53:18:53:21 | data |
98105
| tst.js:57:5:57:39 | axios.p ... data2}) | tst.js:57:19:57:23 | data1 |
99106
| tst.js:57:5:57:39 | axios.p ... data2}) | tst.js:57:33:57:37 | data2 |
@@ -132,6 +139,7 @@ test_getADataNode
132139
| tst.js:249:1:251:2 | form.su ... e();\\n}) | tst.js:247:24:247:68 | request ... o.png') |
133140
| tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:255:25:255:35 | 'new_value' |
134141
| tst.js:286:20:286:55 | new Web ... :8080') | tst.js:288:21:288:35 | 'Hello Server!' |
142+
| tst.js:321:5:321:32 | superag ... st(url) | tst.js:321:39:321:42 | data |
135143
test_getHost
136144
| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host |
137145
| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host |
@@ -154,6 +162,9 @@ test_getUrl
154162
| puppeteer.ts:6:11:6:42 | page.go ... e.com') | puppeteer.ts:6:21:6:41 | 'https: ... le.com' |
155163
| puppeteer.ts:8:5:8:61 | page.ad ... css" }) | puppeteer.ts:8:29:8:58 | "http:/ ... le.css" |
156164
| puppeteer.ts:18:30:18:50 | page.go ... estUrl) | puppeteer.ts:18:40:18:49 | requestUrl |
165+
| superagent.js:4:5:4:26 | superag ... ', url) | superagent.js:4:23:4:25 | url |
166+
| superagent.js:5:5:5:23 | superagent.del(url) | superagent.js:5:20:5:22 | url |
167+
| superagent.js:6:5:6:32 | superag ... st(url) | superagent.js:6:29:6:31 | url |
157168
| tst.js:11:5:11:16 | request(url) | tst.js:11:13:11:15 | url |
158169
| tst.js:13:5:13:20 | request.get(url) | tst.js:13:17:13:19 | url |
159170
| tst.js:15:5:15:23 | request.delete(url) | tst.js:15:20:15:22 | url |
@@ -240,9 +251,15 @@ test_getUrl
240251
| tst.js:296:5:299:6 | axios({ ... \\n }) | tst.js:296:11:299:5 | {\\n ... ,\\n } |
241252
| tst.js:296:5:299:6 | axios({ ... \\n }) | tst.js:298:14:298:44 | "http:/ ... -axios" |
242253
| tst.js:312:12:312:36 | fetchPo ... o/bar') | tst.js:312:26:312:35 | '/foo/bar' |
254+
| tst.js:319:5:319:26 | superag ... ', url) | tst.js:319:23:319:25 | url |
255+
| tst.js:320:5:320:23 | superagent.del(url) | tst.js:320:20:320:22 | url |
256+
| tst.js:321:5:321:32 | superag ... st(url) | tst.js:321:29:321:31 | url |
243257
test_getAResponseDataNode
244258
| axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true |
245259
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true |
260+
| superagent.js:4:5:4:26 | superag ... ', url) | superagent.js:4:5:4:26 | superag ... ', url) | stream | true |
261+
| superagent.js:5:5:5:23 | superagent.del(url) | superagent.js:5:5:5:23 | superagent.del(url) | stream | true |
262+
| superagent.js:6:5:6:32 | superag ... st(url) | superagent.js:6:5:6:32 | superag ... st(url) | stream | true |
246263
| tst.js:19:5:19:23 | requestPromise(url) | tst.js:19:5:19:23 | requestPromise(url) | text | true |
247264
| tst.js:21:5:21:23 | superagent.get(url) | tst.js:21:5:21:23 | superagent.get(url) | stream | true |
248265
| tst.js:25:5:25:14 | axios(url) | tst.js:25:5:25:14 | axios(url) | | true |
@@ -314,3 +331,6 @@ test_getAResponseDataNode
314331
| tst.js:296:5:299:6 | axios({ ... \\n }) | tst.js:303:26:303:37 | err.response | json | false |
315332
| tst.js:296:5:299:6 | axios({ ... \\n }) | tst.js:304:27:304:38 | err.response | json | false |
316333
| tst.js:312:12:312:36 | fetchPo ... o/bar') | tst.js:312:12:312:36 | fetchPo ... o/bar') | fetch.response | true |
334+
| tst.js:319:5:319:26 | superag ... ', url) | tst.js:319:5:319:26 | superag ... ', url) | stream | true |
335+
| tst.js:320:5:320:23 | superagent.del(url) | tst.js:320:5:320:23 | superagent.del(url) | stream | true |
336+
| tst.js:321:5:321:32 | superag ... st(url) | tst.js:321:5:321:32 | superag ... st(url) | stream | true |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { superagent } from "./superagentWrapper.js";
2+
3+
function test(url) {
4+
superagent('GET', url);
5+
superagent.del(url);
6+
superagent.agent().post(url).send(data);
7+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import superagent from 'superagent';
2+
export { superagent }

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,9 @@ function usePolyfill() {
314314
return response.text()
315315
})
316316
}
317+
318+
function useSuperagent(url){
319+
superagent('GET', url);
320+
superagent.del(url);
321+
superagent.agent().post(url).send(data);
322+
}

0 commit comments

Comments
 (0)