Skip to content

Commit ff2a5e8

Browse files
authored
Merge pull request #10986 from erik-krogh/tsPerf
JS: push more context into load/store steps from the exploratory flow-analysis
2 parents 994c033 + 21e7e27 commit ff2a5e8

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ private predicate parameterPropReadStep(
11751175
invk = getAwaitOperand(succ)
11761176
) and
11771177
callInputStep(f, invk, arg, parm, cfg) and
1178+
prop = pragma[only_bind_into](getARelevantProp(cfg)) and
11781179
(
11791180
read = parm.getAPropertyRead(prop)
11801181
or
@@ -1192,7 +1193,7 @@ private predicate reachesReturn(
11921193
isRelevant(read, cfg) and
11931194
returnExpr(f, read, _) and
11941195
summary = PathSummary::level() and
1195-
callInputStep(f, _, _, _, _) // check that a relevant result can exist.
1196+
parameterPropReadStep(_, _, _, cfg, _, _, f, _) // check that a relevant result can exist.
11961197
or
11971198
exists(DataFlow::Node mid, PathSummary oldSummary, PathSummary newSummary |
11981199
flowStep(read, cfg, mid, oldSummary) and
@@ -1202,6 +1203,33 @@ private predicate reachesReturn(
12021203
)
12031204
}
12041205

1206+
// used in `getARelevantProp`, outlined for performance
1207+
pragma[noinline]
1208+
private string getARelevantStoreProp(DataFlow::Configuration cfg) {
1209+
exists(DataFlow::Node previous | isRelevant(previous, cfg) |
1210+
basicStoreStep(previous, _, result) or
1211+
isAdditionalStoreStep(previous, _, result, cfg)
1212+
)
1213+
}
1214+
1215+
// used in `getARelevantProp`, outlined for performance
1216+
pragma[noinline]
1217+
private string getARelevantLoadProp(DataFlow::Configuration cfg) {
1218+
exists(DataFlow::Node previous | isRelevant(previous, cfg) |
1219+
basicLoadStep(previous, _, result) or
1220+
isAdditionalLoadStep(previous, _, result, cfg)
1221+
)
1222+
}
1223+
1224+
/** Gets the name of a property that is both loaded and stored according to the exploratory analysis. */
1225+
pragma[noinline]
1226+
private string getARelevantProp(DataFlow::Configuration cfg) {
1227+
result = getARelevantStoreProp(cfg) and
1228+
result = getARelevantLoadProp(cfg)
1229+
or
1230+
result = getAPropertyUsedInLoadStore(cfg)
1231+
}
1232+
12051233
/**
12061234
* Holds if the property `prop` of the object `pred` should be loaded into `succ`.
12071235
*/
@@ -1275,6 +1303,7 @@ private predicate reachableFromStoreBase(
12751303
) {
12761304
exists(TPathSummary s1, TPathSummary s2, DataFlow::Node rhs |
12771305
storeStep(rhs, nd, startProp, cfg, s2) and
1306+
startProp = getARelevantProp(cfg) and
12781307
endProp = startProp and
12791308
base = nd and
12801309
exists(boolean hasCall, DataFlow::FlowLabel data |
@@ -1300,6 +1329,7 @@ private predicate reachableFromStoreBase(
13001329
exists(string midProp |
13011330
reachableFromStoreBase(startProp, midProp, base, mid, cfg, oldSummary, onlyRelevantInCall) and
13021331
isAdditionalLoadStoreStep(mid, nd, midProp, endProp, cfg) and
1332+
endProp = getARelevantProp(cfg) and
13031333
newSummary = PathSummary::level()
13041334
)
13051335
|

0 commit comments

Comments
 (0)