Skip to content

Commit 90ad8e3

Browse files
author
Max Schaefer
committed
JavaScript: Import flow summaries from CSV data.
1 parent f4fed36 commit 90ad8e3

1 file changed

Lines changed: 169 additions & 0 deletions

File tree

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/**
2+
* Provides classes for importing source, sink and flow step summaries
3+
* from external CSV data added at snapshot build time.
4+
*/
5+
6+
import javascript
7+
import semmle.javascript.dataflow.Portals
8+
import external.ExternalArtifact
9+
10+
/**
11+
* An additional source specified in an `additional-sources.csv` file.
12+
*/
13+
class AdditionalSourceSpec extends ExternalData {
14+
AdditionalSourceSpec() {
15+
this.getDataPath() = "additional-sources.csv"
16+
}
17+
18+
/**
19+
* Gets the portal of this additional source.
20+
*/
21+
Portal getPortal() {
22+
result.toString() = getField(0)
23+
}
24+
25+
/**
26+
* Gets the flow label of this source.
27+
*/
28+
DataFlow::FlowLabel getFlowLabel() {
29+
result.toString() = getField(1)
30+
}
31+
32+
/**
33+
* Gets the configuration for which this is a source.
34+
*/
35+
DataFlow::Configuration getConfiguration() {
36+
result.toString() = getField(2)
37+
}
38+
39+
override string toString() {
40+
result = getPortal() + " as " + getFlowLabel() + " source for " + getConfiguration()
41+
}
42+
}
43+
44+
private class AdditionalSourceFromSpec extends DataFlow::AdditionalSource {
45+
AdditionalSourceSpec spec;
46+
47+
AdditionalSourceFromSpec() {
48+
this = spec.getPortal().getAnExitNode(_)
49+
}
50+
51+
override predicate isSourceFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
52+
cfg = spec.getConfiguration() and lbl = spec.getFlowLabel()
53+
}
54+
}
55+
56+
/**
57+
* An additional sink specified in an `additional-sinks.csv` file.
58+
*/
59+
class AdditionalSinkSpec extends ExternalData {
60+
AdditionalSinkSpec() {
61+
this.getDataPath() = "additional-sinks.csv"
62+
}
63+
64+
/**
65+
* Gets the portal specification of this additional sink.
66+
*/
67+
Portal getPortal() {
68+
result.toString() = getField(0)
69+
}
70+
71+
/**
72+
* Gets the flow label of this sink.
73+
*/
74+
DataFlow::FlowLabel getFlowLabel() {
75+
result.toString() = getField(1)
76+
}
77+
78+
/**
79+
* Gets the configuration for which this is a sink.
80+
*/
81+
DataFlow::Configuration getConfiguration() {
82+
result.toString() = getField(2)
83+
}
84+
85+
override string toString() {
86+
result = getPortal() + " as " + getFlowLabel() + " sink for " + getConfiguration()
87+
}
88+
}
89+
90+
private class AdditionalSinkFromSpec extends DataFlow::AdditionalSink {
91+
AdditionalSinkSpec spec;
92+
93+
AdditionalSinkFromSpec() {
94+
this = spec.getPortal().getAnEntryNode(_)
95+
}
96+
97+
override predicate isSinkFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
98+
cfg = spec.getConfiguration() and lbl = spec.getFlowLabel()
99+
}
100+
}
101+
/**
102+
* An additional flow step specified in an `additional-steps.csv` file.
103+
*/
104+
class AdditionalStepSpec extends ExternalData {
105+
AdditionalStepSpec() {
106+
this.getDataPath() = "additional-steps.csv"
107+
}
108+
109+
/**
110+
* Gets the start portal of this additional step.
111+
*/
112+
Portal getStartPortal() {
113+
result.toString() = getField(0)
114+
}
115+
116+
/**
117+
* Gets the start flow label of this additional step.
118+
*/
119+
DataFlow::FlowLabel getStartFlowLabel() {
120+
result.toString() = getField(1)
121+
}
122+
123+
/**
124+
* Gets the end portal of this additional step.
125+
*/
126+
Portal getEndPortal() {
127+
result.toString() = getField(2)
128+
}
129+
130+
/**
131+
* Gets the end flow label of this additional step.
132+
*/
133+
DataFlow::FlowLabel getEndFlowLabel() {
134+
result.toString() = getField(3)
135+
}
136+
137+
/**
138+
* Gets the configuration to which this step should be added.
139+
*/
140+
DataFlow::Configuration getConfiguration() {
141+
result.toString() = getField(4)
142+
}
143+
144+
override string toString() {
145+
result = "edge from " + getStartPortal() + " to " + getEndPortal() +
146+
", transforming " + getStartFlowLabel() + " into " + getEndFlowLabel() +
147+
" for " + getConfiguration()
148+
}
149+
}
150+
151+
private class AdditionalFlowStepFromSpec extends DataFlow::Configuration {
152+
AdditionalStepSpec spec;
153+
DataFlow::Node entry;
154+
DataFlow::Node exit;
155+
156+
AdditionalFlowStepFromSpec() {
157+
this = spec.getConfiguration() and
158+
entry = spec.getStartPortal().getAnEntryNode(_) and
159+
exit = spec.getEndPortal().getAnExitNode(_)
160+
}
161+
162+
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ,
163+
DataFlow::FlowLabel predlbl, DataFlow::FlowLabel succlbl) {
164+
pred = entry and
165+
succ = exit and
166+
predlbl = spec.getStartFlowLabel() and
167+
succlbl = spec.getEndFlowLabel()
168+
}
169+
}

0 commit comments

Comments
 (0)