mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
Java: Adjust to use the qlpack data-flow api.
This commit is contained in:
@@ -1261,6 +1261,7 @@ predicate notHaveIntersection(RefType t1, RefType t2) {
|
||||
* Holds if there is a common (reflexive, transitive) subtype of the erased
|
||||
* types `t1` and `t2`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate erasedHaveIntersection(RefType t1, RefType t2) {
|
||||
exists(SrcRefType commonSub |
|
||||
commonSub.getASourceSupertype*() = t1 and commonSub.getASourceSupertype*() = t2
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
import java
|
||||
|
||||
module DataFlow {
|
||||
import semmle.code.java.dataflow.internal.DataFlow
|
||||
private import semmle.code.java.dataflow.internal.DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlow
|
||||
import DataFlowMake<JavaDataFlow>
|
||||
import semmle.code.java.dataflow.internal.DataFlowImpl1
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
import MakeImpl<JavaDataFlow>
|
||||
@@ -0,0 +1,3 @@
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
import MakeImplCommon<JavaDataFlow>
|
||||
@@ -1,6 +1,9 @@
|
||||
/**
|
||||
* Provides Java-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
import DataFlowDispatch
|
||||
@@ -9,3 +12,10 @@ module Private {
|
||||
module Public {
|
||||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module JavaDataFlow implements DataFlowParameter {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
Node exprNode(DataFlowExpr e) { result = Public::exprNode(e) }
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ private predicate instanceFieldAssign(Expr src, FieldAccess fa) {
|
||||
* Thus, `node2` references an object with a field `f` that contains the
|
||||
* value of `node1`.
|
||||
*/
|
||||
predicate storeStep(Node node1, Content f, Node node2) {
|
||||
predicate storeStep(Node node1, ContentSet f, Node node2) {
|
||||
exists(FieldAccess fa |
|
||||
instanceFieldAssign(node1.asExpr(), fa) and
|
||||
node2.(PostUpdateNode).getPreUpdateNode() = getFieldQualifier(fa) and
|
||||
@@ -124,7 +124,7 @@ predicate storeStep(Node node1, Content f, Node node2) {
|
||||
* Thus, `node1` references an object with a field `f` whose value ends up in
|
||||
* `node2`.
|
||||
*/
|
||||
predicate readStep(Node node1, Content f, Node node2) {
|
||||
predicate readStep(Node node1, ContentSet f, Node node2) {
|
||||
exists(FieldRead fr |
|
||||
node1 = getFieldQualifier(fr) and
|
||||
fr.getField() = f.(FieldContent).getField() and
|
||||
@@ -156,7 +156,7 @@ predicate readStep(Node node1, Content f, Node node2) {
|
||||
* any value stored inside `f` is cleared at the pre-update node associated with `x`
|
||||
* in `x.f = newValue`.
|
||||
*/
|
||||
predicate clearsContent(Node n, Content c) {
|
||||
predicate clearsContent(Node n, ContentSet c) {
|
||||
exists(FieldAccess fa |
|
||||
instanceFieldAssign(_, fa) and
|
||||
n = getFieldQualifier(fa) and
|
||||
@@ -207,47 +207,25 @@ DataFlowType getNodeType(Node n) {
|
||||
}
|
||||
|
||||
/** Gets a string representation of a type returned by `getErasedRepr`. */
|
||||
string ppReprType(Type t) {
|
||||
string ppReprType(DataFlowType t) {
|
||||
if t.(BoxedType).getPrimitiveType().getName() = "double"
|
||||
then result = "Number"
|
||||
else result = t.toString()
|
||||
}
|
||||
|
||||
private predicate canContainBool(Type t) {
|
||||
t instanceof BooleanType or
|
||||
any(BooleanType b).(RefType).getASourceSupertype+() = t
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
|
||||
* a node of type `t1` to a node of type `t2`.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate compatibleTypes(Type t1, Type t2) {
|
||||
exists(Type e1, Type e2 |
|
||||
e1 = getErasedRepr(t1) and
|
||||
e2 = getErasedRepr(t2)
|
||||
|
|
||||
// Because of `getErasedRepr`, `erasedHaveIntersection` is a sufficient
|
||||
// compatibility check, but `conContainBool` is kept as a dummy disjunct
|
||||
// to get the proper join-order.
|
||||
erasedHaveIntersection(e1, e2)
|
||||
or
|
||||
canContainBool(e1) and canContainBool(e2)
|
||||
)
|
||||
}
|
||||
bindingset[t1, t2]
|
||||
pragma[inline_late]
|
||||
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { erasedHaveIntersection(t1, t2) }
|
||||
|
||||
/** A node that performs a type cast. */
|
||||
class CastNode extends ExprNode {
|
||||
CastNode() { this.getExpr() instanceof CastingExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` should never be skipped over in the `PathGraph` and in path
|
||||
* explanations.
|
||||
*/
|
||||
predicate neverSkipInPathGraph(Node n) { none() }
|
||||
|
||||
private newtype TDataFlowCallable =
|
||||
TSrcCallable(Callable c) or
|
||||
TSummarizedCallable(SummarizedCallable c) or
|
||||
@@ -381,8 +359,6 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) {
|
||||
)
|
||||
}
|
||||
|
||||
int accessPathLimit() { result = 5 }
|
||||
|
||||
/**
|
||||
* Holds if access paths with `c` at their head always should be tracked at high
|
||||
* precision. This disables adaptive access path precision for such access paths.
|
||||
|
||||
Reference in New Issue
Block a user