Skip to content

Commit 502faa7

Browse files
authored
Merge pull request #4494 from erik-krogh/callLimit
Approved by asgerf
2 parents 5d9f54e + 8cf21e3 commit 502faa7

File tree

6 files changed

+96
-0
lines changed

6 files changed

+96
-0
lines changed

change-notes/1.26/analysis-javascript.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
- [@angular/*](https://www.npmjs.com/package/@angular/core)
99
- [AWS Serverless](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
1010
- [Alibaba Serverless](https://www.alibabacloud.com/help/doc-detail/156876.htm)
11+
- [debounce](https://www.npmjs.com/package/debounce)
1112
- [bluebird](https://www.npmjs.com/package/bluebird)
13+
- [call-limit](https://www.npmjs.com/package/call-limit)
1214
- [express](https://www.npmjs.com/package/express)
1315
- [fast-json-stable-stringify](https://www.npmjs.com/package/fast-json-stable-stringify)
1416
- [fast-safe-stringify](https://www.npmjs.com/package/fast-safe-stringify)
@@ -18,11 +20,15 @@
1820
- [json-stable-stringify](https://www.npmjs.com/package/json-stable-stringify)
1921
- [json-stringify-safe](https://www.npmjs.com/package/json-stringify-safe)
2022
- [json3](https://www.npmjs.com/package/json3)
23+
- [jQuery throttle / debounce](https://github.com/cowboy/jquery-throttle-debounce)
2124
- [lodash](https://www.npmjs.com/package/lodash)
25+
- [lodash.debounce](https://www.npmjs.com/package/lodash.debounce)
26+
- [lodash.throttle](https://www.npmjs.com/package/lodash.throttle)
2227
- [needle](https://www.npmjs.com/package/needle)
2328
- [object-inspect](https://www.npmjs.com/package/object-inspect)
2429
- [pretty-format](https://www.npmjs.com/package/pretty-format)
2530
- [stringify-object](https://www.npmjs.com/package/stringify-object)
31+
- [throttle-debounce](https://www.npmjs.com/package/throttle-debounce)
2632
- [underscore](https://www.npmjs.com/package/underscore)
2733

2834
* Analyzing files with the ".cjs" extension is now supported.

javascript/ql/src/semmle/javascript/dataflow/Nodes.qll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,46 @@ module PartialInvokeNode {
13791379
}
13801380
}
13811381

1382+
/**
1383+
* A partial call that behaves like a throttle call, like `require("call-limit")(fs, limit)` or `_.memoize`.
1384+
* Seen as a partial invocation that binds no arguments.
1385+
*/
1386+
private class ThrottleLikePartialCall extends PartialInvokeNode::Range, DataFlow::CallNode {
1387+
int callbackIndex;
1388+
1389+
ThrottleLikePartialCall() {
1390+
callbackIndex = 0 and
1391+
(
1392+
this = LodashUnderscore::member(["throttle", "debounce", "once", "memoize"]).getACall()
1393+
or
1394+
this = DataFlow::moduleImport(["call-limit", "debounce"]).getACall()
1395+
)
1396+
or
1397+
callbackIndex = 1 and
1398+
(
1399+
this = LodashUnderscore::member(["after", "before"]).getACall()
1400+
or
1401+
// not jQuery: https://github.com/cowboy/jquery-throttle-debounce
1402+
this = DataFlow::globalVarRef("$").getAMemberCall(["throttle", "debounce"])
1403+
)
1404+
or
1405+
callbackIndex = -1 and
1406+
this = DataFlow::moduleMember("throttle-debounce", ["debounce", "throttle"]).getACall()
1407+
}
1408+
1409+
override DataFlow::SourceNode getBoundFunction(DataFlow::Node callback, int boundArgs) {
1410+
(
1411+
callbackIndex >= 0 and
1412+
callback = getArgument(callbackIndex)
1413+
or
1414+
callbackIndex = -1 and
1415+
callback = getLastArgument()
1416+
) and
1417+
boundArgs = 0 and
1418+
result = this
1419+
}
1420+
}
1421+
13821422
/**
13831423
* A partial call through `ramda.partial`.
13841424
*/

javascript/ql/test/library-tests/InterProceduralFlow/DataFlow.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,18 @@
3232
| partial.js:5:15:5:24 | "tainted1" | partial.js:15:15:15:15 | x |
3333
| partial.js:5:15:5:24 | "tainted1" | partial.js:21:15:21:15 | x |
3434
| partial.js:5:15:5:24 | "tainted1" | partial.js:27:15:27:15 | x |
35+
| partial.js:5:15:5:24 | "tainted1" | partial.js:34:15:34:15 | x |
36+
| partial.js:5:15:5:24 | "tainted1" | partial.js:41:15:41:15 | x |
37+
| partial.js:5:15:5:24 | "tainted1" | partial.js:47:15:47:15 | x |
38+
| partial.js:5:15:5:24 | "tainted1" | partial.js:53:15:53:15 | x |
3539
| partial.js:6:15:6:24 | "tainted2" | partial.js:10:15:10:15 | y |
3640
| partial.js:6:15:6:24 | "tainted2" | partial.js:16:15:16:15 | y |
3741
| partial.js:6:15:6:24 | "tainted2" | partial.js:22:15:22:15 | y |
3842
| partial.js:6:15:6:24 | "tainted2" | partial.js:28:15:28:15 | y |
43+
| partial.js:6:15:6:24 | "tainted2" | partial.js:35:15:35:15 | y |
44+
| partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y |
45+
| partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y |
46+
| partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y |
3947
| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val |
4048
| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v |
4149
| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v |

javascript/ql/test/library-tests/InterProceduralFlow/GermanFlow.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,18 @@
3333
| partial.js:5:15:5:24 | "tainted1" | partial.js:15:15:15:15 | x |
3434
| partial.js:5:15:5:24 | "tainted1" | partial.js:21:15:21:15 | x |
3535
| partial.js:5:15:5:24 | "tainted1" | partial.js:27:15:27:15 | x |
36+
| partial.js:5:15:5:24 | "tainted1" | partial.js:34:15:34:15 | x |
37+
| partial.js:5:15:5:24 | "tainted1" | partial.js:41:15:41:15 | x |
38+
| partial.js:5:15:5:24 | "tainted1" | partial.js:47:15:47:15 | x |
39+
| partial.js:5:15:5:24 | "tainted1" | partial.js:53:15:53:15 | x |
3640
| partial.js:6:15:6:24 | "tainted2" | partial.js:10:15:10:15 | y |
3741
| partial.js:6:15:6:24 | "tainted2" | partial.js:16:15:16:15 | y |
3842
| partial.js:6:15:6:24 | "tainted2" | partial.js:22:15:22:15 | y |
3943
| partial.js:6:15:6:24 | "tainted2" | partial.js:28:15:28:15 | y |
44+
| partial.js:6:15:6:24 | "tainted2" | partial.js:35:15:35:15 | y |
45+
| partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y |
46+
| partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y |
47+
| partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y |
4048
| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val |
4149
| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v |
4250
| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v |

javascript/ql/test/library-tests/InterProceduralFlow/TaintTracking.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,18 @@
3838
| partial.js:5:15:5:24 | "tainted1" | partial.js:15:15:15:15 | x |
3939
| partial.js:5:15:5:24 | "tainted1" | partial.js:21:15:21:15 | x |
4040
| partial.js:5:15:5:24 | "tainted1" | partial.js:27:15:27:15 | x |
41+
| partial.js:5:15:5:24 | "tainted1" | partial.js:34:15:34:15 | x |
42+
| partial.js:5:15:5:24 | "tainted1" | partial.js:41:15:41:15 | x |
43+
| partial.js:5:15:5:24 | "tainted1" | partial.js:47:15:47:15 | x |
44+
| partial.js:5:15:5:24 | "tainted1" | partial.js:53:15:53:15 | x |
4145
| partial.js:6:15:6:24 | "tainted2" | partial.js:10:15:10:15 | y |
4246
| partial.js:6:15:6:24 | "tainted2" | partial.js:16:15:16:15 | y |
4347
| partial.js:6:15:6:24 | "tainted2" | partial.js:22:15:22:15 | y |
4448
| partial.js:6:15:6:24 | "tainted2" | partial.js:28:15:28:15 | y |
49+
| partial.js:6:15:6:24 | "tainted2" | partial.js:35:15:35:15 | y |
50+
| partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y |
51+
| partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y |
52+
| partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y |
4553
| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val |
4654
| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v |
4755
| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v |

javascript/ql/test/library-tests/InterProceduralFlow/partial.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,29 @@ function f4(x, y) {
2828
let sink2 = y;
2929
}
3030
R.partial(f4, [source1])(source2);
31+
32+
const limit = require('call-limit')
33+
function f5(x, y) {
34+
let sink1 = x;
35+
let sink2 = y;
36+
}
37+
const limited = limit(f5, 5)
38+
limited(source1, source2);
39+
40+
function f6(x, y) {
41+
let sink1 = x;
42+
let sink2 = y;
43+
}
44+
_.throttle(f6, 100)(source1, source2);
45+
46+
function f7(x, y) {
47+
let sink1 = x;
48+
let sink2 = y;
49+
}
50+
_.after(3, f7)(source1, source2);
51+
52+
function f8(x, y) {
53+
let sink1 = x;
54+
let sink2 = y;
55+
}
56+
require("throttle-debounce").debounce(1000, false, f8)(source1, source2);

0 commit comments

Comments
 (0)