Skip to content

Commit 0360df6

Browse files
author
Max Schaefer
committed
JavaScript: Improve terminology and comments.
1 parent f9d704b commit 0360df6

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,9 @@ private predicate exploratoryFlowStep(
442442
basicFlowStep(pred, succ, _, cfg) or
443443
basicStoreStep(pred, succ, _) or
444444
loadStep(pred, succ, _) or
445-
approximateCallbackStep(pred, succ) or
445+
// the following two disjuncts taken together over-approximate flow through
446+
// higher-order calls
447+
callback(pred, succ) or
446448
succ = pred.(DataFlow::FunctionNode).getAParameter()
447449
}
448450

@@ -622,9 +624,10 @@ private predicate flowThroughProperty(
622624

623625
/**
624626
* Holds if `arg` and `cb` are passed as arguments to a function which in turn
625-
* invokes `cb`, passing `arg` as its `i`th argument. All of this is done under
626-
* configuration `cfg`, and `arg` flows along a path summarized by `summary`,
627-
* while `cb` is only tracked locally.
627+
* invokes `cb`, passing `arg` as its `i`th argument.
628+
*
629+
* All of this is done under configuration `cfg`, and `arg` flows along a path
630+
* summarized by `summary`, while `cb` is only tracked locally.
628631
*/
629632
private predicate higherOrderCall(
630633
DataFlow::Node arg, DataFlow::Node cb, int i, DataFlow::Configuration cfg, PathSummary summary
@@ -634,10 +637,12 @@ private predicate higherOrderCall(
634637
reachableFromInput(f, outer, arg, innerArg, cfg, oldSummary) and
635638
argumentPassing(outer, cb, f, cbParm) and
636639
innerArg = inner.getArgument(j) |
640+
// direct higher-order call
637641
cbParm.flowsTo(inner.getCalleeNode()) and
638642
i = j and
639643
summary = oldSummary
640644
or
645+
// indirect higher-order call
641646
exists (DataFlow::Node cbArg, PathSummary newSummary |
642647
cbParm.flowsTo(cbArg) and
643648
higherOrderCall(innerArg, cbArg, i, cfg, newSummary) and
@@ -649,7 +654,9 @@ private predicate higherOrderCall(
649654
/**
650655
* Holds if `pred` is passed as an argument to a function `f` which also takes a
651656
* callback parameter `cb` and then invokes `cb`, passing `pred` into parameter `succ`
652-
* of `cb`. All of this is done under configuration `cfg`, and `arg` flows along a path
657+
* of `cb`.
658+
*
659+
* All of this is done under configuration `cfg`, and `arg` flows along a path
653660
* summarized by `summary`, while `cb` is only tracked locally.
654661
*/
655662
private predicate flowIntoHigherOrderCall(

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ private module NodeTracking {
101101
or
102102
loadStep(mid, nd, _)
103103
or
104-
approximateCallbackStep(mid, nd)
104+
callback(mid, nd)
105105
or
106106
nd = mid.(DataFlow::FunctionNode).getAParameter()
107107
)
@@ -220,10 +220,12 @@ private module NodeTracking {
220220
reachableFromInput(f, outer, arg, innerArg, oldSummary) and
221221
argumentPassing(outer, cb, f, cbParm) and
222222
innerArg = inner.getArgument(j) |
223+
// direct higher-order call
223224
cbParm.flowsTo(inner.getCalleeNode()) and
224225
i = j and
225226
summary = oldSummary
226227
or
228+
// indirect higher-order call
227229
exists (DataFlow::Node cbArg, PathSummary newSummary |
228230
cbParm.flowsTo(cbArg) and
229231
higherOrderCall(innerArg, cbArg, i, newSummary) and

javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,30 @@ predicate loadStep(DataFlow::Node pred, DataFlow::PropRead succ, string prop) {
236236
}
237237

238238
/**
239-
* Holds if there is a call with argument `pred`, and `succ` flows into the callee
240-
* position of that call.
239+
* Holds if there is a higher-order call with argument `arg`, and `cb` is the local
240+
* source of an argument that flows into the callee position of that call:
241+
*
242+
* ```
243+
* function f(x, g) {
244+
* g(
245+
* x // arg
246+
* );
247+
* }
248+
*
249+
* function cb() { // cb
250+
* }
251+
*
252+
* f(arg, cb);
241253
*
242254
* This is an over-approximation of a possible data flow step through a callback
243255
* invocation.
244256
*/
245-
predicate approximateCallbackStep(DataFlow::Node pred, DataFlow::SourceNode succ) {
246-
exists (DataFlow::InvokeNode invk, DataFlow::ParameterNode cb |
247-
pred = invk.getAnArgument() and
248-
cb.flowsTo(invk.getCalleeNode()) and
249-
callStep(any(DataFlow::Node nd | succ.flowsTo(nd)), cb)
257+
predicate callback(DataFlow::Node arg, DataFlow::SourceNode cb) {
258+
exists (DataFlow::InvokeNode invk, DataFlow::ParameterNode cbParm, DataFlow::Node cbArg |
259+
arg = invk.getAnArgument() and
260+
cbParm.flowsTo(invk.getCalleeNode()) and
261+
callStep(cbArg, cbParm) and
262+
cb.flowsTo(cbArg)
250263
)
251264
}
252265

0 commit comments

Comments
 (0)