summaryrefslogtreecommitdiff
path: root/runtime/verifier/method_verifier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/verifier/method_verifier.cc')
-rw-r--r--runtime/verifier/method_verifier.cc18
1 files changed, 14 insertions, 4 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 83da6b7b4e..d5319fdb0c 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -790,9 +790,16 @@ bool MethodVerifier::Verify() {
} else if (method_access_flags_ & kAccFinal) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have final methods";
return false;
- } else if (!(method_access_flags_ & kAccPublic)) {
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have non-public members";
- return false;
+ } else {
+ uint32_t access_flag_options = kAccPublic;
+ if (dex_file_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
+ access_flag_options |= kAccPrivate;
+ }
+ if (!(method_access_flags_ & access_flag_options)) {
+ Fail(VERIFY_ERROR_BAD_CLASS_HARD)
+ << "interfaces may not have protected or package-private members";
+ return false;
+ }
}
}
}
@@ -3794,9 +3801,12 @@ ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(
// Note: this check must be after the initializer check, as those are required to fail a class,
// while this check implies an IncompatibleClassChangeError.
if (klass->IsInterface()) {
- // methods called on interfaces should be invoke-interface, invoke-super, or invoke-static.
+ // methods called on interfaces should be invoke-interface, invoke-super, invoke-direct (if
+ // dex file version is 37 or greater), or invoke-static.
if (method_type != METHOD_INTERFACE &&
method_type != METHOD_STATIC &&
+ ((dex_file_->GetVersion() < DexFile::kDefaultMethodsVersion) ||
+ method_type != METHOD_DIRECT) &&
method_type != METHOD_SUPER) {
Fail(VERIFY_ERROR_CLASS_CHANGE)
<< "non-interface method " << PrettyMethod(dex_method_idx, *dex_file_)