Skip to content

Commit 07959b5

Browse files
author
Sauyon Lee
committed
Add tests for org.springframework.util;StringUtils taint models
1 parent 3486ce2 commit 07959b5

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import org.springframework.util.StringUtils;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Enumeration;
6+
import java.util.Locale;
7+
import java.lang.String;
8+
9+
class StringUtilsTest {
10+
String taint() { return "tainted"; }
11+
12+
String[] taintArray() { return null; }
13+
14+
Locale taintLocale() { return null; }
15+
16+
Collection<String> taintedCollection() { return null; }
17+
18+
Enumeration<String> taintedEnumeration() { return null; }
19+
20+
void sink(Object o) {}
21+
22+
void test() throws Exception {
23+
sink(StringUtils.addStringToArray(null, taint())); // $hasTaintFlow
24+
25+
sink(StringUtils.addStringToArray(taintArray(), "")); // $hasTaintFlow
26+
27+
sink(StringUtils.applyRelativePath("/", taint())); // $hasTaintFlow
28+
sink(StringUtils.applyRelativePath(taint(), "../../test")); // $hasTaintFlow
29+
30+
sink(StringUtils.arrayToCommaDelimitedString(taintArray())); // $hasTaintFlow
31+
32+
sink(StringUtils.arrayToDelimitedString(taintArray(), ":")); // $hasTaintFlow
33+
sink(StringUtils.arrayToDelimitedString(null, taint())); // $hasTaintFlow
34+
35+
sink(StringUtils.capitalize(taint())); // $hasTaintFlow
36+
37+
sink(StringUtils.cleanPath(taint())); // $hasTaintFlow
38+
39+
sink(StringUtils.collectionToCommaDelimitedString(taintedCollection())); // $hasTaintFlow
40+
41+
sink(StringUtils.collectionToDelimitedString(taintedCollection(), ":")); // $hasTaintFlow
42+
sink(StringUtils.collectionToDelimitedString(null, taint())); // $hasTaintFlow
43+
44+
sink(StringUtils.collectionToDelimitedString(taintedCollection(), ":", "", "")); // $hasTaintFlow
45+
sink(StringUtils.collectionToDelimitedString(null, taint(), "", "")); // $hasTaintFlow
46+
sink(StringUtils.collectionToDelimitedString(null, ":", taint(), "")); // $hasTaintFlow
47+
sink(StringUtils.collectionToDelimitedString(null, ":", "", taint())); // $hasTaintFlow
48+
49+
sink(StringUtils.commaDelimitedListToSet(taint())); // $hasTaintFlow
50+
51+
sink(StringUtils.commaDelimitedListToStringArray(taint())); // $hasTaintFlow
52+
53+
sink(StringUtils.concatenateStringArrays(taintArray(), null)); // $hasTaintFlow
54+
sink(StringUtils.concatenateStringArrays(null, taintArray())); // $hasTaintFlow
55+
56+
sink(StringUtils.delete(taint(), "")); // $hasTaintFlow
57+
58+
sink(StringUtils.deleteAny(taint(), "")); // $hasTaintFlow
59+
60+
sink(StringUtils.delimitedListToStringArray(taint(), ":")); // $hasTaintFlow
61+
sink(StringUtils.delimitedListToStringArray(taint(), ":", ".")); // $hasTaintFlow
62+
63+
sink(StringUtils.getFilename(taint())); // $hasTaintFlow
64+
65+
sink(StringUtils.getFilenameExtension(taint())); // $hasTaintFlow
66+
67+
sink(StringUtils.mergeStringArrays(taintArray(), null)); // $hasTaintFlow
68+
sink(StringUtils.mergeStringArrays(null, taintArray())); // $hasTaintFlow
69+
70+
sink(StringUtils.parseLocale(taint()));
71+
72+
sink(StringUtils.parseLocaleString(taint()));
73+
74+
sink(StringUtils.parseTimeZoneString(taint()));
75+
76+
sink(StringUtils.quote(taint())); // $hasTaintFlow
77+
78+
sink(StringUtils.quoteIfString(taint())); // $hasTaintFlow
79+
80+
sink(StringUtils.removeDuplicateStrings(taintArray())); // $hasTaintFlow
81+
82+
sink(StringUtils.replace(taint(), "", "")); // $hasTaintFlow
83+
sink(StringUtils.replace("", "", taint())); // $hasTaintFlow
84+
85+
sink(StringUtils.sortStringArray(taintArray())); // $hasTaintFlow
86+
87+
sink(StringUtils.split(taint(), "")); // $hasTaintFlow
88+
89+
sink(StringUtils.splitArrayElementsIntoProperties(taintArray(), "")); // $hasTaintFlow
90+
sink(StringUtils.splitArrayElementsIntoProperties(taintArray(), "", "")); // $hasTaintFlow
91+
92+
sink(StringUtils.stripFilenameExtension(taint())); // $hasTaintFlow
93+
94+
sink(StringUtils.tokenizeToStringArray(taint(), "")); // $hasTaintFlow
95+
sink(StringUtils.tokenizeToStringArray(taint(), "", true, true)); // $hasTaintFlow
96+
97+
sink(StringUtils.toLanguageTag(taintLocale()));
98+
99+
sink(StringUtils.toStringArray(taintedCollection())); // $hasTaintFlow
100+
101+
sink(StringUtils.toStringArray(taintedEnumeration())); // $hasTaintFlow
102+
103+
sink(StringUtils.trimAllWhitespace(taint())); // $hasTaintFlow
104+
105+
sink(StringUtils.trimArrayElements(taintArray())); // $hasTaintFlow
106+
107+
sink(StringUtils.trimLeadingCharacter(taint(), 'a')); // $hasTaintFlow
108+
109+
sink(StringUtils.trimLeadingWhitespace(taint())); // $hasTaintFlow
110+
111+
sink(StringUtils.trimTrailingCharacter(taint(), 'a')); // $hasTaintFlow
112+
113+
sink(StringUtils.trimTrailingWhitespace(taint())); // $hasTaintFlow
114+
115+
sink(StringUtils.trimWhitespace(taint())); // $hasTaintFlow
116+
117+
sink(StringUtils.uncapitalize(taint())); // $hasTaintFlow
118+
119+
sink(StringUtils.unqualify(taint())); // $hasTaintFlow
120+
121+
sink(StringUtils.unqualify(taint(), '.')); // $hasTaintFlow
122+
123+
sink(StringUtils.uriDecode(taint(), java.nio.charset.StandardCharsets.UTF_8)); // $hasTaintFlow
124+
}
125+
}

