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

Skip to content

Commit 4939439

Browse files
committed
Java: Re-factor CSV Validation into standalone module.
1 parent 053460f commit 4939439

5 files changed

Lines changed: 157 additions & 124 deletions

File tree

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/** Provides a query predicate to check the CSV data for validation errors. */
2+
3+
import java
4+
private import ExternalFlow
5+
private import internal.FlowSummaryImpl::Private::External
6+
private import internal.AccessPathSyntax
7+
8+
private string getInvalidModelInput() {
9+
exists(string pred, string input, string part |
10+
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
11+
or
12+
summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary"
13+
|
14+
(
15+
invalidSpecComponent(input, part) and
16+
not part = "" and
17+
not (part = "Argument" and pred = "sink") and
18+
not parseArg(part, _)
19+
or
20+
part = input.(AccessPath).getToken(0) and
21+
parseParam(part, _)
22+
) and
23+
result = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
24+
)
25+
}
26+
27+
private string getInvalidModelOutput() {
28+
exists(string pred, string output, string part |
29+
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
30+
or
31+
summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary"
32+
|
33+
invalidSpecComponent(output, part) and
34+
not part = "" and
35+
not (part = ["Argument", "Parameter"] and pred = "source") and
36+
result = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
37+
)
38+
}
39+
40+
private string getInvalidModelKind() {
41+
exists(string row, string kind | summaryModel(row) |
42+
kind = row.splitAt(";", 8) and
43+
not kind = ["taint", "value"] and
44+
result = "Invalid kind \"" + kind + "\" in summary model."
45+
)
46+
or
47+
exists(string row, string kind | sinkModel(row) |
48+
kind = row.splitAt(";", 7) and
49+
not kind =
50+
[
51+
"open-url", "jndi-injection", "ldap", "sql", "jdbc-url", "logging", "mvel", "xpath",
52+
"groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-open-stream",
53+
"url-redirect", "create-file", "write-file", "set-hostname-verifier", "header-splitting",
54+
"information-leak", "xslt", "jexl", "bean-validation"
55+
] and
56+
not kind.matches("regex-use%") and
57+
not kind.matches("qltest%") and
58+
result = "Invalid kind \"" + kind + "\" in sink model."
59+
)
60+
or
61+
exists(string row, string kind | sourceModel(row) |
62+
kind = row.splitAt(";", 7) and
63+
not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and
64+
not kind.matches("qltest%") and
65+
result = "Invalid kind \"" + kind + "\" in source model."
66+
)
67+
}
68+
69+
private string getInvalidModelSubtype() {
70+
exists(string pred, string row, int expect |
71+
sourceModel(row) and expect = 9 and pred = "source"
72+
or
73+
sinkModel(row) and expect = 9 and pred = "sink"
74+
or
75+
summaryModel(row) and expect = 10 and pred = "summary"
76+
|
77+
exists(string b |
78+
b = row.splitAt(";", 2) and
79+
not b = ["true", "false"] and
80+
result = "Invalid boolean \"" + b + "\" in " + pred + " model."
81+
)
82+
)
83+
}
84+
85+
private string getInvalidModelColumnCount() {
86+
exists(string pred, string row, int expect |
87+
sourceModel(row) and expect = 9 and pred = "source"
88+
or
89+
sinkModel(row) and expect = 9 and pred = "sink"
90+
or
91+
summaryModel(row) and expect = 10 and pred = "summary"
92+
|
93+
exists(int cols |
94+
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
95+
cols != expect and
96+
result =
97+
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
98+
" in " + row + "."
99+
)
100+
)
101+
}
102+
103+
private string getInvalidModelSignature() {
104+
exists(
105+
string pred, string namespace, string type, string name, string signature, string ext,
106+
string provenance
107+
|
108+
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
109+
or
110+
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
111+
or
112+
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
113+
pred = "summary"
114+
or
115+
negativeSummaryModel(namespace, type, name, signature, provenance) and
116+
ext = "" and
117+
pred = "nonesummary"
118+
|
119+
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
120+
result = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
121+
or
122+
not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and
123+
result = "Dubious type \"" + type + "\" in " + pred + " model."
124+
or
125+
not name.regexpMatch("[a-zA-Z0-9_]*") and
126+
result = "Dubious name \"" + name + "\" in " + pred + " model."
127+
or
128+
not signature.regexpMatch("|\\([a-zA-Z0-9_\\.\\$<>,\\[\\]]*\\)") and
129+
result = "Dubious signature \"" + signature + "\" in " + pred + " model."
130+
or
131+
not ext.regexpMatch("|Annotated") and
132+
result = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
133+
or
134+
not provenance = ["manual", "generated"] and
135+
result = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
136+
)
137+
}
138+
139+
/** Holds if some row in a CSV-based flow model appears to contain typos. */
140+
query predicate invalidModelRow(string msg) {
141+
msg =
142+
[
143+
getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(),
144+
getInvalidModelSubtype(), getInvalidModelColumnCount(), getInvalidModelKind()
145+
]
146+
}

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

Lines changed: 8 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -428,13 +428,17 @@ private class SummaryModelCsvBase extends SummaryModelCsv {
428428
}
429429
}
430430

431-
private predicate sourceModel(string row) { any(SourceModelCsv s).row(row) }
431+
/** Holds if `row` is a source model. */
432+
predicate sourceModel(string row) { any(SourceModelCsv s).row(row) }
432433

433-
private predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
434+
/** Holds if `row` is a sink model. */
435+
predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
434436

