mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
Note that binding variables may be casting nodes
This commit is contained in:
@@ -375,7 +375,18 @@ predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { compatibleTypes0(t
|
||||
|
||||
/** A node that performs a type cast. */
|
||||
class CastNode extends ExprNode {
|
||||
CastNode() { this.getExpr() instanceof CastingExpr }
|
||||
CastNode() {
|
||||
this.getExpr() instanceof CastingExpr
|
||||
or
|
||||
exists(SsaExplicitUpdate upd |
|
||||
upd.getDefiningExpr().(VariableAssign).getSource() =
|
||||
[
|
||||
any(SwitchStmt ss).getExpr(), any(SwitchExpr se).getExpr(),
|
||||
any(InstanceOfExpr ioe).getExpr()
|
||||
] and
|
||||
this.asExpr() = upd.getAFirstUse()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TDataFlowCallable =
|
||||
|
||||
42
java/ql/test/library-tests/flow-through-binding/Test.java
Normal file
42
java/ql/test/library-tests/flow-through-binding/Test.java
Normal file
@@ -0,0 +1,42 @@
|
||||
public class Test {
|
||||
|
||||
public static Object testFlowThroughSwitchStmt(String s, Integer i, boolean unknown) {
|
||||
Object o = unknown ? s : i;
|
||||
switch (o) {
|
||||
case Integer i2 -> { return i2; }
|
||||
default -> { return null; }
|
||||
}
|
||||
}
|
||||
|
||||
public static Object testFlowThroughSwitchExpr(String s, Integer i, boolean unknown) {
|
||||
Object o = unknown ? s : i;
|
||||
Integer toRet = switch (o) {
|
||||
case Integer i2 -> i2;
|
||||
default -> null;
|
||||
};
|
||||
return toRet;
|
||||
}
|
||||
|
||||
public static Object testFlowThroughBindingInstanceOf(String s, Integer i, boolean unknown) {
|
||||
Object o = unknown ? s : i;
|
||||
if (o instanceof Integer i2)
|
||||
return i2;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T source() { return null; }
|
||||
|
||||
public static void sink(Object o) { }
|
||||
|
||||
public static void test(boolean unknown, boolean unknown2) {
|
||||
|
||||
String source1 = source();
|
||||
Integer source2 = source();
|
||||
sink(testFlowThroughSwitchStmt(source1, source2, unknown));
|
||||
sink(testFlowThroughSwitchExpr(source1, source2, unknown));
|
||||
sink(testFlowThroughBindingInstanceOf(source1, source2, unknown));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
1
java/ql/test/library-tests/flow-through-binding/options
Normal file
1
java/ql/test/library-tests/flow-through-binding/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args --release 21
|
||||
@@ -0,0 +1,3 @@
|
||||
| Test.java:35:23:35:30 | source(...) | Test.java:36:10:36:61 | testFlowThroughSwitchStmt(...) |
|
||||
| Test.java:35:23:35:30 | source(...) | Test.java:37:10:37:61 | testFlowThroughSwitchExpr(...) |
|
||||
| Test.java:35:23:35:30 | source(...) | Test.java:38:10:38:68 | testFlowThroughBindingInstanceOf(...) |
|
||||
18
java/ql/test/library-tests/flow-through-binding/test.ql
Normal file
18
java/ql/test/library-tests/flow-through-binding/test.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() = any(MethodCall mc | mc.getCallee().getName() = "source")
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asExpr() = any(MethodCall mc | mc.getMethod().getName() = "sink").getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = DataFlow::Global<TestConfig>;
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink
|
||||
where Flow::flow(source, sink)
|
||||
select source, sink
|
||||
Reference in New Issue
Block a user