Reordered checks for permission and invocation type of private methods.
The verifier now checks for accessibilty of a method so it can throw an
IllegalAccessError where appropriate. It will then check if a private
method was invoked using invoke-super or invoke-direct, and throw a
VerifyError. Before it would throw VerifyError in both error cases.
Change-Id: Iba418c4cf6b4543bf253408db0d1283dcd1121eb
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 2b90089..04829bf 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -3182,18 +3182,18 @@
<< PrettyMethod(res_method);
return NULL;
}
- // Check that invoke-virtual and invoke-super are not used on private methods.
- if (res_method->IsPrivate() && method_type == METHOD_VIRTUAL) {
- Fail(VERIFY_ERROR_GENERIC) << "invoke-super/virtual can't be used on private method "
- << PrettyMethod(res_method);
- return NULL;
- }
// Check if access is allowed.
if (!referrer->CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call " << PrettyMethod(res_method)
<< " from " << PrettyDescriptor(referrer) << ")";
return NULL;
}
+ // Check that invoke-virtual and invoke-super are not used on private methods of the same class.
+ if (res_method->IsPrivate() && method_type == METHOD_VIRTUAL) {
+ Fail(VERIFY_ERROR_GENERIC) << "invoke-super/virtual can't be used on private method "
+ << PrettyMethod(res_method);
+ return NULL;
+ }
// Check that interface methods match interface classes.
if (klass->IsInterface() && method_type != METHOD_INTERFACE) {
Fail(VERIFY_ERROR_CLASS_CHANGE) << "non-interface method " << PrettyMethod(res_method)