435-
private predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
437+
/** Holds if `row` is a summary model. */
438+
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
436439

437-
private predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) }
440+
/** Holds if `row` is negative summary model. */
441+
predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) }
438442

439443
/** Holds if a source model exists for the given parameters. */
440444
predicate sourceModel(
@@ -571,123 +575,6 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
571575
)
572576
}
573577

574-
/** Provides a query predicate to check the CSV data for validation errors. */
575-
module CsvValidation {
576-
/** Holds if some row in a CSV-based flow model appears to contain typos. */
577-
query predicate invalidModelRow(string msg) {
578-
exists(
579-
string pred, string namespace, string type, string name, string signature, string ext,
580-
string provenance
581-
|
582-
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
583-
or
584-
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
585-
or
586-
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
587-
pred = "summary"
588-
or
589-
negativeSummaryModel(namespace, type, name, signature, provenance) and
590-
ext = "" and
591-
pred = "nonesummary"
592-
|
593-
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
594-
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
595-
or
596-
not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and
597-
msg = "Dubious type \"" + type + "\" in " + pred + " model."
598-
or
599-
not name.regexpMatch("[a-zA-Z0-9_]*") and
600-
msg = "Dubious name \"" + name + "\" in " + pred + " model."
601-
or
602-
not signature.regexpMatch("|\\([a-zA-Z0-9_\\.\\$<>,\\[\\]]*\\)") and
603-
msg = "Dubious signature \"" + signature + "\" in " + pred + " model."
604-
or
605-
not ext.regexpMatch("|Annotated") and
606-
msg = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
607-
or
608-
not provenance = ["manual", "generated"] and
609-
msg = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
610-
)
611-
or
612-
exists(string pred, string input, string part |
613-
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
614-
or
615-
summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary"
616-
|
617-
(
618-
invalidSpecComponent(input, part) and
619-
not part = "" and
620-
not (part = "Argument" and pred = "sink") and
621-
not parseArg(part, _)
622-
or
623-
part = input.(AccessPath).getToken(0) and
624-
parseParam(part, _)
625-
) and
626-
msg = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
627-
)
628-
or
629-
exists(string pred, string output, string part |
630-
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
631-
or
632-
summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary"
633-
|
634-
invalidSpecComponent(output, part) and
635-
not part = "" and
636-
not (part = ["Argument", "Parameter"] and pred = "source") and
637-
msg = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
638-
)
639-
or
640-
exists(string pred, string row, int expect |
641-
sourceModel(row) and expect = 9 and pred = "source"
642-
or
643-
sinkModel(row) and expect = 9 and pred = "sink"
644-
or
645-
summaryModel(row) and expect = 10 and pred = "summary"
646-
|
647-
exists(int cols |
648-
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
649-
cols != expect and
650-
msg =
651-
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
652-
" in " + row + "."
653-
)
654-
or
655-
exists(string b |
656-
b = row.splitAt(";", 2) and
657-
not b = ["true", "false"] and
658-
msg = "Invalid boolean \"" + b + "\" in " + pred + " model."
659-
)
660-
)
661-
or
662-
exists(string row, string kind | summaryModel(row) |
663-
kind = row.splitAt(";", 8) and
664-
not kind = ["taint", "value"] and
665-
msg = "Invalid kind \"" + kind + "\" in summary model."
666-
)
667-
or
668-
exists(string row, string kind | sinkModel(row) |
669-
kind = row.splitAt(";", 7) and
670-
not kind =
671-
[
672-
"open-url", "jndi-injection", "ldap", "sql", "jdbc-url", "logging", "mvel", "xpath",
673-
"groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent",
674-
"url-open-stream", "url-redirect", "create-file", "write-file", "set-hostname-verifier",
675-
"header-splitting", "information-leak", "xslt", "jexl", "bean-validation"
676-
] and
677-
not kind.matches("regex-use%") and
678-
not kind.matches("qltest%") and
679-
msg = "Invalid kind \"" + kind + "\" in sink model."
680-
)
681-
or
682-
exists(string row, string kind | sourceModel(row) |
683-
kind = row.splitAt(";", 7) and
684-
not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and
685-
not kind.matches("qltest%") and
686-
msg = "Invalid kind \"" + kind + "\" in source model."
687-
)
688-
}
689-
}
690-
691578
pragma[nomagic]
692579
private predicate elementSpec(
693580
string namespace, string type, boolean subtypes, string name, string signature, string ext

java/ql/test/library-tests/dataflow/external-models/sinks.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import java
2+
import semmle.code.java.dataflow.CsvValidation
23
import semmle.code.java.dataflow.DataFlow
34
import semmle.code.java.dataflow.ExternalFlow
4-
import CsvValidation
55

66
class SinkModelTest extends SinkModelCsv {
77
override predicate row(string row) {

java/ql/test/library-tests/dataflow/external-models/srcs.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import java
2+
import semmle.code.java.dataflow.CsvValidation
23
import semmle.code.java.dataflow.DataFlow
34
import semmle.code.java.dataflow.ExternalFlow
4-
import CsvValidation
55

66
class SourceModelTest extends SourceModelCsv {
77
override predicate row(string row) {

java/ql/test/library-tests/dataflow/external-models/steps.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import java
2+
import semmle.code.java.dataflow.CsvValidation
23
import semmle.code.java.dataflow.DataFlow
34
import semmle.code.java.dataflow.ExternalFlow
45
import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
5-
import CsvValidation
66

77
class SummaryModelTest extends SummaryModelCsv {
88
override predicate row(string row) {

0 commit comments

Comments
 (0)