Files
codeql/java/ql/lib/semmle/code/java/dispatch/WrappedInvocation.qll
Ian Lynagh 6566f7b69f Kotlin: Add types for the different kinds of casts that Kotlin has
We might want to unify some of these in future, but doing that
correctly is easier than splitting them up correctly, so I've given each
one its own QL class for now.

I am not familiar with many of the libraries/queries that use CastExpr.
I've briefly looked at them and updated them in a way that looks
superficially reasonable, but some of the uses will probably want to be
refined later.
2022-05-10 19:51:13 +01:00

60 lines
1.7 KiB
Plaintext

/**
* Provides classes and predicates for reasoning about calls that may invoke one
* of their arguments.
*/
import java
import VirtualDispatch
/**
* Holds if `m` might invoke `runmethod` through a functional interface on the
* `n`th parameter.
*/
private predicate runner(Method m, int n, Method runmethod) {
m.getParameterType(n).(RefType).getSourceDeclaration().(FunctionalInterface).getRunMethod() =
runmethod and
(
m.isNative()
or
exists(Parameter p, MethodAccess ma, int j |
p = m.getParameter(n) and
ma.getEnclosingCallable() = m and
runner(ma.getMethod().getSourceDeclaration(), j, _) and
ma.getArgument(j) = p.getAnAccess()
)
)
}
/**
* Gets an argument of `ma` on which `ma.getMethod()` might invoke `runmethod`
* through a functional interface. The argument is traced backwards through
* casts and variable assignments.
*/
private Expr getRunnerArgument(MethodAccess ma, Method runmethod) {
exists(Method runner, int param |
runner(runner, param, runmethod) and
viableImpl(ma) = runner and
result = ma.getArgument(param)
)
or
getRunnerArgument(ma, runmethod).(CastingExpr).getExpr() = result
or
pragma[only_bind_out](getRunnerArgument(ma, runmethod))
.(VarAccess)
.getVariable()
.getAnAssignedValue() = result
}
/**
* Gets a method that can be invoked through a functional interface as an
* argument to `ma`.
*/
Method getRunnerTarget(MethodAccess ma) {
exists(Expr action, Method runmethod | action = getRunnerArgument(ma, runmethod) |
action.(FunctionalExpr).asMethod().getSourceDeclaration() = result
or
action.(ClassInstanceExpr).getAnonymousClass().getAMethod().getSourceDeclaration() = result and
result.overridesOrInstantiates*(runmethod)
)
}