diff options
| -rw-r--r-- | vm/analysis/CodeVerify.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c index ef6872e62..a7d634eae 100644 --- a/vm/analysis/CodeVerify.c +++ b/vm/analysis/CodeVerify.c @@ -1002,6 +1002,24 @@ static RegType primSigCharToRegType(char sigChar) } /* + * See if the method matches the MethodType. + */ +static bool isCorrectInvokeKind(MethodType methodType, Method* resMethod) +{ + switch (methodType) { + case METHOD_DIRECT: + return dvmIsDirectMethod(resMethod); + case METHOD_STATIC: + return dvmIsStaticMethod(resMethod); + case METHOD_VIRTUAL: + case METHOD_INTERFACE: + return !dvmIsDirectMethod(resMethod); + default: + return false; + } +} + +/* * Verify the arguments to a method. We're executing in "method", making * a call to the method reference in vB. * @@ -1060,10 +1078,9 @@ static Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs, //char* curMethodDesc = // dexProtoCopyMethodDescriptor(&meth->prototype); - LOGI("Could not find method %s.%s, referenced from " - "method %s.%s\n", - dotMissingClass, methodName/*, methodDesc*/, - dotMethClass, meth->name/*, curMethodDesc*/); + LOGI("Could not find method %s.%s, referenced from method %s.%s\n", + dotMissingClass, methodName/*, methodDesc*/, + dotMethClass, meth->name/*, curMethodDesc*/); free(dotMissingClass); free(dotMethClass); @@ -1093,6 +1110,16 @@ static Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs, } /* + * See if the method type implied by the invoke instruction matches the + * access flags for the target method. + */ + if (!isCorrectInvokeKind(methodType, resMethod)) { + LOG_VFY("VFY: invoke type does not match method type of %s.%s\n", + resMethod->clazz->descriptor, resMethod->name); + goto fail; + } + + /* * If we're using invoke-super(method), make sure that the executing * method's class' superclass has a vtable entry for the target method. */ |
