Skip to content

Commit d709343

Browse files
authored
Merge pull request #21011 from aschackmull/mad/shared-externalflow
Java/C++/Go/C#: Share parts of ExternalFlow.qll
2 parents 74ed18a + 64a48e4 commit d709343

File tree

15 files changed

+631
-634
lines changed

15 files changed

+631
-634
lines changed

cpp/ql/lib/ext/empty.model.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ extensions:
99
pack: codeql/cpp-all
1010
extensible: sinkModel
1111
data: []
12+
- addsTo:
13+
pack: codeql/cpp-all
14+
extensible: barrierModel
15+
data: []
16+
- addsTo:
17+
pack: codeql/cpp-all
18+
extensible: barrierGuardModel
19+
data: []
1220
- addsTo:
1321
pack: codeql/cpp-all
1422
extensible: summaryModel

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 74 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ private import internal.FlowSummaryImpl
101101
private import internal.FlowSummaryImpl::Public
102102
private import internal.FlowSummaryImpl::Private
103103
private import internal.FlowSummaryImpl::Private::External
104-
private import internal.ExternalFlowExtensions as Extensions
104+
private import internal.ExternalFlowExtensions::Extensions as Extensions
105105
private import codeql.mad.ModelValidation as SharedModelVal
106106
private import codeql.util.Unit
107+
private import codeql.mad.static.ModelsAsData as SharedMaD
107108

108109
/**
109110
* A unit class for adding additional source model rows.
@@ -144,135 +145,82 @@ predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
144145
/** Holds if `row` is a summary model. */
145146
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
146147

