OSDN Git Service

Don't call into ResolveType with possible exception
authorMathieu Chartier <mathieuc@google.com>
Tue, 6 Dec 2016 21:21:38 +0000 (13:21 -0800)
committerMathieu Chartier <mathieuc@google.com>
Wed, 14 Dec 2016 20:01:55 +0000 (12:01 -0800)
Bug: 33307169

Test: test-art-host

Change-Id: Ic4d499d772828ba1da7a1b9acfc2026f0fcec2b2

runtime/class_linker-inl.h

index 0a65cd1..213986a 100644 (file)
@@ -25,6 +25,7 @@
 #include "mirror/class_loader.h"
 #include "mirror/dex_cache-inl.h"
 #include "mirror/iftable.h"
+#include "mirror/throwable.h"
 #include "mirror/object_array.h"
 #include "handle_scope-inl.h"
 #include "scoped_thread_state_change-inl.h"
@@ -89,17 +90,28 @@ inline mirror::String* ClassLinker::ResolveString(dex::StringIndex string_idx,
 
 inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) {
   Thread::PoisonObjectPointersIfDebug();
+  if (kIsDebugBuild) {
+    Thread::Current()->AssertNoPendingException();
+  }
   ObjPtr<mirror::Class> resolved_type =
       referrer->GetDexCacheResolvedType(type_idx, image_pointer_size_);
   if (UNLIKELY(resolved_type == nullptr)) {
-    ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
     StackHandleScope<2> hs(Thread::Current());
-    Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
-    Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
-    const DexFile& dex_file = *dex_cache->GetDexFile();
-    resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
-    // Note: We cannot check here to see whether we added the type to the cache. The type
-    //       might be an erroneous class, which results in it being hidden from us.
+    // There could be an out of bounds exception from GetDexCacheResolvedType, don't call
+    // ResolveType for this case.
+    if (LIKELY(!hs.Self()->IsExceptionPending())) {
+      ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
+      Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
+      Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+      const DexFile& dex_file = *dex_cache->GetDexFile();
+      resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
+      // Note: We cannot check here to see whether we added the type to the cache. The type
+      //       might be an erroneous class, which results in it being hidden from us.
+    } else {
+      // Make sure its an array out of bounds exception.
+      DCHECK(hs.Self()->GetException()->GetClass()->DescriptorEquals(
+          "Ljava/lang/ArrayIndexOutOfBoundsException;"));
+    }
   }
   return resolved_type.Ptr();
 }