mirror of
https://github.com/github/codeql.git
synced 2025-12-21 11:16:30 +01:00
Java: Make synthesized method bodies disjoint from source code.
This commit is contained in:
@@ -10,7 +10,7 @@ private module DispatchImpl {
|
|||||||
DataFlowCallable viableCallable(DataFlowCall c) {
|
DataFlowCallable viableCallable(DataFlowCall c) {
|
||||||
result.asCallable() = VirtualDispatch::viableCallable(c.asCall())
|
result.asCallable() = VirtualDispatch::viableCallable(c.asCall())
|
||||||
or
|
or
|
||||||
result.asCallable().(SummarizedCallable) = c.asCall().getCallee().getSourceDeclaration()
|
result.asSummarizedCallable() = c.asCall().getCallee().getSourceDeclaration()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +118,7 @@ private module DispatchImpl {
|
|||||||
not failsUnification(t, t2)
|
not failsUnification(t, t2)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
result.asCallable() = def and def instanceof SummarizedCallable
|
result.asSummarizedCallable() = def
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,17 +13,12 @@ newtype TNode =
|
|||||||
not e.getType() instanceof VoidType and
|
not e.getType() instanceof VoidType and
|
||||||
not e.getParent*() instanceof Annotation
|
not e.getParent*() instanceof Annotation
|
||||||
} or
|
} or
|
||||||
TExplicitParameterNode(Parameter p) {
|
TExplicitParameterNode(Parameter p) { exists(p.getCallable().getBody()) } or
|
||||||
exists(p.getCallable().getBody()) or p.getCallable() instanceof SummarizedCallable
|
|
||||||
} or
|
|
||||||
TImplicitVarargsArray(Call c) {
|
TImplicitVarargsArray(Call c) {
|
||||||
c.getCallee().isVarargs() and
|
c.getCallee().isVarargs() and
|
||||||
not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray())
|
not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray())
|
||||||
} or
|
} or
|
||||||
TInstanceParameterNode(Callable c) {
|
TInstanceParameterNode(Callable c) { exists(c.getBody()) and not c.isStatic() } or
|
||||||
(exists(c.getBody()) or c instanceof SummarizedCallable) and
|
|
||||||
not c.isStatic()
|
|
||||||
} or
|
|
||||||
TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or
|
TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or
|
||||||
TMallocNode(ClassInstanceExpr cie) or
|
TMallocNode(ClassInstanceExpr cie) or
|
||||||
TExplicitExprPostUpdate(Expr e) {
|
TExplicitExprPostUpdate(Expr e) {
|
||||||
@@ -45,6 +40,9 @@ newtype TNode =
|
|||||||
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||||
} or
|
} or
|
||||||
|
TSummaryParameterNode(SummarizedCallable c, int pos) {
|
||||||
|
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
|
||||||
|
} or
|
||||||
TFieldValueNode(Field f)
|
TFieldValueNode(Field f)
|
||||||
|
|
||||||
private predicate explicitInstanceArgument(Call call, Expr instarg) {
|
private predicate explicitInstanceArgument(Call call, Expr instarg) {
|
||||||
@@ -96,6 +94,8 @@ module Public {
|
|||||||
or
|
or
|
||||||
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getType()
|
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getType()
|
||||||
or
|
or
|
||||||
|
result = this.(SummaryParameterNode).getTypeImpl()
|
||||||
|
or
|
||||||
result = this.(FieldValueNode).getField().getType()
|
result = this.(FieldValueNode).getField().getType()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ module Public {
|
|||||||
* Holds if this node is the parameter of `c` at the specified (zero-based)
|
* Holds if this node is the parameter of `c` at the specified (zero-based)
|
||||||
* position. The implicit `this` parameter is considered to have index `-1`.
|
* position. The implicit `this` parameter is considered to have index `-1`.
|
||||||
*/
|
*/
|
||||||
abstract predicate isParameterOf(Callable c, int pos);
|
abstract predicate isParameterOf(DataFlowCallable c, int pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,7 +173,9 @@ module Public {
|
|||||||
/** Gets the parameter corresponding to this node. */
|
/** Gets the parameter corresponding to this node. */
|
||||||
Parameter getParameter() { result = param }
|
Parameter getParameter() { result = param }
|
||||||
|
|
||||||
override predicate isParameterOf(Callable c, int pos) { c.getParameter(pos) = param }
|
override predicate isParameterOf(DataFlowCallable c, int pos) {
|
||||||
|
c.asCallable().getParameter(pos) = param
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the node corresponding to `p`. */
|
/** Gets the node corresponding to `p`. */
|
||||||
@@ -213,7 +215,9 @@ module Public {
|
|||||||
/** Gets the callable containing this `this` parameter. */
|
/** Gets the callable containing this `this` parameter. */
|
||||||
Callable getCallable() { result = callable }
|
Callable getCallable() { result = callable }
|
||||||
|
|
||||||
override predicate isParameterOf(Callable c, int pos) { callable = c and pos = -1 }
|
override predicate isParameterOf(DataFlowCallable c, int pos) {
|
||||||
|
callable = c.asCallable() and pos = -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -336,13 +340,14 @@ module Private {
|
|||||||
result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
|
result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
|
||||||
result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
|
result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
|
||||||
result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or
|
result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or
|
||||||
n = TSummaryInternalNode(result.asCallable(), _) or
|
n = TSummaryInternalNode(result.asSummarizedCallable(), _) or
|
||||||
|
n = TSummaryParameterNode(result.asSummarizedCallable(), _) or
|
||||||
result.asFieldScope() = n.(FieldValueNode).getField()
|
result.asFieldScope() = n.(FieldValueNode).getField()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
|
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
|
||||||
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
|
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
|
||||||
p.isParameterOf(c.asCallable(), pos)
|
p.isParameterOf(c, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
|
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
|
||||||
@@ -443,6 +448,27 @@ module Private {
|
|||||||
SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||||
result = TSummaryInternalNode(c, state)
|
result = TSummaryInternalNode(c, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SummaryParameterNode extends ParameterNode, TSummaryParameterNode {
|
||||||
|
private SummarizedCallable sc;
|
||||||
|
private int pos_;
|
||||||
|
|
||||||
|
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) }
|
||||||
|
|
||||||
|
override Location getLocation() { result = sc.getLocation() }
|
||||||
|
|
||||||
|
override string toString() { result = "[summary param] " + pos_ + " in " + sc }
|
||||||
|
|
||||||
|
override predicate isParameterOf(DataFlowCallable c, int pos) {
|
||||||
|
c.asSummarizedCallable() = sc and pos = pos_
|
||||||
|
}
|
||||||
|
|
||||||
|
Type getTypeImpl() {
|
||||||
|
result = sc.getParameter(pos_).getType()
|
||||||
|
or
|
||||||
|
pos_ = -1 and result = sc.getDeclaringType()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private import Private
|
private import Private
|
||||||
|
|||||||
@@ -230,26 +230,32 @@ class CastNode extends ExprNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private newtype TDataFlowCallable =
|
private newtype TDataFlowCallable =
|
||||||
TCallable(Callable c) or
|
TSrcCallable(Callable c) or
|
||||||
|
TSummarizedCallable(SummarizedCallable c) or
|
||||||
TFieldScope(Field f)
|
TFieldScope(Field f)
|
||||||
|
|
||||||
class DataFlowCallable extends TDataFlowCallable {
|
class DataFlowCallable extends TDataFlowCallable {
|
||||||
Callable asCallable() { this = TCallable(result) }
|
Callable asCallable() { this = TSrcCallable(result) }
|
||||||
|
|
||||||
|
SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
|
||||||
|
|
||||||
Field asFieldScope() { this = TFieldScope(result) }
|
Field asFieldScope() { this = TFieldScope(result) }
|
||||||
|
|
||||||
RefType getDeclaringType() {
|
RefType getDeclaringType() {
|
||||||
result = this.asCallable().getDeclaringType() or
|
result = this.asCallable().getDeclaringType() or
|
||||||
|
result = this.asSummarizedCallable().getDeclaringType() or
|
||||||
result = this.asFieldScope().getDeclaringType()
|
result = this.asFieldScope().getDeclaringType()
|
||||||
}
|
}
|
||||||
|
|
||||||
string toString() {
|
string toString() {
|
||||||
result = this.asCallable().toString() or
|
result = this.asCallable().toString() or
|
||||||
|
result = "Synthetic: " + this.asSummarizedCallable().toString() or
|
||||||
result = "Field scope: " + this.asFieldScope().toString()
|
result = "Field scope: " + this.asFieldScope().toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
Location getLocation() {
|
Location getLocation() {
|
||||||
result = this.asCallable().getLocation() or
|
result = this.asCallable().getLocation() or
|
||||||
|
result = this.asSummarizedCallable().getLocation() or
|
||||||
result = this.asFieldScope().getLocation()
|
result = this.asFieldScope().getLocation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,7 +323,7 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
|
|||||||
/** Gets the data flow node that this call targets. */
|
/** Gets the data flow node that this call targets. */
|
||||||
Node getReceiver() { result = receiver }
|
Node getReceiver() { result = receiver }
|
||||||
|
|
||||||
override DataFlowCallable getEnclosingCallable() { result.asCallable() = c }
|
override DataFlowCallable getEnclosingCallable() { result.asSummarizedCallable() = c }
|
||||||
|
|
||||||
override string toString() { result = "[summary] call to " + receiver + " in " + c }
|
override string toString() { result = "[summary] call to " + receiver + " in " + c }
|
||||||
|
|
||||||
@@ -376,9 +382,8 @@ predicate forceHighPrecision(Content c) {
|
|||||||
|
|
||||||
/** Holds if `n` should be hidden from path explanations. */
|
/** Holds if `n` should be hidden from path explanations. */
|
||||||
predicate nodeIsHidden(Node n) {
|
predicate nodeIsHidden(Node n) {
|
||||||
n instanceof SummaryNode
|
n instanceof SummaryNode or
|
||||||
or
|
n instanceof SummaryParameterNode
|
||||||
n.(ParameterNode).isParameterOf(any(SummarizedCallable c), _)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LambdaCallKind = Method; // the "apply" method in the functional interface
|
class LambdaCallKind = Method; // the "apply" method in the functional interface
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ private module FlowSummaries {
|
|||||||
|
|
||||||
class SummarizedCallableBase = Callable;
|
class SummarizedCallableBase = Callable;
|
||||||
|
|
||||||
DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c }
|
DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c }
|
||||||
|
|
||||||
/** Gets the parameter position of the instance parameter. */
|
/** Gets the parameter position of the instance parameter. */
|
||||||
int instanceParameterPosition() { result = -1 }
|
int instanceParameterPosition() { result = -1 }
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ private class RelevantNode extends Node {
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate viableParamCand(Call call, int i, ParameterNode p) {
|
private predicate viableParamCand(Call call, int i, ParameterNode p) {
|
||||||
exists(Callable callable |
|
exists(DataFlowCallable callable |
|
||||||
callable = dispatchCand(call) and
|
callable.asCallable() = dispatchCand(call) and
|
||||||
p.isParameterOf(callable, i) and
|
p.isParameterOf(callable, i) and
|
||||||
p instanceof RelevantNode
|
p instanceof RelevantNode
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ private Callable dispatchCand(Call c) {
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate viableParam(Call call, int i, ParameterNode p) {
|
private predicate viableParam(Call call, int i, ParameterNode p) {
|
||||||
exists(Callable callable |
|
exists(DataFlowCallable callable |
|
||||||
callable = dispatchCand(call) and
|
callable.asCallable() = dispatchCand(call) and
|
||||||
p.isParameterOf(callable, i)
|
p.isParameterOf(callable, i)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user