Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions javascript/ql/src/semmle/javascript/dataflow/Configuration.qll
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,6 @@ private predicate isRelevant(DataFlow::Node nd, DataFlow::Configuration cfg) {
* either `pred` is an argument of `f` and `succ` the corresponding parameter, or
* `pred` is a variable definition whose value is captured by `f` at `succ`.
*/
pragma[noopt]
private predicate callInputStep(Function f, DataFlow::Node invk,
DataFlow::Node pred, DataFlow::Node succ,
DataFlow::Configuration cfg) {
Expand Down Expand Up @@ -567,6 +566,7 @@ private predicate callInputStep(Function f, DataFlow::Node invk,
* Note that the summary does not take the initial step from argument to parameter
* into account.
*/
pragma[nomagic]
private predicate reachableFromInput(Function f, DataFlow::Node invk,
DataFlow::Node input, DataFlow::Node nd,
DataFlow::Configuration cfg, PathSummary summary) {
Expand Down Expand Up @@ -600,20 +600,28 @@ private predicate flowThroughCall(DataFlow::Node input, DataFlow::Node invk,
* Holds if `pred` may flow into property `prop` of `succ` under configuration `cfg`
* along a path summarized by `summary`.
*/
private predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop,
pragma[nomagic]
private predicate storeStep(DataFlow::Node pred, DataFlow::Node succ, string prop,
DataFlow::Configuration cfg, PathSummary summary) {
basicStoreStep(pred, succ, prop) and
summary = PathSummary::level()
or
exists (Function f, DataFlow::Node mid, DataFlow::SourceNode base |
exists (Function f, DataFlow::Node mid, DataFlow::Node base |
// `f` stores its parameter `pred` in property `prop` of a value that it returns,
// and `succ` is an invocation of `f`
reachableFromInput(f, succ, pred, mid, cfg, summary) and
base.hasPropertyWrite(prop, mid) and
base.flowsToExpr(f.getAReturnedExpr())
returnedPropWrite(f, base, prop, mid)
)
}

/**
* Holds if `f` may return `base`, which has a write of property `prop` with right-hand side `rhs`.
*/
predicate returnedPropWrite(Function f, DataFlow::SourceNode base, string prop, DataFlow::Node rhs) {
base.hasPropertyWrite(prop, rhs) and
base.flowsToExpr(f.getAReturnedExpr())
}

/**
* 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
Expand Down