147-
/** Holds if a source model exists for the given parameters. */
148-
predicate sourceModel(
149-
string namespace, string type, boolean subtypes, string name, string signature, string ext,
150-
string output, string kind, string provenance, string model
151-
) {
152-
exists(string row |
153-
sourceModel(row) and
154-
row.splitAt(";", 0) = namespace and
155-
row.splitAt(";", 1) = type and
156-
row.splitAt(";", 2) = subtypes.toString() and
157-
subtypes = [true, false] and
158-
row.splitAt(";", 3) = name and
159-
row.splitAt(";", 4) = signature and
160-
row.splitAt(";", 5) = ext and
161-
row.splitAt(";", 6) = output and
162-
row.splitAt(";", 7) = kind
163-
) and
164-
provenance = "manual" and
165-
model = ""
166-
or
167-
exists(QlBuiltins::ExtensionId madId |
168-
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
169-
provenance, madId) and
170-
model = "MaD:" + madId.toString()
171-
)
172-
}
173-
174-
/** Holds if a sink model exists for the given parameters. */
175-
predicate sinkModel(
176-
string namespace, string type, boolean subtypes, string name, string signature, string ext,
177-
string input, string kind, string provenance, string model
178-
) {
179-
exists(string row |
180-
sinkModel(row) and
181-
row.splitAt(";", 0) = namespace and
182-
row.splitAt(";", 1) = type and
183-
row.splitAt(";", 2) = subtypes.toString() and
184-
subtypes = [true, false] and
185-
row.splitAt(";", 3) = name and
186-
row.splitAt(";", 4) = signature and
187-
row.splitAt(";", 5) = ext and
188-
row.splitAt(";", 6) = input and
189-
row.splitAt(";", 7) = kind
190-
) and
191-
provenance = "manual" and
192-
model = ""
193-
or
194-
exists(QlBuiltins::ExtensionId madId |
195-
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance,
196-
madId) and
197-
model = "MaD:" + madId.toString()
198-
)
199-
}
200-
201-
/**
202-
* Holds if a summary model exists for the given parameters.
203-
*
204-
* This predicate does not expand `@` to `*`s.
205-
*/
206-
private predicate summaryModel0(
207-
string namespace, string type, boolean subtypes, string name, string signature, string ext,
208-
string input, string output, string kind, string provenance, string model
209-
) {
210-
exists(string row |
211-
summaryModel(row) and
212-
row.splitAt(";", 0) = namespace and
213-
row.splitAt(";", 1) = type and
214-
row.splitAt(";", 2) = subtypes.toString() and
215-
subtypes = [true, false] and
216-
row.splitAt(";", 3) = name and
217-
row.splitAt(";", 4) = signature and
218-
row.splitAt(";", 5) = ext and
219-
row.splitAt(";", 6) = input and
220-
row.splitAt(";", 7) = output and
221-
row.splitAt(";", 8) = kind
222-
) and
223-
provenance = "manual" and
224-
model = ""
225-
or
226-
exists(QlBuiltins::ExtensionId madId |
227-
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
228-
provenance, madId) and
229-
model = "MaD:" + madId.toString()
230-
)
231-
}
232-
233-
/**
234-
* Holds if the given extension tuple `madId` should pretty-print as `model`.
235-
*
236-
* This predicate should only be used in tests.
237-
*/
238-
predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
239-
exists(
148+
private module MadInput implements SharedMaD::InputSig {
149+
/** Holds if a source model exists for the given parameters. */
150+
predicate additionalSourceModel(
240151
string namespace, string type, boolean subtypes, string name, string signature, string ext,
241-
string output, string kind, string provenance
242-
|
243-
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
244-
provenance, madId)
245-
|
246-
model =
247-
"Source: " + namespace + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; "
248-
+ ext + "; " + output + "; " + kind + "; " + provenance
249-
)
250-
or
251-
exists(
152+
string output, string kind, string provenance, string model
153+
) {
154+
exists(string row |
155+
sourceModel(row) and
156+
row.splitAt(";", 0) = namespace and
157+
row.splitAt(";", 1) = type and
158+
row.splitAt(";", 2) = subtypes.toString() and
159+
subtypes = [true, false] and
160+
row.splitAt(";", 3) = name and
161+
row.splitAt(";", 4) = signature and
162+
row.splitAt(";", 5) = ext and
163+
row.splitAt(";", 6) = output and
164+
row.splitAt(";", 7) = kind
165+
) and
166+
provenance = "manual" and
167+
model = ""
168+
}
169+
170+
/** Holds if a sink model exists for the given parameters. */
171+
predicate additionalSinkModel(
252172
string namespace, string type, boolean subtypes, string name, string signature, string ext,
253-
string input, string kind, string provenance
254-
|
255-
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance,
256-
madId)
257-
|
258-
model =
259-
"Sink: " + namespace + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; " +
260-
ext + "; " + input + "; " + kind + "; " + provenance
261-
)
262-
or
263-
exists(
173+
string input, string kind, string provenance, string model
174+
) {
175+
exists(string row |
176+
sinkModel(row) and
177+
row.splitAt(";", 0) = namespace and
178+
row.splitAt(";", 1) = type and
179+
row.splitAt(";", 2) = subtypes.toString() and
180+
subtypes = [true, false] and
181+
row.splitAt(";", 3) = name and
182+
row.splitAt(";", 4) = signature and
183+
row.splitAt(";", 5) = ext and
184+
row.splitAt(";", 6) = input and
185+
row.splitAt(";", 7) = kind
186+
) and
187+
provenance = "manual" and
188+
model = ""
189+
}
190+
191+
/**
192+
* Holds if a summary model exists for the given parameters.
193+
*
194+
* This predicate does not expand `@` to `*`s.
195+
*/
196+
predicate additionalSummaryModel(
264197
string namespace, string type, boolean subtypes, string name, string signature, string ext,
265-
string input, string output, string kind, string provenance
266-
|
267-
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
268-
provenance, madId)
269-
|
270-
model =
271-
"Summary: " + namespace + "; " + type + "; " + subtypes + "; " + name + "; " + signature +
272-
"; " + ext + "; " + input + "; " + output + "; " + kind + "; " + provenance
273-
)
198+
string input, string output, string kind, string provenance, string model
199+
) {
200+
exists(string row |
201+
summaryModel(row) and
202+
row.splitAt(";", 0) = namespace and
203+
row.splitAt(";", 1) = type and
204+
row.splitAt(";", 2) = subtypes.toString() and
205+
subtypes = [true, false] and
206+
row.splitAt(";", 3) = name and
207+
row.splitAt(";", 4) = signature and
208+
row.splitAt(";", 5) = ext and
209+
row.splitAt(";", 6) = input and
210+
row.splitAt(";", 7) = output and
211+
row.splitAt(";", 8) = kind
212+
) and
213+
provenance = "manual" and
214+
model = ""
215+
}
216+
217+
string namespaceSegmentSeparator() { result = "::" }
274218
}
275219

