Skip to content

Commit c369b28

Browse files
committed
optimizations in global data flow
1 parent f39872e commit c369b28

File tree

1 file changed

+39
-27
lines changed

1 file changed

+39
-27
lines changed

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

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -939,18 +939,21 @@ private predicate basicFlowStepNoBarrier(
939939
* This predicate is field insensitive (it does not distinguish between `x` and `x.p`)
940940
* and hence should only be used for purposes of approximation.
941941
*/
942-
pragma[inline]
942+
pragma[noinline]
943943
private predicate exploratoryFlowStep(
944944
DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg
945945
) {
946-
basicFlowStepNoBarrier(pred, succ, _, cfg) or
947-
exploratoryLoadStep(pred, succ, cfg) or
948-
isAdditionalLoadStoreStep(pred, succ, _, _, cfg) or
949-
// the following three disjuncts taken together over-approximate flow through
950-
// higher-order calls
951-
exploratoryCallbackStep(pred, succ) or
952-
succ = pred.(DataFlow::FunctionNode).getAParameter() or
953-
exploratoryBoundInvokeStep(pred, succ)
946+
isRelevantForward(pred, cfg) and
947+
(
948+
basicFlowStepNoBarrier(pred, succ, _, cfg) or
949+
exploratoryLoadStep(pred, succ, cfg) or
950+
isAdditionalLoadStoreStep(pred, succ, _, _, cfg) or
951+
// the following three disjuncts taken together over-approximate flow through
952+
// higher-order calls
953+
exploratoryCallbackStep(pred, succ) or
954+
succ = pred.(DataFlow::FunctionNode).getAParameter() or
955+
exploratoryBoundInvokeStep(pred, succ)
956+
)
954957
}
955958

956959
/**
@@ -1024,6 +1027,7 @@ private string getAPropertyUsedInLoadStore(DataFlow::Configuration cfg) {
10241027
* Holds if there exists a store-step from `pred` to `succ` under configuration `cfg`,
10251028
* and somewhere in the program there exists a load-step that could possibly read the stored value.
10261029
*/
1030+
pragma[noinline]
10271031
private predicate exploratoryForwardStoreStep(
10281032
DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg
10291033
) {
@@ -1075,8 +1079,10 @@ private string getABackwardsRelevantStoreProperty(DataFlow::Configuration cfg) {
10751079
private predicate isRelevantForward(DataFlow::Node nd, DataFlow::Configuration cfg) {
10761080
isSource(nd, cfg, _) and isLive()
10771081
or
1078-
exists(DataFlow::Node mid | isRelevantForward(mid, cfg) |
1079-
exploratoryFlowStep(mid, nd, cfg) or
1082+
exists(DataFlow::Node mid |
1083+
exploratoryFlowStep(mid, nd, cfg)
1084+
or
1085+
isRelevantForward(mid, cfg) and
10801086
exploratoryForwardStoreStep(mid, nd, cfg)
10811087
)
10821088
}
@@ -1098,11 +1104,10 @@ private predicate isRelevant(DataFlow::Node nd, DataFlow::Configuration cfg) {
10981104
private predicate isRelevantBackStep(
10991105
DataFlow::Node mid, DataFlow::Node nd, DataFlow::Configuration cfg
11001106
) {
1107+
exploratoryFlowStep(nd, mid, cfg)
1108+
or
11011109
isRelevantForward(nd, cfg) and
1102-
(
1103-
exploratoryFlowStep(nd, mid, cfg) or
1104-
exploratoryBackwardStoreStep(nd, mid, cfg)
1105-
)
1110+
exploratoryBackwardStoreStep(nd, mid, cfg)
11061111
}
11071112

11081113
/**
@@ -1273,23 +1278,30 @@ private predicate parameterPropRead(
12731278
DataFlow::Node arg, string prop, DataFlow::Node succ, DataFlow::Configuration cfg,
12741279
PathSummary summary
12751280
) {
1276-
exists(Function f, DataFlow::Node read, DataFlow::Node invk |
1281+
exists(Function f, DataFlow::Node read, DataFlow::Node invk, DataFlow::Node parm |
1282+
reachesReturn(f, read, cfg, summary) and
1283+
parameterPropReadStep(parm, read, prop, cfg, arg, invk, f, succ)
1284+
)
1285+
}
1286+
1287+
// all the non-recursive parts of parameterPropRead outlined into a precomputed predicate
1288+
pragma[noinline]
1289+
private predicate parameterPropReadStep(
1290+
DataFlow::SourceNode parm, DataFlow::Node read, string prop, DataFlow::Configuration cfg,
1291+
DataFlow::Node arg, DataFlow::Node invk, Function f, DataFlow::Node succ
1292+
) {
1293+
(
12771294
not f.isAsyncOrGenerator() and invk = succ
12781295
or
12791296
// load from an immediately awaited function call
12801297
f.isAsync() and
12811298
invk = getAwaitOperand(succ)
1282-
|
1283-
exists(DataFlow::SourceNode parm |
1284-
callInputStep(f, invk, arg, parm, cfg) and
1285-
(
1286-
reachesReturn(f, read, cfg, summary) and
1287-
read = parm.getAPropertyRead(prop)
1288-
or
1289-
reachesReturn(f, read, cfg, summary) and
1290-
exists(DataFlow::Node use | parm.flowsTo(use) | isAdditionalLoadStep(use, read, prop, cfg))
1291-
)
1292-
)
1299+
) and
1300+
callInputStep(f, invk, arg, parm, cfg) and
1301+
(
1302+
read = parm.getAPropertyRead(prop)
1303+
or
1304+
exists(DataFlow::Node use | parm.flowsTo(use) | isAdditionalLoadStep(use, read, prop, cfg))
12931305
)
12941306
}
12951307

0 commit comments

Comments
 (0)