Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3aacc5f

Browse files
committed
C++: Copy FlowSummaryImpl.qll from Swift.
1 parent fbf9545 commit 3aacc5f

1 file changed

Lines changed: 259 additions & 0 deletions

File tree

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
/**
2+
* Provides classes and predicates for defining flow summaries.
3+
*/
4+
5+
private import swift
6+
private import codeql.dataflow.internal.FlowSummaryImpl
7+
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
8+
private import DataFlowImplSpecific as DataFlowImplSpecific
9+
private import DataFlowImplSpecific::Private
10+
private import DataFlowImplSpecific::Public
11+
private import DataFlowImplCommon
12+
private import codeql.swift.dataflow.ExternalFlow
13+
14+
module Input implements InputSig<DataFlowImplSpecific::SwiftDataFlow> {
15+
class SummarizedCallableBase = Function;
16+
17+
ArgumentPosition callbackSelfParameterPosition() { result instanceof ThisArgumentPosition }
18+
19+
ReturnKind getStandardReturnValueKind() { result instanceof NormalReturnKind }
20+
21+
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
22+
23+
string encodeArgumentPosition(ArgumentPosition pos) { result = pos.toString() }
24+
25+
string encodeReturn(ReturnKind rk, string arg) {
26+
rk != getStandardReturnValueKind() and
27+
result = "ReturnValue" and
28+
arg = rk.toString()
29+
}
30+
31+
string encodeContent(ContentSet cs, string arg) {
32+
exists(Content::FieldContent c |
33+
cs.isSingleton(c) and
34+
result = "Field" and
35+
arg = c.getField().getName()
36+
)
37+
or
38+
exists(Content::TupleContent c |
39+
cs.isSingleton(c) and
40+
result = "TupleElement" and
41+
arg = c.getIndex().toString()
42+
)
43+
or
44+
exists(Content::EnumContent c, string sig |
45+
cs.isSingleton(c) and
46+
sig = c.getSignature()
47+
|
48+
if sig = "some:0"
49+
then
50+
result = "OptionalSome" and
51+
arg = ""
52+
else (
53+
result = "EnumElement" and
54+
arg = sig
55+
)
56+
)
57+
or
58+
exists(Content::CollectionContent c |
59+
cs.isSingleton(c) and
60+
result = "CollectionElement" and
61+
arg = ""
62+
)
63+
}
64+
65+
string encodeWithoutContent(ContentSet c, string arg) {
66+
result = "WithoutContent" + c and arg = ""
67+
}
68+
69+
string encodeWithContent(ContentSet c, string arg) { result = "WithContent" + c and arg = "" }
70+
71+
bindingset[token]
72+
ContentSet decodeUnknownContent(AccessPath::AccessPathTokenBase token) {
73+
// map legacy "ArrayElement" specification components to `CollectionContent`
74+
token.getName() = "ArrayElement" and
75+
result.isSingleton(any(Content::CollectionContent c))
76+
or
77+
token.getName() = "CollectionElement" and
78+
result.isSingleton(any(Content::CollectionContent c))
79+
}
80+
81+
bindingset[token]
82+
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
83+
// needed to support `Argument[x..y]` ranges and `Argument[-1]`
84+
token.getName() = "Argument" and
85+
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
86+
result.(PositionalParameterPosition).getIndex() = pos
87+
or
88+
pos = -1 and result instanceof ThisParameterPosition
89+
)
90+
}
91+
92+
bindingset[token]
93+
ArgumentPosition decodeUnknownArgumentPosition(AccessPath::AccessPathTokenBase token) {
94+
// needed to support `Parameter[x..y]` ranges and `Parameter[-1]`
95+
token.getName() = "Parameter" and
96+
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
97+
result.(PositionalArgumentPosition).getIndex() = pos
98+
or
99+
pos = -1 and
100+
result instanceof ThisArgumentPosition
101+
)
102+
}
103+
}
104+
105+
private import Make<DataFlowImplSpecific::SwiftDataFlow, Input> as Impl
106+
107+
private module StepsInput implements Impl::Private::StepsInputSig {
108+
DataFlowCall getACall(Public::SummarizedCallable sc) { result.asCall().getStaticTarget() = sc }
109+
}
110+
111+
module SourceSinkInterpretationInput implements
112+
Impl::Private::External::SourceSinkInterpretationInputSig<Location>
113+
{
114+
class Element = AstNode;
115+
116+
class SourceOrSinkElement = Element;
117+
118+
/**
119+
* Holds if an external source specification exists for `e` with output specification
120+
* `output`, kind `kind`, and provenance `provenance`.
121+
*/
122+
predicate sourceElement(SourceOrSinkElement e, string output, string kind) {
123+
exists(
124+
string namespace, string type, boolean subtypes, string name, string signature, string ext
125+
|
126+
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, _) and
127+
e = interpretElement(namespace, type, subtypes, name, signature, ext)
128+
)
129+
}
130+
131+
/**
132+
* Holds if an external sink specification exists for `e` with input specification
133+
* `input`, kind `kind` and provenance `provenance`.
134+
*/
135+
predicate sinkElement(SourceOrSinkElement e, string input, string kind) {
136+
exists(
137+
string package, string type, boolean subtypes, string name, string signature, string ext
138+
|
139+
sinkModel(package, type, subtypes, name, signature, ext, input, kind, _) and
140+
e = interpretElement(package, type, subtypes, name, signature, ext)
141+
)
142+
}
143+
144+
private newtype TInterpretNode =
145+
TElement_(Element n) or
146+
TNode_(Node n) or
147+
TDataFlowCall_(DataFlowCall c)
148+
149+
/** An entity used to interpret a source/sink specification. */
150+
class InterpretNode extends TInterpretNode {
151+
/** Gets the element that this node corresponds to, if any. */
152+
SourceOrSinkElement asElement() { this = TElement_(result) }
153+
154+
/** Gets the data-flow node that this node corresponds to, if any. */
155+
Node asNode() { this = TNode_(result) }
156+
157+
/** Gets the call that this node corresponds to, if any. */
158+
DataFlowCall asCall() { this = TDataFlowCall_(result) }
159+
160+
/** Gets the callable that this node corresponds to, if any. */
161+
DataFlowCallable asCallable() { result.getUnderlyingCallable() = this.asElement() }
162+
163+
/** Gets the target of this call, if any. */
164+
Element getCallTarget() { result = this.asCall().asCall().getStaticTarget() }
165+
166+
/** Gets a textual representation of this node. */
167+
string toString() {
168+
result = this.asElement().toString()
169+
or
170+
result = this.asNode().toString()
171+
or
172+
result = this.asCall().toString()
173+
}
174+
175+
/** Gets the location of this node. */
176+
Location getLocation() {
177+
result = this.asElement().getLocation()
178+
or
179+
result = this.asNode().getLocation()
180+
or
181+
result = this.asCall().getLocation()
182+
}
183+
}
184+
185+
/** Provides additional sink specification logic. */
186+
bindingset[c]
187+
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) {
188+
// Allow fields to be picked as output nodes.
189+
exists(Node n, AstNode ast |
190+
n = node.asNode() and
191+
ast = mid.asElement()
192+
|
193+
c = "" and
194+
n.asExpr().(MemberRefExpr).getMember() = ast
195+
)
196+
}
197+
198+
/** Provides additional source specification logic. */
199+
bindingset[c]
200+
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) {
201+
exists(Node n, AstNode ast, MemberRefExpr e |
202+
n = node.asNode() and
203+
ast = mid.asElement() and
204+
e.getMember() = ast
205+
|
206+
// Allow fields to be picked as input nodes.
207+
c = "" and
208+
e.getBase() = n.asExpr()
209+
or
210+
// Allow post update nodes to be picked as input nodes when the `input` column
211+
// of the row is `PostUpdate`.
212+
c = "PostUpdate" and
213+
e.getBase() = n.(PostUpdateNode).getPreUpdateNode().asExpr()
214+
)
215+
}
216+
}
217+
218+
module Private {
219+
import Impl::Private
220+
221+
module Steps = Impl::Private::Steps<StepsInput>;
222+
223+
module External {
224+
import Impl::Private::External
225+
import Impl::Private::External::SourceSinkInterpretation<Location, SourceSinkInterpretationInput>
226+
}
227+
228+
/**
229+
* Provides predicates for constructing summary components.
230+
*/
231+
module SummaryComponent {
232+
private import Impl::Private::SummaryComponent as SC
233+
234+
predicate parameter = SC::parameter/1;
235+
236+
predicate argument = SC::argument/1;
237+
238+
predicate content = SC::content/1;
239+
240+
predicate withoutContent = SC::withoutContent/1;
241+
242+
predicate withContent = SC::withContent/1;
243+
}
244+
245+
/**
246+
* Provides predicates for constructing stacks of summary components.
247+
*/
248+
module SummaryComponentStack {
249+
private import Impl::Private::SummaryComponentStack as SCS
250+
251+
predicate singleton = SCS::singleton/1;
252+
253+
predicate push = SCS::push/2;
254+
255+
predicate argument = SCS::argument/1;
256+
}
257+
}
258+
259+
module Public = Impl::Public;

0 commit comments

Comments
 (0)