Skip to content

Commit 4c59cfb

Browse files
committed
C#: Re-factor the invalidModelRow predicate.
1 parent 19469a2 commit 4c59cfb

1 file changed

Lines changed: 88 additions & 60 deletions

File tree

csharp/ql/lib/semmle/code/csharp/dataflow/CsvValidation.qll

Lines changed: 88 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,7 @@ private import internal.FlowSummaryImpl::Private::External
66
private import internal.FlowSummaryImplSpecific
77
private import ExternalFlow
88

9-
/** Holds if some row in a CSV-based flow model appears to contain typos. */
10-
query predicate invalidModelRow(string msg) {
11-
exists(
12-
string pred, string namespace, string type, string name, string signature, string ext,
13-
string provenance
14-
|
15-
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
16-
or
17-
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
18-
or
19-
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
20-
pred = "summary"
21-
or
22-
negativeSummaryModel(namespace, type, name, signature, provenance) and
23-
ext = "" and
24-
pred = "nonesummary"
25-
|
26-
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
27-
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
28-
or
29-
not type.regexpMatch("[a-zA-Z0-9_<>,\\+]+") and
30-
msg = "Dubious type \"" + type + "\" in " + pred + " model."
31-
or
32-
not name.regexpMatch("[a-zA-Z0-9_<>,]*") and
33-
msg = "Dubious member name \"" + name + "\" in " + pred + " model."
34-
or
35-
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
36-
msg = "Dubious signature \"" + signature + "\" in " + pred + " model."
37-
or
38-
not ext.regexpMatch("|Attribute") and
39-
msg = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
40-
or
41-
not provenance = ["manual", "generated"] and
42-
msg = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
43-
)
44-
or
9+
private string getInvalidModelInput() {
4510
exists(string pred, AccessPath input, string part |
4611
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
4712
or
@@ -56,9 +21,11 @@ query predicate invalidModelRow(string msg) {
5621
part = input.getToken(_) and
5722
parseParam(part, _)
5823
) and
59-
msg = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
24+
result = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
6025
)
61-
or
26+
}
27+
28+
private string getInvalidModelOutput() {
6229
exists(string pred, string output, string part |
6330
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
6431
or
@@ -67,9 +34,47 @@ query predicate invalidModelRow(string msg) {
6734
invalidSpecComponent(output, part) and
6835
not part = "" and
6936
not (part = ["Argument", "Parameter"] and pred = "source") and
70-
msg = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
37+
result = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
38+
)
39+
}
40+
41+
private string getInvalidModelKind() {
42+
exists(string row, string kind | summaryModel(row) |
43+
kind = row.splitAt(";", 8) and
44+
not kind = ["taint", "value"] and
45+
result = "Invalid kind \"" + kind + "\" in summary model."
7146
)
7247
or
48+
exists(string row, string kind | sinkModel(row) |
49+
kind = row.splitAt(";", 7) and
50+
not kind = ["code", "sql", "xss", "remote", "html"] and
51+
result = "Invalid kind \"" + kind + "\" in sink model."
52+
)
53+
or
54+
exists(string row, string kind | sourceModel(row) |
55+
kind = row.splitAt(";", 7) and
56+
not kind = "local" and
57+
result = "Invalid kind \"" + kind + "\" in source model."
58+
)
59+
}
60+
61+
private string getInvalidModelSubtype() {
62+
exists(string pred, string row, int expect |
63+
sourceModel(row) and expect = 9 and pred = "source"
64+
or
65+
sinkModel(row) and expect = 9 and pred = "sink"
66+
or
67+
summaryModel(row) and expect = 10 and pred = "summary"
68+
|
69+
exists(string b |
70+
b = row.splitAt(";", 2) and
71+
not b = ["true", "false"] and
72+
result = "Invalid boolean \"" + b + "\" in " + pred + " model."
73+
)
74+
)
75+
}
76+
77+
private string getInvalidModelColumnCount() {
7378
exists(string pred, string row, int expect |
7479
sourceModel(row) and expect = 9 and pred = "source"
7580
or
@@ -80,33 +85,56 @@ query predicate invalidModelRow(string msg) {
8085
exists(int cols |
8186
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
8287
cols != expect and
83-
msg =
88+
result =
8489
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
8590
" in " + row + "."
8691
)
92+
)
93+
}
94+
95+
/** Holds if some row in a CSV-based flow model appears to contain typos. */
96+
query predicate invalidModelRow(string msg) {
97+
exists(
98+
string pred, string namespace, string type, string name, string signature, string ext,
99+
string provenance
100+
|
101+
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
87102
or
88-
exists(string b |
89-
b = row.splitAt(";", 2) and
90-
not b = ["true", "false"] and
91-
msg = "Invalid boolean \"" + b + "\" in " + pred + " model."
92-
)
103+
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
104+
or
105+
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
106+
pred = "summary"
107+
or
108+
negativeSummaryModel(namespace, type, name, signature, provenance) and
109+
ext = "" and
110+
pred = "nonesummary"
111+
|
112+
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
113+
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
114+
or
115+
not type.regexpMatch("[a-zA-Z0-9_<>,\\+]+") and
116+
msg = "Dubious type \"" + type + "\" in " + pred + " model."
117+
or
118+
not name.regexpMatch("[a-zA-Z0-9_<>,]*") and
119+
msg = "Dubious member name \"" + name + "\" in " + pred + " model."
120+
or
121+
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
122+
msg = "Dubious signature \"" + signature + "\" in " + pred + " model."
123+
or
124+
not ext.regexpMatch("|Attribute") and
125+
msg = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
126+
or
127+
not provenance = ["manual", "generated"] and
128+
msg = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
93129
)
94130
or
95-
exists(string row, string kind | summaryModel(row) |
96-
kind = row.splitAt(";", 8) and
97-
not kind = ["taint", "value"] and
98-
msg = "Invalid kind \"" + kind + "\" in summary model."
99-
)
131+
msg = getInvalidModelInput()
100132
or
101-
exists(string row, string kind | sinkModel(row) |
102-
kind = row.splitAt(";", 7) and
103-
not kind = ["code", "sql", "xss", "remote", "html"] and
104-
msg = "Invalid kind \"" + kind + "\" in sink model."
105-
)
133+
msg = getInvalidModelOutput()
106134
or
107-
exists(string row, string kind | sourceModel(row) |
108-
kind = row.splitAt(";", 7) and
109-
not kind = "local" and
110-
msg = "Invalid kind \"" + kind + "\" in source model."
111-
)
135+
msg = getInvalidModelSubtype()
136+
or
137+
msg = getInvalidModelColumnCount()
138+
or
139+
msg = getInvalidModelKind()
112140
}

0 commit comments

Comments
 (0)