java/ql/test/library-tests/frameworks/spring/flow.expected

Whitespace-only changes.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import java
2+
import semmle.code.java.frameworks.spring.Spring
3+
import semmle.code.java.dataflow.TaintTracking
4+
import TestUtilities.InlineExpectationsTest
5+
6+
class TaintFlowConf extends TaintTracking::Configuration {
7+
TaintFlowConf() { this = "qltest:frameworks:spring-taint-flow" }
8+
9+
override predicate isSource(DataFlow::Node n) {
10+
exists(string name | name.matches("taint%") |
11+
n.asExpr().(MethodAccess).getMethod().hasName(name)
12+
)
13+
}
14+
15+
override predicate isSink(DataFlow::Node n) {
16+
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
17+
}
18+
}
19+
20+
class ValueFlowConf extends DataFlow::Configuration {
21+
ValueFlowConf() { this = "qltest:frameworks:spring-value-flow" }
22+
23+
override predicate isSource(DataFlow::Node n) {
24+
n.asExpr().(MethodAccess).getMethod().hasName("taint")
25+
}
26+
27+
override predicate isSink(DataFlow::Node n) {
28+
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
29+
}
30+
}
31+
32+
class HasFlowTest extends InlineExpectationsTest {
33+
HasFlowTest() { this = "HasFlowTest" }
34+
35+
override string getARelevantTag() { result = ["hasTaintFlow", "hasValueFlow"] }
36+
37+
override predicate hasActualResult(Location ___location, string element, string tag, string value) {
38+
tag = "hasTaintFlow" and
39+
exists(DataFlow::Node src, DataFlow::Node sink, TaintFlowConf conf | conf.hasFlow(src, sink) |
40+
not any(ValueFlowConf vconf).hasFlow(src, sink) and
41+
sink.getLocation() = ___location and
42+
element = sink.toString() and
43+
value = ""
44+
)
45+
or
46+
tag = "hasValueFlow" and
47+
exists(DataFlow::Node src, DataFlow::Node sink, ValueFlowConf conf | conf.hasFlow(src, sink) |
48+
sink.getLocation() = ___location and
49+
element = sink.toString() and
50+
value = ""
51+
)
52+
}
53+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.2.3

0 commit comments

Comments
 (0)