Fix issued with non-public interface methods.
Some APK's ship with dex files containing non-public interface
methods. These would cause crashes on newer versions of ART due to
stricter verification of dex files. Make ART emit a warning but allow
this behavior.
Bug: 27928832
Change-Id: Ia3689ee091aa154fb5954b1f6dd50c489128acce
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 811e763..681c5f9 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -2626,6 +2626,23 @@
// From here on out it is easier to mask out the bits we're supposed to ignore.
method_access_flags &= kMethodAccessFlags;
+ // Interfaces are special.
+ if ((class_access_flags & kAccInterface) != 0) {
+ // Non-static interface methods must be public.
+ if ((method_access_flags & (kAccPublic | kAccStatic)) == 0) {
+ *error_msg = StringPrintf("Interface virtual method %" PRIu32 "(%s) is not public",
+ method_index,
+ GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
+ if (header_->GetVersion() >= 37) {
+ return false;
+ } else {
+ // Allow in older versions, but warn.
+ LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
+ << *error_msg;
+ }
+ }
+ }
+
// If there aren't any instructions, make sure that's expected.
if (!has_code) {
// Only native or abstract methods may not have code.
@@ -2664,7 +2681,7 @@
}
// Interfaces are special.
if ((class_access_flags & kAccInterface) != 0) {
- // Interface methods must be public and abstract.
+ // Interface methods without code must be abstract.
if ((method_access_flags & (kAccPublic | kAccAbstract)) != (kAccPublic | kAccAbstract)) {
*error_msg = StringPrintf("Interface method %" PRIu32 "(%s) is not public and abstract",
method_index,