Java: Move SSA data flow test and extend it to cover phi-read input edges.

This commit is contained in:
Anders Schack-Mulligen
2025-02-18 13:50:14 +01:00
parent 5379506464
commit 291ea6f6eb
4 changed files with 55 additions and 7 deletions

View File

@@ -0,0 +1,24 @@
public class A {
Object source() { return null; }
void sink(Object o) { }
boolean isSafe(Object o) { return o == null; }
void foo() {
Object x = source();
if (!isSafe(x)) {
x = null;
}
sink(x);
x = source();
if (!isSafe(x)) {
if (isSafe(x)) {
sink(x);
} else {
throw new RuntimeException();
}
}
sink(x);
}
}

View File

@@ -0,0 +1,31 @@
import java
import semmle.code.java.controlflow.Guards
import semmle.code.java.dataflow.DataFlow
private predicate isSafe(Guard g, Expr checked, boolean branch) {
exists(MethodCall mc | g = mc |
mc.getMethod().hasName("isSafe") and
checked = mc.getAnArgument() and
branch = true
)
}
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(MethodCall).getMethod().hasName("source")
}
predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc | mc.getMethod().hasName("sink") and mc.getAnArgument() = sink.asExpr())
}
predicate isBarrier(DataFlow::Node node) {
node = DataFlow::BarrierGuard<isSafe/3>::getABarrierNode()
}
}
module Flow = DataFlow::Global<TestConfig>;
from DataFlow::Node source, DataFlow::Node sink
where Flow::flow(source, sink)
select source, sink

View File

@@ -24,13 +24,6 @@ public class GuardTest {
break;
}
String s2 = "string";
if (!isSafe(s2)) {
s2 = null;
}
sink(s2);
}
}