1
1
/**
2
2
* INTERNAL use only. This is an experimental API subject to change without notice.
3
3
*
4
- * Provides classes and predicates for dealing with flow models specified in CSV format.
4
+ * Provides classes and predicates for dealing with MaD flow models specified
5
+ * in data extensions and CSV format.
5
6
*
6
7
* The CSV specification has the following columns:
7
8
* - Sources:
8
- * `namespace ; type; subtypes; name; signature; ext; output; kind`
9
+ * `package ; type; subtypes; name; signature; ext; output; kind; provenance `
9
10
* - Sinks:
10
- * `namespace ; type; subtypes; name; signature; ext; input; kind`
11
+ * `package ; type; subtypes; name; signature; ext; input; kind; provenance `
11
12
* - Summaries:
12
- * `namespace ; type; subtypes; name; signature; ext; input; output; kind`
13
+ * `package ; type; subtypes; name; signature; ext; input; output; kind; provenance `
13
14
*
14
15
* The interpretation of a row is similar to API-graphs with a left-to-right
15
16
* reading.
16
- * 1. The `namespace ` column selects a package.
17
+ * 1. The `package ` column selects a package.
17
18
* 2. The `type` column selects a type within that package.
18
19
* 3. The `subtypes` is a boolean that indicates whether to jump to an
19
20
* arbitrary subtype of that type.
@@ -76,45 +77,6 @@ private module Frameworks {
76
77
private import semmle.go.frameworks.Stdlib
77
78
}
78
79
79
- /**
80
- * A unit class for adding additional source model rows.
81
- *
82
- * Extend this class to add additional source definitions.
83
- */
84
- class SourceModelCsv extends Unit {
85
- /** Holds if `row` specifies a source definition. */
86
- abstract predicate row ( string row ) ;
87
- }
88
-
89
- /**
90
- * A unit class for adding additional sink model rows.
91
- *
92
- * Extend this class to add additional sink definitions.
93
- */
94
- class SinkModelCsv extends Unit {
95
- /** Holds if `row` specifies a sink definition. */
96
- abstract predicate row ( string row ) ;
97
- }
98
-
99
- /**
100
- * A unit class for adding additional summary model rows.
101
- *
102
- * Extend this class to add additional flow summary definitions.
103
- */
104
- class SummaryModelCsv extends Unit {
105
- /** Holds if `row` specifies a summary definition. */
106
- abstract predicate row ( string row ) ;
107
- }
108
-
109
- /** Holds if `row` is a source model. */
110
- predicate sourceModel ( string row ) { any ( SourceModelCsv s ) .row ( row ) }
111
-
112
- /** Holds if `row` is a sink model. */
113
- predicate sinkModel ( string row ) { any ( SinkModelCsv s ) .row ( row ) }
114
-
115
- /** Holds if `row` is a summary model. */
116
- predicate summaryModel ( string row ) { any ( SummaryModelCsv s ) .row ( row ) }
117
-
118
80
/** Holds if a source model exists for the given parameters. */
119
81
predicate sourceModel = Extensions:: sourceModel / 9 ;
120
82
@@ -124,45 +86,45 @@ predicate sinkModel = Extensions::sinkModel/9;
124
86
/** Holds if a summary model exists for the given parameters. */
125
87
predicate summaryModel = Extensions:: summaryModel / 10 ;
126
88
127
- /** Holds if `package` have CSV framework coverage. */
128
- private predicate packageHasCsvCoverage ( string package ) {
89
+ /** Holds if `package` have MaD framework coverage. */
90
+ private predicate packageHasMaDCoverage ( string package ) {
129
91
sourceModel ( package , _, _, _, _, _, _, _, _) or
130
92
sinkModel ( package , _, _, _, _, _, _, _, _) or
131
93
summaryModel ( package , _, _, _, _, _, _, _, _, _)
132
94
}
133
95
134
96
/**
135
- * Holds if `package` and `subpkg` have CSV framework coverage and `subpkg`
97
+ * Holds if `package` and `subpkg` have MaD framework coverage and `subpkg`
136
98
* is a subpackage of `package`.
137
99
*/
138
100
private predicate packageHasASubpackage ( string package , string subpkg ) {
139
- packageHasCsvCoverage ( package ) and
140
- packageHasCsvCoverage ( subpkg ) and
101
+ packageHasMaDCoverage ( package ) and
102
+ packageHasMaDCoverage ( subpkg ) and
141
103
subpkg .prefix ( subpkg .indexOf ( "." ) ) = package
142
104
}
143
105
144
106
/**
145
- * Holds if `package` has CSV framework coverage and it is not a subpackage of
146
- * any other package with CSV framework coverage.
107
+ * Holds if `package` has MaD framework coverage and it is not a subpackage of
108
+ * any other package with MaD framework coverage.
147
109
*/
148
110
private predicate canonicalPackage ( string package ) {
149
- packageHasCsvCoverage ( package ) and not packageHasASubpackage ( _, package )
111
+ packageHasMaDCoverage ( package ) and not packageHasASubpackage ( _, package )
150
112
}
151
113
152
114
/**
153
- * Holds if `package` and `subpkg` have CSV framework coverage, `subpkg` is a
115
+ * Holds if `package` and `subpkg` have MaD framework coverage, `subpkg` is a
154
116
* subpackage of `package` (or they are the same), and `package` is not a
155
- * subpackage of any other package with CSV framework coverage.
117
+ * subpackage of any other package with MaD framework coverage.
156
118
*/
157
119
private predicate canonicalPackageHasASubpackage ( string package , string subpkg ) {
158
120
canonicalPackage ( package ) and
159
121
( subpkg = package or packageHasASubpackage ( package , subpkg ) )
160
122
}
161
123
162
124
/**
163
- * Holds if CSV framework coverage of `package` is `n` api endpoints of the
125
+ * Holds if MaD framework coverage of `package` is `n` api endpoints of the
164
126
* kind `(kind, part)`, and `pkgs` is the number of subpackages of `package`
165
- * which have CSV framework coverage (including `package` itself).
127
+ * which have MaD framework coverage (including `package` itself).
166
128
*/
167
129
predicate modelCoverage ( string package , int pkgs , string kind , string part , int n ) {
168
130
pkgs = strictcount ( string subpkg | canonicalPackageHasASubpackage ( package , subpkg ) ) and
@@ -193,8 +155,8 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
193
155
)
194
156
}
195
157
196
- /** Provides a query predicate to check the CSV data for validation errors. */
197
- module CsvValidation {
158
+ /** Provides a query predicate to check the MaD models for validation errors. */
159
+ module ModelValidation {
198
160
private string getInvalidModelInput ( ) {
199
161
exists ( string pred , AccessPath input , string part |
200
162
sinkModel ( _, _, _, _, _, _, input , _, _) and pred = "sink"
@@ -227,57 +189,25 @@ module CsvValidation {
227
189
}
228
190
229
191
private string getInvalidModelKind ( ) {
230
- exists ( string row , string kind | summaryModel ( row ) |
231
- kind = row .splitAt ( ";" , 8 ) and
192
+ exists ( string kind | summaryModel ( _, _, _, _, _, _, _, _, kind , _) |
232
193
not kind = [ "taint" , "value" ] and
233
194
result = "Invalid kind \"" + kind + "\" in summary model."
234
195
)
235
196
}
236
197
237
- private string getInvalidModelSubtype ( ) {
238
- exists ( string pred , string row |
239
- sourceModel ( row ) and pred = "source"
240
- or
241
- sinkModel ( row ) and pred = "sink"
242
- or
243
- summaryModel ( row ) and pred = "summary"
244
- |
245
- exists ( string b |
246
- b = row .splitAt ( ";" , 2 ) and
247
- not b = [ "true" , "false" ] and
248
- result = "Invalid boolean \"" + b + "\" in " + pred + " model."
249
- )
250
- )
251
- }
252
-
253
- private string getInvalidModelColumnCount ( ) {
254
- exists ( string pred , string row , int expect |
255
- sourceModel ( row ) and expect = 8 and pred = "source"
256
- or
257
- sinkModel ( row ) and expect = 8 and pred = "sink"
258
- or
259
- summaryModel ( row ) and expect = 9 and pred = "summary"
260
- |
261
- exists ( int cols |
262
- cols = 1 + max ( int n | exists ( row .splitAt ( ";" , n ) ) ) and
263
- cols != expect and
264
- result =
265
- "Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
266
- "."
267
- )
268
- )
269
- }
270
-
271
198
private string getInvalidModelSignature ( ) {
272
- exists ( string pred , string namespace , string type , string name , string signature , string ext |
273
- sourceModel ( namespace , type , _, name , signature , ext , _, _, _) and pred = "source"
199
+ exists (
200
+ string pred , string package , string type , string name , string signature , string ext ,
201
+ string provenance
202
+ |
203
+ sourceModel ( package , type , _, name , signature , ext , _, _, provenance ) and pred = "source"
274
204
or
275
- sinkModel ( namespace , type , _, name , signature , ext , _, _, _ ) and pred = "sink"
205
+ sinkModel ( package , type , _, name , signature , ext , _, _, provenance ) and pred = "sink"
276
206
or
277
- summaryModel ( namespace , type , _, name , signature , ext , _, _, _, _ ) and pred = "summary"
207
+ summaryModel ( package , type , _, name , signature , ext , _, _, _, provenance ) and pred = "summary"
278
208
|
279
- not namespace .regexpMatch ( "[a-zA-Z0-9_\\./]*" ) and
280
- result = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
209
+ not package .regexpMatch ( "[a-zA-Z0-9_\\./]*" ) and
210
+ result = "Dubious package \"" + package + "\" in " + pred + " model."
281
211
or
282
212
not type .regexpMatch ( "[a-zA-Z0-9_\\$<>]*" ) and
283
213
result = "Dubious type \"" + type + "\" in " + pred + " model."
@@ -290,26 +220,29 @@ module CsvValidation {
290
220
or
291
221
not ext .regexpMatch ( "|Annotated" ) and
292
222
result = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
223
+ or
224
+ not provenance = [ "manual" , "generated" ] and
225
+ result = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
293
226
)
294
227
}
295
228
296
- /** Holds if some row in a CSV-based flow model appears to contain typos. */
229
+ /** Holds if some row in a MaD flow model appears to contain typos. */
297
230
query predicate invalidModelRow ( string msg ) {
298
231
msg =
299
232
[
300
233
getInvalidModelSignature ( ) , getInvalidModelInput ( ) , getInvalidModelOutput ( ) ,
301
- getInvalidModelSubtype ( ) , getInvalidModelColumnCount ( ) , getInvalidModelKind ( )
234
+ getInvalidModelKind ( )
302
235
]
303
236
}
304
237
}
305
238
306
239
pragma [ nomagic]
307
240
private predicate elementSpec (
308
- string namespace , string type , boolean subtypes , string name , string signature , string ext
241
+ string package , string type , boolean subtypes , string name , string signature , string ext
309
242
) {
310
- sourceModel ( namespace , type , subtypes , name , signature , ext , _, _, _) or
311
- sinkModel ( namespace , type , subtypes , name , signature , ext , _, _, _) or
312
- summaryModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _)
243
+ sourceModel ( package , type , subtypes , name , signature , ext , _, _, _) or
244
+ sinkModel ( package , type , subtypes , name , signature , ext , _, _, _) or
245
+ summaryModel ( package , type , subtypes , name , signature , ext , _, _, _, _)
313
246
}
314
247
315
248
private string paramsStringPart ( Function f , int i ) {
@@ -405,7 +338,7 @@ predicate parseContent(string component, DataFlow::Content content) {
405
338
cached
406
339
private module Cached {
407
340
/**
408
- * Holds if `node` is specified as a source with the given kind in a CSV flow
341
+ * Holds if `node` is specified as a source with the given kind in a MaD flow
409
342
* model.
410
343
*/
411
344
cached
@@ -414,7 +347,7 @@ private module Cached {
414
347
}
415
348
416
349
/**
417
- * Holds if `node` is specified as a sink with the given kind in a CSV flow
350
+ * Holds if `node` is specified as a sink with the given kind in a MaD flow
418
351
* model.
419
352
*/
420
353
cached
0 commit comments