Merge pull request #15632 from aschackmull/dataflow/flowfeature-bugfix

Dataflow: Fix flow-feature bug for parameterless static functions
This commit is contained in:
Anders Schack-Mulligen
2024-02-19 09:24:43 +01:00
committed by GitHub
4 changed files with 112 additions and 3 deletions

View File

@@ -0,0 +1,49 @@
public class A {
static Object source(String s) { return null; }
static void sink(Object o) { }
static Object id(Object x) { return x; }
static void test1(int dummy) {
Object src = source("1");
Object a = src;
sink(a); // $ EqCc="1" SrcCc="1" SinkCc="1"
}
static void test2() {
Object src = source("2");
Object a = src;
sink(a); // $ EqCc="2" SrcCc="2" SinkCc="2"
}
void test3() {
Object src = source("3");
Object a = id(src);
sink(a); // $ EqCc="3" SrcCc="3" SinkCc="3"
}
static void test4() {
Object src = source("4");
Object a = id(src);
sink(a); // $ EqCc="4" SrcCc="4" SinkCc="4"
}
static Object test5src() {
return source("5");
}
static void test5() {
Object x = test5src();
Object y = id(x);
sink(y); // $ SinkCc="5"
}
static void test6sink(Object x) {
sink(x); // $ SrcCc="6"
}
static void test6() {
Object x = source("6");
test6sink(x);
}
}

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,60 @@
import java
import semmle.code.java.dataflow.DataFlow
import TestUtilities.InlineExpectationsTest
module Base {
predicate isSource(DataFlow::Node n) { n.asExpr().(MethodCall).getMethod().hasName("source") }
predicate isSink(DataFlow::Node n) {
exists(MethodCall ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
}
}
module ConfigSourceCc implements DataFlow::ConfigSig {
import Base
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
}
module ConfigSinkCc implements DataFlow::ConfigSig {
import Base
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSinkCallContext }
}
module ConfigEqualCc implements DataFlow::ConfigSig {
import Base
DataFlow::FlowFeature getAFeature() {
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
}
}
module FlowSourceCc = DataFlow::Global<ConfigSourceCc>;
module FlowSinkCc = DataFlow::Global<ConfigSinkCc>;
module FlowEqualCc = DataFlow::Global<ConfigEqualCc>;
module HasFlowTest implements TestSig {
string getARelevantTag() { result = ["SrcCc", "SinkCc", "EqCc"] }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node src, DataFlow::Node sink |
tag = "SrcCc" and
FlowSourceCc::flow(src, sink)
or
tag = "SinkCc" and
FlowSinkCc::flow(src, sink)
or
tag = "EqCc" and
FlowEqualCc::flow(src, sink)
|
sink.getLocation() = location and
element = sink.toString() and
value = src.asExpr().(MethodCall).getAnArgument().toString()
)
}
}
import MakeTest<HasFlowTest>

View File

@@ -1551,9 +1551,7 @@ module MakeImplCommon<InputSig Lang> {
class CallContextSomeCall extends CallContextCall, TSomeCall {
override string toString() { result = "CcSomeCall" }
override predicate relevantFor(DataFlowCallable callable) {
exists(ParamNode p | getNodeEnclosingCallable(p) = callable)
}
override predicate relevantFor(DataFlowCallable callable) { any() }
override predicate matchesCall(DataFlowCall call) { any() }
}