JS: Add global post-update steps

This commit is contained in:
Asger F
2023-10-06 10:30:12 +02:00
parent 9372f7993d
commit 50aace3fa3
2 changed files with 25 additions and 0 deletions

View File

@@ -671,6 +671,8 @@ private predicate valuePreservingStep(Node node1, Node node2) {
or
FlowSteps::globalFlowStep(node1, node2)
or
FlowSteps::globalPostUpdateStep(node1, node2)
or
node2 = FlowSteps::getThrowTarget(node1)
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(),

View File

@@ -383,6 +383,14 @@ private module CachedSteps {
result = DataFlow::valueNode(gv.getAnAccess())
}
/**
* Gets a post-update of `gv` in `f`.
*/
pragma[noinline]
private DataFlow::ExprPostUpdateNode getAPostUpdateIn(GlobalVariable gv, File f) {
result.getPreUpdateNode() = getAUseIn(gv, f)
}
/**
* Holds if there is a flow step from `pred` to `succ` through a global
* variable. Both `pred` and `succ` must be in the same file.
@@ -395,6 +403,20 @@ private module CachedSteps {
)
}
/**
* Holds if `pred` is a post-update node for a use of a global variable, and `succ`
* is a use of the global variable in the same file.
*/
cached
predicate globalPostUpdateStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(GlobalVariable gv, File f |
pred = getAPostUpdateIn(gv, f) and
succ = getAUseIn(gv, f) and
// Remove some unnecessary steps
not succ = any(DataFlow::PropWrite write).getBase()
)
}
/**
* Holds if there is a write to property `prop` of global variable `gv`
* in file `f`, where the right-hand side of the write is `rhs`.
@@ -438,6 +460,7 @@ private module CachedSteps {
predicate basicStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
succ.(DataFlow::SourceNode).hasPropertyWrite(prop, pred)
or
// Note that this case is handled by globalPostUpdateStep in dataflow2
exists(GlobalVariable gv, File f |
globalPropertyWrite(gv, f, prop, pred) and
globalPropertyRead(gv, f, prop, succ)