Skip to content

Commit 0f70da2

Browse files
authored
Merge pull request github#3105 from aschackmull/java/postupdate-jump
Java: Fix missing jump step from PostUpdate to capture.
2 parents e6cdbb9 + d8edae9 commit 0f70da2

File tree

4 files changed

+86
-1
lines changed

4 files changed

+86
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ private predicate variableCaptureStep(Node node1, ExprNode node2) {
113113
*/
114114
predicate jumpStep(Node node1, Node node2) {
115115
staticFieldStep(node1, node2) or
116-
variableCaptureStep(node1, node2)
116+
variableCaptureStep(node1, node2) or
117+
variableCaptureStep(node1.(PostUpdateNode).getPreUpdateNode(), node2)
117118
}
118119

119120
/**
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
public class A {
2+
static class Box {
3+
String elem;
4+
Box(String e) { elem = e; }
5+
void setElem(String e) { elem = e; }
6+
String getElem() { return elem; }
7+
}
8+
9+
String get() {
10+
return null;
11+
}
12+
13+
void f1(int i) {
14+
A a = f2("A", i);
15+
String x = a.get();
16+
}
17+
18+
A f2(String p, int i) {
19+
String s;
20+
if (i == 0) {
21+
s = "B";
22+
} else {
23+
s = "C";
24+
}
25+
Box b1 = new Box("D");
26+
Box b2 = new Box(null);
27+
b2.setElem("E");
28+
A a = new A() {
29+
@Override
30+
String get() {
31+
switch (i) {
32+
case 0: return p;
33+
case 1: return s;
34+
case 2: return b1.getElem();
35+
case 3: return b2.getElem();
36+
}
37+
}
38+
};
39+
return a;
40+
}
41+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
| A.java:14:14:14:16 | "A" | A.java:14:14:14:16 | "A" |
2+
| A.java:14:14:14:16 | "A" | A.java:15:16:15:22 | get(...) |
3+
| A.java:14:14:14:16 | "A" | A.java:18:8:18:15 | p |
4+
| A.java:14:14:14:16 | "A" | A.java:32:26:32:26 | p |
5+
| A.java:21:11:21:13 | "B" | A.java:15:16:15:22 | get(...) |
6+
| A.java:21:11:21:13 | "B" | A.java:21:7:21:13 | ...=... |
7+
| A.java:21:11:21:13 | "B" | A.java:21:11:21:13 | "B" |
8+
| A.java:21:11:21:13 | "B" | A.java:33:26:33:26 | s |
9+
| A.java:23:11:23:13 | "C" | A.java:15:16:15:22 | get(...) |
10+
| A.java:23:11:23:13 | "C" | A.java:23:7:23:13 | ...=... |
11+
| A.java:23:11:23:13 | "C" | A.java:23:11:23:13 | "C" |
12+
| A.java:23:11:23:13 | "C" | A.java:33:26:33:26 | s |
13+
| A.java:25:22:25:24 | "D" | A.java:4:9:4:16 | e |
14+
| A.java:25:22:25:24 | "D" | A.java:4:21:4:28 | ...=... |
15+
| A.java:25:22:25:24 | "D" | A.java:4:28:4:28 | e |
16+
| A.java:25:22:25:24 | "D" | A.java:6:31:6:34 | elem |
17+
| A.java:25:22:25:24 | "D" | A.java:15:16:15:22 | get(...) |
18+
| A.java:25:22:25:24 | "D" | A.java:25:22:25:24 | "D" |
19+
| A.java:25:22:25:24 | "D" | A.java:34:26:34:37 | getElem(...) |
20+
| A.java:27:16:27:18 | "E" | A.java:5:18:5:25 | e |
21+
| A.java:27:16:27:18 | "E" | A.java:5:30:5:37 | ...=... |
22+
| A.java:27:16:27:18 | "E" | A.java:5:37:5:37 | e |
23+
| A.java:27:16:27:18 | "E" | A.java:6:31:6:34 | elem |
24+
| A.java:27:16:27:18 | "E" | A.java:15:16:15:22 | get(...) |
25+
| A.java:27:16:27:18 | "E" | A.java:27:16:27:18 | "E" |
26+
| A.java:27:16:27:18 | "E" | A.java:35:26:35:37 | getElem(...) |
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import java
2+
import semmle.code.java.dataflow.DataFlow
3+
import DataFlow
4+
5+
StringLiteral src() { result.getCompilationUnit().fromSource() }
6+
7+
class Conf extends Configuration {
8+
Conf() { this = "qq capture" }
9+
10+
override predicate isSource(Node n) { n.asExpr() = src() }
11+
12+
override predicate isSink(Node n) { any() }
13+
}
14+
15+
from Node src, Node sink, Conf conf
16+
where conf.hasFlow(src, sink)
17+
select src, sink

0 commit comments

Comments
 (0)