Java: Adjust to use the qlpack data-flow api.

This commit is contained in:
Anders Schack-Mulligen
2023-05-04 14:14:39 +02:00
parent 50e7892498
commit c34c667e6b
6 changed files with 27 additions and 32 deletions

View File

@@ -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

View File

@@ -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
}

View File

@@ -0,0 +1,3 @@
private import DataFlowImplSpecific
private import codeql.dataflow.DataFlowImpl
import MakeImpl<JavaDataFlow>

View File

@@ -0,0 +1,3 @@
private import DataFlowImplSpecific
private import codeql.dataflow.DataFlowImplCommon
import MakeImplCommon<JavaDataFlow>

View File

@@ -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) }
}

View File

@@ -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.