Skip to content

Commit 98398a9

Browse files
committed
JS: add two-prop version of loadStoreStep and infer pseudo properties
Initial step towards migrating CollectionFlowStep to PreCallGraphStep
1 parent 67ec5d3 commit 98398a9

6 files changed

Lines changed: 64 additions & 31 deletions

File tree

javascript/ql/src/semmle/javascript/Collections.qll

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,12 @@ private import DataFlow::PseudoProperties
1010

1111
/**
1212
* A pseudo-property used in a data-flow/type-tracking step for collections.
13-
*
14-
* By extending `TypeTrackingPseudoProperty` the class enables the use of the collection related pseudo-properties in type-tracking predicates.
1513
*/
16-
private class PseudoProperty extends TypeTrackingPseudoProperty {
14+
private class PseudoProperty extends string {
1715
PseudoProperty() {
1816
this = [arrayLikeElement(), "1"] or // the "1" is required for the `ForOfStep`.
1917
this = any(CollectionDataFlow::MapSet step).getAPseudoProperty()
2018
}
21-
22-
override PseudoProperty getLoadStoreToProp() {
23-
exists(CollectionFlowStep step | step.loadStore(_, _, this, result))
24-
}
2519
}
2620

2721
/**

javascript/ql/src/semmle/javascript/Promises.qll

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,6 @@ module PromiseTypeTracking {
214214
result = PromiseTypeTracking::promiseStep(mid, summary)
215215
)
216216
}
217-
218-
/**
219-
* A class enabling the use of the `resolveField` as a pseudo-property in type-tracking predicates.
220-
*/
221-
private class ResolveFieldAsTypeTrackingProperty extends TypeTrackingPseudoProperty {
222-
ResolveFieldAsTypeTrackingProperty() { this = Promises::valueProp() }
223-
}
224217
}
225218

226219
private import semmle.javascript.dataflow.internal.PreCallGraphStep

javascript/ql/src/semmle/javascript/dataflow/TypeTracking.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,15 @@ class SharedTypeTrackingStep extends Unit {
358358
* Holds if type-tracking should step from the `prop` property of `pred` to the same property in `succ`.
359359
*/
360360
predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() }
361+
362+
/**
363+
* Holds if type-tracking should step from the `loadProp` property of `pred` to the `storeProp` property in `succ`.
364+
*/
365+
predicate loadStoreStep(
366+
DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp
367+
) {
368+
none()
369+
}
361370
}
362371

363372
/** Provides access to the steps contributed by subclasses of `SharedTypeTrackingStep`. */
@@ -389,6 +398,15 @@ module SharedTypeTrackingStep {
389398
predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
390399
any(SharedTypeTrackingStep s).loadStoreStep(pred, succ, prop)
391400
}
401+
402+
/**
403+
* Holds if type-tracking should step from the `loadProp` property of `pred` to the `storeProp` property in `succ`.
404+
*/
405+
predicate loadStoreStep(
406+
DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp
407+
) {
408+
any(SharedTypeTrackingStep s).loadStoreStep(pred, succ, loadProp, storeProp)
409+
}
392410
}
393411

394412
/**

javascript/ql/src/semmle/javascript/dataflow/internal/PreCallGraphStep.qll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ class PreCallGraphStep extends Unit {
4040
* Holds if there is a step from the `prop` property of `pred` to the same property in `succ`.
4141
*/
4242
predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() }
43+
44+
/**
45+
* Holds if there is a step from the `loadProp` property of `pred` to the `storeProp` property in `succ`.
46+
*/
47+
predicate loadStoreStep(
48+
DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp
49+
) {
50+
none()
51+
}
4352
}
4453

4554
module PreCallGraphStep {
@@ -75,6 +84,15 @@ module PreCallGraphStep {
7584
predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
7685
any(PreCallGraphStep s).loadStoreStep(pred, succ, prop)
7786
}
87+
88+
/**
89+
* Holds if there is a step from the `loadProp` property of `pred` to the `storeProp` property in `succ`.
90+
*/
91+
predicate loadStoreStep(
92+
DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp
93+
) {
94+
any(PreCallGraphStep s).loadStoreStep(pred, succ, loadProp, storeProp)
95+
}
7896
}
7997

