Skip to content

Commit b2a2412

Browse files
Java: Clean up the constructor flow steps
1 parent aa8bacb commit b2a2412

File tree

2 files changed

+33
-23
lines changed

2 files changed

+33
-23
lines changed

java/ql/src/semmle/code/java/dataflow/FlowSteps.qll

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,31 @@ abstract class TaintPreservingCallable extends Callable {
5151
predicate transfersTaint(int src, int sink) { none() }
5252
}
5353

54-
private class StringTaintPreservingCallable extends TaintPreservingCallable {
55-
StringTaintPreservingCallable() {
54+
private class StringTaintPreservingMethod extends TaintPreservingCallable {
55+
StringTaintPreservingMethod() {
5656
this.getDeclaringType() instanceof TypeString and
5757
this
5858
.hasName(["concat", "copyValueOf", "endsWith", "format", "formatted", "getBytes", "indent",
5959
"intern", "join", "repeat", "split", "strip", "stripIndent", "stripLeading",
6060
"stripTrailing", "substring", "toCharArray", "toLowerCase", "toString", "toUpperCase",
61-
"trim", "String"])
61+
"trim"])
6262
}
6363

6464
override predicate returnsTaintFrom(int arg) {
6565
arg = -1 and not this.isStatic()
6666
or
67-
this.hasName(["concat", "copyValueOf", "String"]) and arg = 0
67+
this.hasName(["concat", "copyValueOf"]) and arg = 0
6868
or
6969
this.hasName(["format", "formatted", "join"]) and arg = [0 .. getNumberOfParameters()]
7070
}
7171
}
7272

73+
private class StringTaintPreservingConstructor extends Constructor, TaintPreservingCallable {
74+
StringTaintPreservingConstructor() { this.getDeclaringType() instanceof TypeString }
75+
76+
override predicate returnsTaintFrom(int arg) { arg = 0 }
77+
}
78+
7379
private class NumberTaintPreservingCallable extends TaintPreservingCallable {
7480
int argument;
7581

@@ -90,25 +96,28 @@ private class NumberTaintPreservingCallable extends TaintPreservingCallable {
9096
override predicate returnsTaintFrom(int arg) { arg = argument }
9197
}
9298

99+
/** Holds for the types `StringBuilder`, `StringBuffer`, and `StringWriter`. */
100+
private predicate stringBuilderType(RefType t) {
101+
t.hasQualifiedName("java.lang", "StringBuilder") or
102+
t.hasQualifiedName("java.lang", "StringBuffer") or
103+
t.hasQualifiedName("java.io", "StringWriter")
104+
}
105+
93106
private class StringBuilderTaintPreservingCallable extends TaintPreservingCallable {
94107
StringBuilderTaintPreservingCallable() {
95-
exists(Class c | c = this.getDeclaringType().getASourceSupertype*() |
96-
(
97-
c.hasQualifiedName("java.lang", "StringBuilder") or
98-
c.hasQualifiedName("java.lang", "StringBuffer") or
99-
c.hasQualifiedName("java.io", "StringWriter")
100-
) and
101-
(
102-
this.hasName(["append", "insert", "replace", "toString"])
103-
or
104-
this.(Constructor).getParameterType(0) instanceof TypeString and
105-
c = this.getDeclaringType()
106-
)
108+
exists(Method m |
109+
this.(Method).overrides*(m) and
110+
stringBuilderType(m.getDeclaringType()) and
111+
m.hasName(["append", "insert", "replace", "toString", "write"])
107112
)
113+
or
114+
this.(Constructor).getParameterType(0) instanceof RefType and
115+
stringBuilderType(this.getDeclaringType())
108116
}
109117

110118
override predicate returnsTaintFrom(int arg) {
111-
arg = -1
119+
arg = -1 and
120+
not this instanceof Constructor
112121
or
113122
this instanceof Constructor and arg = 0
114123
or
@@ -122,6 +131,11 @@ private class StringBuilderTaintPreservingCallable extends TaintPreservingCallab
122131
override predicate transfersTaint(int src, int sink) {
123132
returnsTaintFrom(src) and
124133
sink = -1 and
125-
src != -1
134+
src != -1 and
135+
not this instanceof Constructor
136+
or
137+
this.hasName("write") and
138+
src = 0 and
139+
sink = -1
126140
}
127141
}

java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -544,11 +544,7 @@ private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
544544
method.overrides*(write) and
545545
write.hasName("write") and
546546
arg = 0 and
547-
(
548-
write.getDeclaringType().hasQualifiedName("java.io", "OutputStream")
549-
or
550-
write.getDeclaringType().hasQualifiedName("java.io", "StringWriter")
551-
)
547+
write.getDeclaringType().hasQualifiedName("java.io", "OutputStream")
552548
)
553549
or
554550
method.(TaintPreservingCallable).transfersTaint(arg, -1)

0 commit comments

Comments
 (0)