220+
private module MaD = SharedMaD::ModelsAsData<Extensions, MadInput>;
221+
222+
import MaD
223+
276224
/**
277225
* Holds if `input` is `input0`, but with all occurrences of `@` replaced
278226
* by `n` repetitions of `*` (and similarly for `output` and `output0`).
@@ -294,69 +242,13 @@ predicate summaryModel(
294242
string input, string output, string kind, string provenance, string model
295243
) {
296244
exists(string input0, string output0 |
297-
summaryModel0(namespace, type, subtypes, name, signature, ext, input0, output0, kind,
245+
MaD::summaryModel(namespace, type, subtypes, name, signature, ext, input0, output0, kind,
298246
provenance, model) and
299247
expandInputAndOutput(input0, input, output0, output,
300248
[0 .. Private::getMaxElementContentIndirectionIndex() - 1])
301249
)
302250
}
303251

304-
private predicate relevantNamespace(string namespace) {
305-
sourceModel(namespace, _, _, _, _, _, _, _, _, _) or
306-
sinkModel(namespace, _, _, _, _, _, _, _, _, _) or
307-
summaryModel(namespace, _, _, _, _, _, _, _, _, _, _)
308-
}
309-
310-
private predicate namespaceLink(string shortns, string longns) {
311-
relevantNamespace(shortns) and
312-
relevantNamespace(longns) and
313-
longns.prefix(longns.indexOf("::")) = shortns
314-
}
315-
316-
private predicate canonicalNamespace(string namespace) {
317-
relevantNamespace(namespace) and not namespaceLink(_, namespace)
318-
}
319-
320-
private predicate canonicalNamespaceLink(string namespace, string subns) {
321-
canonicalNamespace(namespace) and
322-
(subns = namespace or namespaceLink(namespace, subns))
323-
}
324-
325-
/**
326-
* Holds if MaD framework coverage of `namespace` is `n` api endpoints of the
327-
* kind `(kind, part)`, and `namespaces` is the number of subnamespaces of
328-
* `namespace` which have MaD framework coverage (including `namespace`
329-
* itself).
330-
*/
331-
predicate modelCoverage(string namespace, int namespaces, string kind, string part, int n) {
332-
namespaces = strictcount(string subns | canonicalNamespaceLink(namespace, subns)) and
333-
(
334-
part = "source" and
335-
n =
336-
strictcount(string subns, string type, boolean subtypes, string name, string signature,
337-
string ext, string output, string provenance, string model |
338-
canonicalNamespaceLink(namespace, subns) and
339-
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance, model)
340-
)
341-
or
342-
part = "sink" and
343-
n =
344-
strictcount(string subns, string type, boolean subtypes, string name, string signature,
345-
string ext, string input, string provenance, string model |
346-
canonicalNamespaceLink(namespace, subns) and
347-
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance, model)
348-
)
349-
or
350-
part = "summary" and
351-
n =
352-
strictcount(string subns, string type, boolean subtypes, string name, string signature,
353-
string ext, string input, string output, string provenance |
354-
canonicalNamespaceLink(namespace, subns) and
355-
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance, _)
356-
)
357-
)
358-
}
359-
360252
/** Provides a query predicate to check the CSV data for validation errors. */
361253
module CsvValidation {
362254
private string getInvalidModelInput() {

cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* This module provides extensible predicates for defining MaD models.
33
*/
44

5+
private import codeql.mad.static.ModelsAsData as SharedMaD
6+
57
/**
68
* Holds if an external source model exists for the given parameters.
79
*/
@@ -18,10 +20,39 @@ extensible predicate sinkModel(
1820
string input, string kind, string provenance, QlBuiltins::ExtensionId madId
1921
);
2022

23+
/**
24+
* Holds if a barrier model exists for the given parameters.
25+
*/
26+
extensible predicate barrierModel(
27+
string namespace, string type, boolean subtypes, string name, string signature, string ext,
28+
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
29+
);
30+
31+
/**
32+
* Holds if a barrier guard model exists for the given parameters.
33+
*/
34+
extensible predicate barrierGuardModel(
35+
string namespace, string type, boolean subtypes, string name, string signature, string ext,
36+
string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId
37+
);
38+
2139
/**
2240
* Holds if an external summary model exists for the given parameters.
2341
*/
2442
extensible predicate summaryModel(
2543
string namespace, string type, boolean subtypes, string name, string signature, string ext,
2644
string input, string output, string kind, string provenance, QlBuiltins::ExtensionId madId
2745
);
46+
47+
/**
48+
* Holds if a neutral model exists for the given parameters.
49+
*/
50+
extensible predicate neutralModel(
51+
string namespace, string type, string name, string signature, string kind, string provenance
52+
);
53+
54+
module Extensions implements SharedMaD::ExtensionsSig {
55+
import ExternalFlowExtensions
56+
57+
predicate namespaceGrouping(string group, string namespace) { none() }
58+
}

csharp/ql/lib/ext/empty.model.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ extensions:
1111
extensible: sinkModel
1212
data: []
1313

14+
- addsTo:
15+
pack: codeql/csharp-all
16+
extensible: barrierModel
17+
data: []
18+
19+
- addsTo:
20+
pack: codeql/csharp-all
21+
extensible: barrierGuardModel
22+
data: []
23+
1424
- addsTo:
1525
pack: codeql/csharp-all
1626
extensible: summaryModel

0 commit comments

Comments
 (0)