8098
private class SharedFlowStepFromPreCallGraph extends DataFlow::SharedFlowStep {
@@ -93,6 +111,12 @@ private class SharedFlowStepFromPreCallGraph extends DataFlow::SharedFlowStep {
93111
override predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
94112
PreCallGraphStep::loadStoreStep(pred, succ, prop)
95113
}
114+
115+
override predicate loadStoreStep(
116+
DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp
117+
) {
118+
PreCallGraphStep::loadStoreStep(pred, succ, loadProp, storeProp)
119+
}
96120
}
97121

98122
private class SharedTypeTrackingStepFromPreCallGraph extends DataFlow::SharedTypeTrackingStep {
@@ -111,4 +135,10 @@ private class SharedTypeTrackingStepFromPreCallGraph extends DataFlow::SharedTyp
111135
override predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
112136
PreCallGraphStep::loadStoreStep(pred, succ, prop)
113137
}
138+
139+
override predicate loadStoreStep(
140+
DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp
141+
) {
142+
PreCallGraphStep::loadStoreStep(pred, succ, loadProp, storeProp)
143+
}
114144
}

javascript/ql/src/semmle/javascript/dataflow/internal/StepSummary.qll

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,20 @@ class PropertyName extends string {
1010
or
1111
exists(AccessPath::getAnAssignmentTo(_, this))
1212
or
13-
this instanceof TypeTrackingPseudoProperty
13+
SharedTypeTrackingStep::loadStep(_, _, this)
14+
or
15+
SharedTypeTrackingStep::storeStep(_, _, this)
16+
or
17+
SharedTypeTrackingStep::loadStoreStep(_, _, this, _)
18+
or
19+
SharedTypeTrackingStep::loadStoreStep(_, _, _, this)
1420
}
1521
}
1622

1723
class OptionalPropertyName extends string {
1824
OptionalPropertyName() { this instanceof PropertyName or this = "" }
1925
}
2026

21-
/**
22-
* A pseudo-property that can be used in type-tracking.
23-
*/
24-
abstract class TypeTrackingPseudoProperty extends string {
25-
bindingset[this]
26-
TypeTrackingPseudoProperty() { any() }
27-
28-
/**
29-
* Gets a property name that `this` can be copied to in a `LoadStoreStep(this, result)`.
30-
*/
31-
string getLoadStoreToProp() { none() }
32-
}
33-
3427
/**
3528
* A description of a step on an inter-procedural data flow path.
3629
*/
@@ -42,7 +35,7 @@ newtype TStepSummary =
4235
LoadStep(PropertyName prop) or
4336
CopyStep(PropertyName prop) or
4437
LoadStoreStep(PropertyName fromProp, PropertyName toProp) {
45-
exists(TypeTrackingPseudoProperty prop | fromProp = prop and toProp = prop.getLoadStoreToProp())
38+
SharedTypeTrackingStep::loadStoreStep(_, _, fromProp, toProp)
4639
}
4740

4841
/**
@@ -121,6 +114,11 @@ module StepSummary {
121114
summary = CopyStep(prop)
122115
)
123116
or
117+
exists(string fromProp, string toProp |
118+
SharedTypeTrackingStep::loadStoreStep(pred, succ, fromProp, toProp) and
119+
summary = LoadStoreStep(fromProp, toProp)
120+
)
121+
or
124122
SharedTypeTrackingStep::step(pred, succ) and
125123
summary = LevelStep()
126124
or

javascript/ql/src/semmle/javascript/frameworks/HTTP.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,8 +708,8 @@ module HTTP {
708708
override DataFlow::SourceNode getRouteHandler(DataFlow::SourceNode access) {
709709
result instanceof RouteHandlerCandidate and
710710
exists(
711-
DataFlow::Node input, TypeTrackingPseudoProperty key, CollectionFlowStep store,
712-
CollectionFlowStep load, DataFlow::Node storeTo, DataFlow::Node loadFrom
711+
DataFlow::Node input, string key, CollectionFlowStep store, CollectionFlowStep load,
712+
DataFlow::Node storeTo, DataFlow::Node loadFrom
713713
|
714714
this.flowsTo(storeTo) and
715715
store.store(input, storeTo, key) and

0 commit comments

Comments
 (0)