ART: Fix dex file verifier type-list handling

It is rare, but valid, to have an empty type list.

Bug: 17327877
Change-Id: Ib3a8ff3e5ccd8fe7c04b1e97485bf3e6de72aa4d
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 2794af6..a71a5e1 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -224,6 +224,16 @@
       return this->list_[idx];
     }
 
+    // Size in bytes of the part of the list that is common.
+    static constexpr size_t GetHeaderSize() {
+      return 4U;
+    }
+
+    // Size in bytes of the whole type list including all the stored elements.
+    static constexpr size_t GetListSize(size_t count) {
+      return GetHeaderSize() + sizeof(TypeItem) * count;
+    }
+
    private:
     uint32_t size_;  // size of the list, in entries
     TypeItem list_[1];  // elements of the list
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 7e6bdfa..0782045 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -1117,14 +1117,19 @@
       }
       case DexFile::kDexTypeTypeList: {
         const DexFile::TypeList* list = reinterpret_cast<const DexFile::TypeList*>(ptr_);
-        const DexFile::TypeItem* item = &list->GetTypeItem(0);
-        uint32_t count = list->Size();
 
-        if (!CheckListSize(list, 1, sizeof(DexFile::TypeList), "type_list") ||
-            !CheckListSize(item, count, sizeof(DexFile::TypeItem), "type_list size")) {
+        // Check that at least the header (size) is available.
+        if (!CheckListSize(list, 1, DexFile::TypeList::GetHeaderSize(), "type_list")) {
           return false;
         }
-        ptr_ = reinterpret_cast<const byte*>(item + count);
+
+        // Check that the whole list is available.
+        const size_t list_size = DexFile::TypeList::GetListSize(list->Size());
+        if (!CheckListSize(list, 1, list_size, "type_list size")) {
+          return false;
+        }
+
+        ptr_ += count;
         break;
       }
       case DexFile::kDexTypeAnnotationSetRefList: {