Skip to content

Commit 945fa68

Browse files
committed
JS: Inline useStep and special-case return steps to avoid fan-out
1 parent 796a2bc commit 945fa68

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

javascript/ql/lib/semmle/javascript/ApiGraphs.qll

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,18 @@ module API {
13251325
AdditionalUseStep::step(mid, result)
13261326
)
13271327
or
1328-
t = useStep(nd, promisified, boundArgs, prop, result)
1328+
exists(RawSourceNode prev, DataFlow::TypeTracker prevT |
1329+
prev = trackUseNode(nd, promisified, boundArgs, prop, prevT)
1330+
|
1331+
exists(StepSummary summary |
1332+
restrictedBigStep(prev, result, summary) and
1333+
t = prevT.append(summary)
1334+
)
1335+
or
1336+
t.hasCall() = false and
1337+
returnBigStep(prev, result) and
1338+
t = prevT
1339+
)
13291340
}
13301341

13311342
pragma[nomagic]
@@ -1361,26 +1372,23 @@ module API {
13611372
SharedTypeTrackingStep::loadStoreStep(node1.getALocalUse(), node2, prop)
13621373
}
13631374

1364-
/**
1365-
* Holds if `nd`, which is a use of an API-graph node, flows in zero or more potentially
1366-
* inter-procedural steps to some intermediate node, and then from that intermediate node to
1367-
* `res` in one step. The entire flow is described by the resulting `TypeTracker`.
1368-
*
1369-
* This predicate exists solely to enforce a better join order in `trackUseNode` above.
1370-
*/
1371-
pragma[noopt]
1372-
private DataFlow::TypeTracker useStep(
1373-
DataFlow::Node nd, boolean promisified, int boundArgs, string prop, DataFlow::Node res
1374-
) {
1375-
exists(DataFlow::TypeTracker t, StepSummary summary, DataFlow::SourceNode prev |
1376-
prev = trackUseNode(nd, promisified, boundArgs, prop, t) and
1377-
StepSummary::step(prev, res, summary) and
1378-
result = t.append(summary) and
1375+
pragma[nomagic]
1376+
private predicate restrictedBigStep(DataFlow::Node node1, DataFlow::Node node2, StepSummary step) {
1377+
StepSummary::step(node1, node2, step) and
1378+
not (
13791379
// Block argument-passing into 'this' when it determines the call target
1380-
not summary = CallReceiverStep()
1380+
step = CallReceiverStep()
1381+
or
1382+
// Special-case return to avoid large fan-out
1383+
step = ReturnStep()
13811384
)
13821385
}
13831386

1387+
pragma[nomagic]
1388+
private predicate returnBigStep(DataFlow::SourceNode node1, DataFlow::Node node2) {
1389+
StepSummary::step(node1, node2, ReturnStep())
1390+
}
1391+
13841392
private RawSourceNode trackUseNode(
13851393
RawSourceNode nd, boolean promisified, int boundArgs, string prop
13861394
) {

0 commit comments

Comments
 (0)