1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <androidfw/TypeWrappers.h> 18 19 namespace android { 20 21 TypeVariant::iterator& TypeVariant::iterator::operator++() { 22 mIndex++; 23 if (mIndex > dtohl(mTypeVariant->data->entryCount)) { 24 mIndex = dtohl(mTypeVariant->data->entryCount); 25 } 26 return *this; 27 } 28 29 const ResTable_entry* TypeVariant::iterator::operator*() const { 30 const ResTable_type* type = mTypeVariant->data; 31 const uint32_t entryCount = dtohl(type->entryCount); 32 if (mIndex >= entryCount) { 33 return NULL; 34 } 35 36 const uintptr_t containerEnd = reinterpret_cast<uintptr_t>(type) 37 + dtohl(type->header.size); 38 const uint32_t* const entryIndices = reinterpret_cast<const uint32_t*>( 39 reinterpret_cast<uintptr_t>(type) + dtohs(type->header.headerSize)); 40 if (reinterpret_cast<uintptr_t>(entryIndices) + (sizeof(uint32_t) * entryCount) > containerEnd) { 41 ALOGE("Type's entry indices extend beyond its boundaries"); 42 return NULL; 43 } 44 45 const uint32_t entryOffset = dtohl(entryIndices[mIndex]); 46 if (entryOffset == ResTable_type::NO_ENTRY) { 47 return NULL; 48 } 49 50 if ((entryOffset & 0x3) != 0) { 51 ALOGE("Index %u points to entry with unaligned offset 0x%08x", mIndex, entryOffset); 52 return NULL; 53 } 54 55 const ResTable_entry* entry = reinterpret_cast<const ResTable_entry*>( 56 reinterpret_cast<uintptr_t>(type) + dtohl(type->entriesStart) + entryOffset); 57 if (reinterpret_cast<uintptr_t>(entry) > containerEnd - sizeof(*entry)) { 58 ALOGE("Entry offset at index %u points outside the Type's boundaries", mIndex); 59 return NULL; 60 } else if (reinterpret_cast<uintptr_t>(entry) + dtohs(entry->size) > containerEnd) { 61 ALOGE("Entry at index %u extends beyond Type's boundaries", mIndex); 62 return NULL; 63 } else if (dtohs(entry->size) < sizeof(*entry)) { 64 ALOGE("Entry at index %u is too small (%u)", mIndex, dtohs(entry->size)); 65 return NULL; 66 } 67 return entry; 68 } 69 70 } // namespace android 71