JS: Refactor store/load flow a bit

This commit is contained in:
Asger Feldthaus
2020-11-27 11:46:02 +00:00
parent f132b4a279
commit fe86465a0b

View File

@@ -1183,50 +1183,49 @@ private predicate loadStep(
}
/**
* Holds if `rhs` is the right-hand side of a write to property `prop`, and `nd` is reachable
* from the base of that write under configuration `cfg` (possibly through callees) along a
* path summarized by `summary`.
* Holds if there is flow to `base.startProp`, and `base.startProp` flows to `nd.endProp` under `cfg/summary`.
*/
pragma[nomagic]
private predicate reachableFromStoreBase(
string prop, DataFlow::Node rhs, DataFlow::Node nd, DataFlow::Configuration cfg,
string startProp, string endProp, DataFlow::Node base, DataFlow::Node nd, DataFlow::Configuration cfg,
PathSummary summary
) {
exists(PathSummary s1, PathSummary s2 |
exists(PathSummary s1, PathSummary s2, DataFlow::Node rhs |
reachableFromSource(rhs, cfg, s1)
or
reachableFromStoreBase(_, _, rhs, cfg, s1)
reachableFromStoreBase(_, _, _, rhs, cfg, s1)
|
storeStep(rhs, nd, prop, cfg, s2) and
storeStep(rhs, nd, startProp, cfg, s2) and
endProp = startProp and
base = nd and
summary =
MkPathSummary(false, s1.hasCall().booleanOr(s2.hasCall()), s2.getStartLabel(),
s2.getEndLabel())
MkPathSummary(false, s1.hasCall().booleanOr(s2.hasCall()), DataFlow::FlowLabel::data(), DataFlow::FlowLabel::data())
)
or
exists(PathSummary newSummary, PathSummary oldSummary |
reachableFromStoreBaseStep(prop, rhs, nd, cfg, oldSummary, newSummary) and
reachableFromStoreBaseStep(startProp, endProp, base, nd, cfg, oldSummary, newSummary) and
summary = oldSummary.appendValuePreserving(newSummary)
)
}
/**
* Holds if `rhs` is the right-hand side of a write to property `prop`, and `nd` is reachable
* from the base of that write under configuration `cfg` (possibly through callees) along a
* path whose last step is summarized by `newSummary`, and the previous steps are summarized
* Holds if `base` is the base of a write to property `prop`, and `nd` is reachable
* from `base` under configuration `cfg` (possibly through callees) along a path whose
* last step is summarized by `newSummary`, and the previous steps are summarized
* by `oldSummary`.
*/
pragma[noinline]
private predicate reachableFromStoreBaseStep(
string prop, DataFlow::Node rhs, DataFlow::Node nd, DataFlow::Configuration cfg,
string startProp, string endProp, DataFlow::Node base, DataFlow::Node nd, DataFlow::Configuration cfg,
PathSummary oldSummary, PathSummary newSummary
) {
exists(DataFlow::Node mid |
reachableFromStoreBase(prop, rhs, mid, cfg, oldSummary) and
reachableFromStoreBase(startProp, endProp, base, mid, cfg, oldSummary) and
flowStep(mid, cfg, nd, newSummary)
or
exists(string midProp |
reachableFromStoreBase(midProp, rhs, mid, cfg, oldSummary) and
isAdditionalLoadStoreStep(mid, nd, midProp, prop, cfg) and
reachableFromStoreBase(startProp, midProp, base, mid, cfg, oldSummary) and
isAdditionalLoadStoreStep(mid, nd, midProp, endProp, cfg) and
newSummary = PathSummary::level()
)
)
@@ -1260,9 +1259,11 @@ private predicate storeToLoad(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg, PathSummary oldSummary,
PathSummary newSummary
) {
exists(string prop, DataFlow::Node base |
reachableFromStoreBase(prop, pred, base, cfg, oldSummary) and
loadStep(base, succ, prop, cfg, newSummary)
exists(string storeProp, string loadProp, DataFlow::Node storeBase, DataFlow::Node loadBase, PathSummary s1, PathSummary s2 |
storeStep(pred, storeBase, storeProp, cfg, s1) and
reachableFromStoreBase(storeProp, loadProp, storeBase, loadBase, cfg, s2) and
oldSummary = s1.appendValuePreserving(s2) and
loadStep(loadBase, succ, loadProp, cfg, newSummary)
)
}