Merge pull request #4123 from aschackmull/java/records-dataflow

Java: Add data flow for record getters.
This commit is contained in:
Arthur Baars
2020-09-01 13:02:24 +02:00
committed by GitHub
5 changed files with 102 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
public class A {
record Pair(Object x, Object y) { }
static Object source() { return null; }
void sink(Object o) { }
void foo() {
Pair p1 = new Pair(source(), null);
Pair p2 = new Pair(new Object(), source());
bar(p1, p2);
}
void bar(Pair p1, Pair p2) {
sink(p1.x);
sink(p1.y);
sink(p2.x);
sink(p2.y);
Object p1x = p1.x();
Object p1y = p1.y();
Object p2x = p2.x();
Object p2y = p2.y();
sink(p1x);
sink(p1y);
sink(p2x);
sink(p2y);
}
record RecWithGetter(Object f) {
public Object f() {
return this.f;
}
}
record RecWithWeirdGetter1(Object f) {
public Object f() {
return new Object();
}
}
record RecWithWeirdGetter2(Object f) {
public Object f() {
return source();
}
}
void testExplicitGetter1() {
RecWithGetter r1 = new RecWithGetter(source());
RecWithWeirdGetter1 r2 = new RecWithWeirdGetter1(source());
RecWithWeirdGetter2 r3 = new RecWithWeirdGetter2(source());
testExplicitGetter2(r1, r2, r3);
}
void testExplicitGetter2(RecWithGetter r1, RecWithWeirdGetter1 r2, RecWithWeirdGetter2 r3) {
sink(r1.f);
sink(r2.f);
sink(r3.f);
Object r1f = r1.f();
Object r2f = r2.f();
Object r3f = r3.f();
sink(r1f);
sink(r2f);
sink(r3f);
}
}

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args --enable-preview -source 14 -target 14

View File

@@ -0,0 +1,9 @@
| A.java:9:24:9:31 | source(...) | A.java:15:10:15:13 | p1.x |
| A.java:9:24:9:31 | source(...) | A.java:23:10:23:12 | p1x |
| A.java:10:38:10:45 | source(...) | A.java:18:10:18:13 | p2.y |
| A.java:10:38:10:45 | source(...) | A.java:26:10:26:12 | p2y |
| A.java:43:14:43:21 | source(...) | A.java:63:10:63:12 | r3f |
| A.java:48:42:48:49 | source(...) | A.java:55:10:55:13 | r1.f |
| A.java:48:42:48:49 | source(...) | A.java:61:10:61:12 | r1f |
| A.java:49:54:49:61 | source(...) | A.java:56:10:56:13 | r2.f |
| A.java:50:54:50:61 | source(...) | A.java:57:10:57:13 | r3.f |

View File

@@ -0,0 +1,15 @@
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow
class Conf extends Configuration {
Conf() { this = "qqconf" }
override predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("source") }
override predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
}
from Conf conf, Node src, Node sink
where conf.hasFlow(src, sink)
select src, sink