Skip to content

Commit 2729d10

Browse files
authored
Merge pull request #4123 from aschackmull/java/records-dataflow
Java: Add data flow for record getters.
2 parents aa3b268 + 8269287 commit 2729d10

File tree

5 files changed

+102
-0
lines changed

5 files changed

+102
-0
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ predicate readStep(Node node1, Content f, Node node2) {
193193
fr.getField() = f.(FieldContent).getField() and
194194
fr = node2.asExpr()
195195
)
196+
or
197+
exists(Record r, Method getter, Field recf, MethodAccess get |
198+
getter.getDeclaringType() = r and
199+
recf.getDeclaringType() = r and
200+
getter.getNumberOfParameters() = 0 and
201+
getter.getName() = recf.getName() and
202+
not exists(getter.getBody()) and
203+
recf = f.(FieldContent).getField() and
204+
get.getMethod() = getter and
205+
node1.asExpr() = get.getQualifier() and
206+
node2.asExpr() = get
207+
)
196208
}
197209

198210
/**
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
public class A {
2+
record Pair(Object x, Object y) { }
3+
4+
static Object source() { return null; }
5+
6+
void sink(Object o) { }
7+
8+
void foo() {
9+
Pair p1 = new Pair(source(), null);
10+
Pair p2 = new Pair(new Object(), source());
11+
bar(p1, p2);
12+
}
13+
14+
void bar(Pair p1, Pair p2) {
15+
sink(p1.x);
16+
sink(p1.y);
17+
sink(p2.x);
18+
sink(p2.y);
19+
Object p1x = p1.x();
20+
Object p1y = p1.y();
21+
Object p2x = p2.x();
22+
Object p2y = p2.y();
23+
sink(p1x);
24+
sink(p1y);
25+
sink(p2x);
26+
sink(p2y);
27+
}
28+
29+
record RecWithGetter(Object f) {
30+
public Object f() {
31+
return this.f;
32+
}
33+
}
34+
35+
record RecWithWeirdGetter1(Object f) {
36+
public Object f() {
37+
return new Object();
38+
}
39+
}
40+
41+
record RecWithWeirdGetter2(Object f) {
42+
public Object f() {
43+
return source();
44+
}
45+
}
46+
47+
void testExplicitGetter1() {
48+
RecWithGetter r1 = new RecWithGetter(source());
49+
RecWithWeirdGetter1 r2 = new RecWithWeirdGetter1(source());
50+
RecWithWeirdGetter2 r3 = new RecWithWeirdGetter2(source());
51+
testExplicitGetter2(r1, r2, r3);
52+
}
53+
54+
void testExplicitGetter2(RecWithGetter r1, RecWithWeirdGetter1 r2, RecWithWeirdGetter2 r3) {
55+
sink(r1.f);
56+
sink(r2.f);
57+
sink(r3.f);
58+
Object r1f = r1.f();
59+
Object r2f = r2.f();
60+
Object r3f = r3.f();
61+
sink(r1f);
62+
sink(r2f);
63+
sink(r3f);
64+
}
65+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args --enable-preview -source 14 -target 14
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
| A.java:9:24:9:31 | source(...) | A.java:15:10:15:13 | p1.x |
2+
| A.java:9:24:9:31 | source(...) | A.java:23:10:23:12 | p1x |
3+
| A.java:10:38:10:45 | source(...) | A.java:18:10:18:13 | p2.y |
4+
| A.java:10:38:10:45 | source(...) | A.java:26:10:26:12 | p2y |
5+
| A.java:43:14:43:21 | source(...) | A.java:63:10:63:12 | r3f |
6+
| A.java:48:42:48:49 | source(...) | A.java:55:10:55:13 | r1.f |
7+
| A.java:48:42:48:49 | source(...) | A.java:61:10:61:12 | r1f |
8+
| A.java:49:54:49:61 | source(...) | A.java:56:10:56:13 | r2.f |
9+
| A.java:50:54:50:61 | source(...) | A.java:57:10:57:13 | r3.f |
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import java
2+
import semmle.code.java.dataflow.DataFlow
3+
import DataFlow
4+
5+
class Conf extends Configuration {
6+
Conf() { this = "qqconf" }
7+
8+
override predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("source") }
9+
10+
override predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
11+
}
12+
13+
from Conf conf, Node src, Node sink
14+
where conf.hasFlow(src, sink)
15+
select src, sink

0 commit comments

Comments
 (0)