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