11/**
22 * INTERNAL use only. This is an experimental API subject to change without notice.
33 *
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.
56 *
67 * The CSV specification has the following columns:
78 * - Sources:
8- * `namespace ; type; subtypes; name; signature; ext; output; kind`
9+ * `package ; type; subtypes; name; signature; ext; output; kind; provenance `
910 * - Sinks:
10- * `namespace ; type; subtypes; name; signature; ext; input; kind`
11+ * `package ; type; subtypes; name; signature; ext; input; kind; provenance `
1112 * - Summaries:
12- * `namespace ; type; subtypes; name; signature; ext; input; output; kind`
13+ * `package ; type; subtypes; name; signature; ext; input; output; kind; provenance `
1314 *
1415 * The interpretation of a row is similar to API-graphs with a left-to-right
1516 * reading.
16- * 1. The `namespace ` column selects a package.
17+ * 1. The `package ` column selects a package.
1718 * 2. The `type` column selects a type within that package.
1819 * 3. The `subtypes` is a boolean that indicates whether to jump to an
1920 * arbitrary subtype of that type.
@@ -76,45 +77,6 @@ private module Frameworks {
7677 private import semmle.go.frameworks.Stdlib
7778}
7879
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-
11880/** Holds if a source model exists for the given parameters. */
11981predicate sourceModel = Extensions:: sourceModel / 9 ;
12082
@@ -124,45 +86,45 @@ predicate sinkModel = Extensions::sinkModel/9;
12486/** Holds if a summary model exists for the given parameters. */
12587predicate summaryModel = Extensions:: summaryModel / 10 ;
12688
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 ) {
12991 sourceModel ( package , _, _, _, _, _, _, _, _) or
13092 sinkModel ( package , _, _, _, _, _, _, _, _) or
13193 summaryModel ( package , _, _, _, _, _, _, _, _, _)
13294}
13395
13496/**
135- * Holds if `package` and `subpkg` have CSV framework coverage and `subpkg`
97+ * Holds if `package` and `subpkg` have MaD framework coverage and `subpkg`
13698 * is a subpackage of `package`.
13799 */
138100private predicate packageHasASubpackage ( string package , string subpkg ) {
139- packageHasCsvCoverage ( package ) and
140- packageHasCsvCoverage ( subpkg ) and
101+ packageHasMaDCoverage ( package ) and
102+ packageHasMaDCoverage ( subpkg ) and
141103 subpkg .prefix ( subpkg .indexOf ( "." ) ) = package
142104}
143105
144106/**
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.
147109 */
148110private predicate canonicalPackage ( string package ) {
149- packageHasCsvCoverage ( package ) and not packageHasASubpackage ( _, package )
111+ packageHasMaDCoverage ( package ) and not packageHasASubpackage ( _, package )
150112}
151113
152114/**
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
154116 * 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.
156118 */
157119private predicate canonicalPackageHasASubpackage ( string package , string subpkg ) {
158120 canonicalPackage ( package ) and
159121 ( subpkg = package or packageHasASubpackage ( package , subpkg ) )
160122}
161123
162124/**
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
164126 * 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).
166128 */
167129predicate modelCoverage ( string package , int pkgs , string kind , string part , int n ) {
168130 pkgs = strictcount ( string subpkg | canonicalPackageHasASubpackage ( package , subpkg ) ) and
@@ -193,8 +155,8 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
193155 )
194156}
195157
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 {
198160 private string getInvalidModelInput ( ) {
199161 exists ( string pred , AccessPath input , string part |
200162 sinkModel ( _, _, _, _, _, _, input , _, _) and pred = "sink"
@@ -227,57 +189,25 @@ module CsvValidation {
227189 }
228190
229191 private string getInvalidModelKind ( ) {
230- exists ( string row , string kind | summaryModel ( row ) |
231- kind = row .splitAt ( ";" , 8 ) and
192+ exists ( string kind | summaryModel ( _, _, _, _, _, _, _, _, kind , _) |
232193 not kind = [ "taint" , "value" ] and
233194 result = "Invalid kind \"" + kind + "\" in summary model."
234195 )
235196 }
236197
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-
271198 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"
274204 or
275- sinkModel ( namespace , type , _, name , signature , ext , _, _, _ ) and pred = "sink"
205+ sinkModel ( package , type , _, name , signature , ext , _, _, provenance ) and pred = "sink"
276206 or
277- summaryModel ( namespace , type , _, name , signature , ext , _, _, _, _ ) and pred = "summary"
207+ summaryModel ( package , type , _, name , signature , ext , _, _, _, provenance ) and pred = "summary"
278208 |
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."
281211 or
282212 not type .regexpMatch ( "[a-zA-Z0-9_\\$<>]*" ) and
283213 result = "Dubious type \"" + type + "\" in " + pred + " model."
@@ -290,26 +220,29 @@ module CsvValidation {
290220 or
291221 not ext .regexpMatch ( "|Annotated" ) and
292222 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."
293226 )
294227 }
295228
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. */
297230 query predicate invalidModelRow ( string msg ) {
298231 msg =
299232 [
300233 getInvalidModelSignature ( ) , getInvalidModelInput ( ) , getInvalidModelOutput ( ) ,
301- getInvalidModelSubtype ( ) , getInvalidModelColumnCount ( ) , getInvalidModelKind ( )
234+ getInvalidModelKind ( )
302235 ]
303236 }
304237}
305238
306239pragma [ nomagic]
307240private 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
309242) {
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 , _, _, _, _)
313246}
314247
315248private string paramsStringPart ( Function f , int i ) {
@@ -405,7 +338,7 @@ predicate parseContent(string component, DataFlow::Content content) {
405338cached
406339private module Cached {
407340 /**
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
409342 * model.
410343 */
411344 cached
@@ -414,7 +347,7 @@ private module Cached {
414347 }
415348
416349 /**
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
418351 * model.
419352 */
420353 cached
0 commit comments