Skip to content

Commit 3d2bbbd

Browse files
committed
JS: Add PreCallGraphStep extension point
1 parent 1f2ab60 commit 3d2bbbd

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ private import internal.CallGraphs
2323
private import internal.FlowSteps as FlowSteps
2424
private import internal.DataFlowNode
2525
private import internal.AnalyzedParameters
26+
private import internal.PreCallGraphStep
2627

2728
module DataFlow {
2829
/**
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* Provides an extension point for contributing flow edges prior
3+
* to call graph construction and type tracking.
4+
*/
5+
private import javascript
6+
7+
private newtype TUnit = MkUnit()
8+
9+
private class Unit extends TUnit {
10+
string toString() { result = "unit" }
11+
}
12+
13+
/**
14+
* Internal extension point for adding flow edges prior to call graph construction
15+
* and type tracking.
16+
*
17+
* Steps added here will be added to both `AdditionalFlowStep` and `AdditionalTypeTrackingStep`.
18+
*
19+
* Contributing steps that rely on type tracking will lead to negative recursion.
20+
*/
21+
class PreCallGraphStep extends Unit {
22+
/**
23+
* Holds if there is a step from `pred` to `succ`.
24+
*/
25+
predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() }
26+
27+
/**
28+
* Holds if there is a step from `pred` into the `prop` property of `succ`.
29+
*/
30+
predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() }
31+
32+
/**
33+
* Holds if there is a step from the `prop` property of `pred` to `succ`.
34+
*/
35+
predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() }
36+
37+
/**
38+
* Holds if there is a step from the `prop` property of `pred` to the same property in `succ`.
39+
*/
40+
predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() }
41+
}
42+
43+
module PreCallGraphStep {
44+
/**
45+
* Holds if there is a step from `pred` to `succ`.
46+
*/
47+
cached
48+
predicate step(DataFlow::Node pred, DataFlow::Node succ) {
49+
any(PreCallGraphStep s).step(pred, succ)
50+
}
51+
52+
/**
53+
* Holds if there is a step from `pred` into the `prop` property of `succ`.
54+
*/
55+
cached
56+
predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
57+
any(PreCallGraphStep s).storeStep(pred, succ, prop)
58+
}
59+
60+
/**
61+
* Holds if there is a step from the `prop` property of `pred` to `succ`.
62+
*/
63+
cached
64+
predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
65+
any(PreCallGraphStep s).loadStep(pred, succ, prop)
66+
}
67+
68+
/**
69+
* Holds if there is a step from the `prop` property of `pred` to the same property in `succ`.
70+
*/
71+
cached
72+
predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
73+
any(PreCallGraphStep s).loadStoreStep(pred, succ, prop)
74+
}
75+
}
76+
77+
private class NodeWithPreCallGraphStep extends DataFlow::Node {
78+
NodeWithPreCallGraphStep() {
79+
PreCallGraphStep::step(this, _)
80+
or
81+
PreCallGraphStep::storeStep(this, _, _)
82+
or
83+
PreCallGraphStep::loadStep(this, _, _)
84+
or
85+
PreCallGraphStep::loadStoreStep(this, _, _)
86+
}
87+
}
88+
89+
private class AdditionalFlowStepFromPreCallGraph extends NodeWithPreCallGraphStep,
90+
DataFlow::AdditionalFlowStep {
91+
92+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
93+
pred = this and
94+
PreCallGraphStep::step(this, succ)
95+
}
96+
97+
override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
98+
pred = this and
99+
PreCallGraphStep::storeStep(this, succ, prop)
100+
}
101+
102+
override predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
103+
pred = this and
104+
PreCallGraphStep::loadStep(this, succ, prop)
105+
}
106+
107+
override predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
108+
pred = this and
109+
PreCallGraphStep::loadStoreStep(this, succ, prop)
110+
}
111+
}
112+
113+
private class AdditionalTypeTrackingStepFromPreCallGraph extends NodeWithPreCallGraphStep,
114+
DataFlow::AdditionalTypeTrackingStep {
115+
116+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
117+
pred = this and
118+
PreCallGraphStep::step(this, succ)
119+
}
120+
121+
override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
122+
pred = this and
123+
PreCallGraphStep::storeStep(this, succ, prop)
124+
}
125+
126+
override predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
127+
pred = this and
128+
PreCallGraphStep::loadStep(this, succ, prop)
129+
}
130+
131+
override predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
132+
pred = this and
133+
PreCallGraphStep::loadStoreStep(this, succ, prop)
134+
}
135+
}

0 commit comments

Comments
 (0)