Add a bounds check when getting indexed items in dexlayout.
Will be useful to help diagnose issues caused by a corrupted dex file.
Bug: 62515426
Test: mm test-art-host
Change-Id: I8d62f379e85464ce7b418c77843e98cc195f494a
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index 62ee445..a200d8d 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -690,10 +690,10 @@
}
MethodItem* Collections::GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii) {
- MethodId* method_item = GetMethodId(cdii.GetMemberIndex());
+ MethodId* method_id = GetMethodId(cdii.GetMemberIndex());
uint32_t access_flags = cdii.GetRawMemberAccessFlags();
const DexFile::CodeItem* disk_code_item = cdii.GetMethodCodeItem();
- CodeItem* code_item = code_items_.GetExistingObject(cdii.GetMethodCodeItemOffset());;
+ CodeItem* code_item = code_items_.GetExistingObject(cdii.GetMethodCodeItemOffset());
DebugInfoItem* debug_info = nullptr;
if (disk_code_item != nullptr) {
if (code_item == nullptr) {
@@ -707,7 +707,7 @@
disk_code_item, is_static, cdii.GetMemberIndex(), GetLocalsCb, debug_info);
dex_file.DecodeDebugPositionInfo(disk_code_item, GetPositionsCb, debug_info);
}
- return new MethodItem(access_flags, method_item, code_item);
+ return new MethodItem(access_flags, method_id, code_item);
}
ClassData* Collections::CreateClassData(
@@ -719,14 +719,14 @@
ClassDataItemIterator cdii(dex_file, encoded_data);
// Static fields.
FieldItemVector* static_fields = new FieldItemVector();
- for (uint32_t i = 0; cdii.HasNextStaticField(); i++, cdii.Next()) {
+ for (; cdii.HasNextStaticField(); cdii.Next()) {
FieldId* field_item = GetFieldId(cdii.GetMemberIndex());
uint32_t access_flags = cdii.GetRawMemberAccessFlags();
static_fields->push_back(std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
}
// Instance fields.
FieldItemVector* instance_fields = new FieldItemVector();
- for (uint32_t i = 0; cdii.HasNextInstanceField(); i++, cdii.Next()) {
+ for (; cdii.HasNextInstanceField(); cdii.Next()) {
FieldId* field_item = GetFieldId(cdii.GetMemberIndex());
uint32_t access_flags = cdii.GetRawMemberAccessFlags();
instance_fields->push_back(
@@ -734,15 +734,13 @@
}
// Direct methods.
MethodItemVector* direct_methods = new MethodItemVector();
- for (uint32_t i = 0; cdii.HasNextDirectMethod(); i++, cdii.Next()) {
- direct_methods->push_back(
- std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, cdii)));
+ for (; cdii.HasNextDirectMethod(); cdii.Next()) {
+ direct_methods->push_back(std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, cdii)));
}
// Virtual methods.
MethodItemVector* virtual_methods = new MethodItemVector();
- for (uint32_t i = 0; cdii.HasNextVirtualMethod(); i++, cdii.Next()) {
- virtual_methods->push_back(
- std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, cdii)));
+ for (; cdii.HasNextVirtualMethod(); cdii.Next()) {
+ virtual_methods->push_back(std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, cdii)));
}
class_data = new ClassData(static_fields, instance_fields, direct_methods, virtual_methods);
class_data->SetSize(cdii.EndDataPointer() - encoded_data);
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index 95e64bf..fe74572 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -215,14 +215,38 @@
const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset);
ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
- StringId* GetStringId(uint32_t index) { return StringIds()[index].get(); }
- TypeId* GetTypeId(uint32_t index) { return TypeIds()[index].get(); }
- ProtoId* GetProtoId(uint32_t index) { return ProtoIds()[index].get(); }
- FieldId* GetFieldId(uint32_t index) { return FieldIds()[index].get(); }
- MethodId* GetMethodId(uint32_t index) { return MethodIds()[index].get(); }
- ClassDef* GetClassDef(uint32_t index) { return ClassDefs()[index].get(); }
- CallSiteId* GetCallSiteId(uint32_t index) { return CallSiteIds()[index].get(); }
- MethodHandleItem* GetMethodHandle(uint32_t index) { return MethodHandleItems()[index].get(); }
+ StringId* GetStringId(uint32_t index) {
+ CHECK_LT(index, StringIdsSize());
+ return StringIds()[index].get();
+ }
+ TypeId* GetTypeId(uint32_t index) {
+ CHECK_LT(index, TypeIdsSize());
+ return TypeIds()[index].get();
+ }
+ ProtoId* GetProtoId(uint32_t index) {
+ CHECK_LT(index, ProtoIdsSize());
+ return ProtoIds()[index].get();
+ }
+ FieldId* GetFieldId(uint32_t index) {
+ CHECK_LT(index, FieldIdsSize());
+ return FieldIds()[index].get();
+ }
+ MethodId* GetMethodId(uint32_t index) {
+ CHECK_LT(index, MethodIdsSize());
+ return MethodIds()[index].get();
+ }
+ ClassDef* GetClassDef(uint32_t index) {
+ CHECK_LT(index, ClassDefsSize());
+ return ClassDefs()[index].get();
+ }
+ CallSiteId* GetCallSiteId(uint32_t index) {
+ CHECK_LT(index, CallSiteIdsSize());
+ return CallSiteIds()[index].get();
+ }
+ MethodHandleItem* GetMethodHandle(uint32_t index) {
+ CHECK_LT(index, MethodHandleItemsSize());
+ return MethodHandleItems()[index].get();
+ }
StringId* GetStringIdOrNullPtr(uint32_t index) {
return index == DexFile::kDexNoIndex ? nullptr : GetStringId(index);