Skip to content

Commit 32cb8f3

Browse files
committed
Dataflow: Add test for FlowState.
1 parent 219bf51 commit 32cb8f3

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import java.util.function.*;
2+
3+
public class A {
4+
Object source(String state) { return null; }
5+
6+
void sink(Object x, String state) { }
7+
8+
void stateBarrier(Object x, String state) { }
9+
10+
Object step(Object x, String s1, String s2) { return null; }
11+
12+
void check(Object x) { }
13+
14+
void test1() {
15+
Object x = source("A");
16+
check(x); // $ pFwd=A-A pRev=A-B
17+
x = step(x, "A", "B");
18+
check(x); // $ pFwd=A-B pRev=A-A pRev=B-B
19+
sink(x, "A");
20+
sink(x, "B"); // $ flow=A
21+
}
22+
23+
void test2(Supplier<Boolean> b) {
24+
Object x = b.get() ? source("A") : source("B");
25+
check(x); // $ pFwd=A-A pFwd=B-B pRev=B-B pRev=B-C pRev=C-C
26+
x = b.get() ? x : step(x, "B", "C");
27+
check(x); // $ pFwd=A-A pFwd=B-B pFwd=B-C pRev=B-B pRev=C-C
28+
stateBarrier(x, "A");
29+
check(x); // $ pFwd=B-B pFwd=B-C pRev=A-A pRev=B-B pRev=C-C
30+
sink(x, "A");
31+
sink(x, "B"); // $ flow=B
32+
sink(x, "C"); // $ flow=B
33+
}
34+
}

java/ql/test/library-tests/dataflow/state/test.expected

Whitespace-only changes.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import java
2+
import semmle.code.java.dataflow.DataFlow
3+
import TestUtilities.InlineExpectationsTest
4+
import DataFlow
5+
6+
class TestState extends FlowState {
7+
TestState() { src(_, this) or sink(_, this) or step(_, _, this, _) or step(_, _, _, this) }
8+
}
9+
10+
predicate src(Node n, string s) {
11+
exists(MethodAccess ma |
12+
n.asExpr() = ma and
13+
ma.getMethod().hasName("source") and
14+
ma.getAnArgument().(StringLiteral).getValue() = s
15+
)
16+
}
17+
18+
predicate sink(Node n, string s) {
19+
exists(MethodAccess ma |
20+
ma.getMethod().hasName("sink") and
21+
n.asExpr() = ma.getArgument(0) and
22+
ma.getArgument(1).(StringLiteral).getValue() = s
23+
)
24+
}
25+
26+
predicate bar(Node n, string s) {
27+
exists(MethodAccess ma |
28+
ma.getMethod().hasName("stateBarrier") and
29+
n.asExpr() = ma.getArgument(0) and
30+
ma.getArgument(1).(StringLiteral).getValue() = s
31+
)
32+
}
33+
34+
predicate step(Node n1, Node n2, string s1, string s2) {
35+
exists(MethodAccess ma |
36+
ma.getMethod().hasName("step") and
37+
n1.asExpr() = ma.getArgument(0) and
38+
ma.getArgument(1).(StringLiteral).getValue() = s1 and
39+
ma.getArgument(2).(StringLiteral).getValue() = s2 and
40+
ma = n2.asExpr()
41+
)
42+
}
43+
44+
predicate checkNode(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("check") }
45+
46+
class Conf extends Configuration {
47+
Conf() { this = "qltest:state" }
48+
49+
override predicate isSource(Node n) { none() }
50+
51+
override predicate isSource(Node n, FlowState s) { src(n, s) }
52+
53+
override predicate isSink(Node n) { none() }
54+
55+
override predicate isSink(Node n, FlowState s) { sink(n, s) }
56+
57+
override predicate isBarrier(Node n, FlowState s) { bar(n, s) }
58+
59+
override predicate isAdditionalFlowStep(Node n1, FlowState s1, Node n2, FlowState s2) {
60+
step(n1, n2, s1, s2)
61+
}
62+
63+
override int explorationLimit() { result = 0 }
64+
}
65+
66+
class HasFlowTest extends InlineExpectationsTest {
67+
HasFlowTest() { this = "HasFlowTest" }
68+
69+
override string getARelevantTag() { result = ["pFwd", "pRev", "flow"] }
70+
71+
override predicate hasActualResult(Location location, string element, string tag, string value) {
72+
tag = "flow" and
73+
exists(PathNode src, PathNode sink, Conf conf |
74+
conf.hasFlowPath(src, sink) and
75+
sink.getNode().getLocation() = location and
76+
element = sink.toString() and
77+
value = src.getState()
78+
)
79+
or
80+
tag = "pFwd" and
81+
exists(PartialPathNode src, PartialPathNode node, Conf conf |
82+
conf.hasPartialFlow(src, node, _) and
83+
checkNode(node.getNode()) and
84+
node.getNode().getLocation() = location and
85+
element = node.toString() and
86+
value = src.getState() + "-" + node.getState()
87+
)
88+
or
89+
tag = "pRev" and
90+
exists(PartialPathNode node, PartialPathNode sink, Conf conf |
91+
conf.hasPartialFlowRev(node, sink, _) and
92+
checkNode(node.getNode()) and
93+
node.getNode().getLocation() = location and
94+
element = node.toString() and
95+
value = node.getState() + "-" + sink.getState()
96+
)
97+
}
98+
}

0 commit comments

Comments
 (0)