/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Byte-swapping and verification of dex files.
 */

#include "DexFile.h"
#include "DexClass.h"
#include "DexDataMap.h"
#include "DexProto.h"
#include "DexUtf.h"
#include "Leb128.h"

#include <zlib.h>

#include <stdlib.h>
#include <string.h>

#define SWAP2(_value)      (_value)
#define SWAP4(_value)      (_value)
#define SWAP8(_value)      (_value)

#define SWAP_FIELD2(_field) (_field) = SWAP2(_field)
#define SWAP_FIELD4(_field) (_field) = SWAP4(_field)
#define SWAP_FIELD8(_field) (_field) = SWAP8(_field)

/*
 * Some information we pass around to help verify values.
 */
struct CheckState {
    const DexHeader*  pHeader;
    const u1*         fileStart;
    const u1*         fileEnd;             // points to fileStart + fileLen
    u4                fileLen;
    DexDataMap*       pDataMap;            // set after map verification
    const DexFile*    pDexFile;            // set after intraitem verification
    const DexMapItem* pCallSiteIds;        // set after intraitem verification
    const DexMapItem* pMethodHandleItems;  // set after intraitem verification

    /*
     * bitmap of type_id indices that have been used to define classes;
     * initialized immediately before class_def cross-verification, and
     * freed immediately after it
     */
    u4*               pDefinedClassBits;

    const void*       previousItem; // set during section iteration
};

/*
 * Return the file offset of the given pointer.
 */
static inline u4 fileOffset(const CheckState* state, const void* ptr) {
    return ((const u1*) ptr) - state->fileStart;
}

/*
 * Return a pointer for the given file offset.
 */
static inline void* filePointer(const CheckState* state, u4 offset) {
    return (void*) (state->fileStart + offset);
}

/*
 * Verify that a pointer range, start inclusive to end exclusive, only
 * covers bytes in the file and doesn't point beyond the end of the
 * file. That is, the start must indicate a valid byte or may point at
 * the byte just past the end of the file (but no further), and the
 * end must be no less than the start and must also not point beyond
 * the byte just past the end of the file.
 */
static inline bool checkPtrRange(const CheckState* state,
        const void* start, const void* end, const char* label) {
    const void* fileStart = state->fileStart;
    const void* fileEnd = state->fileEnd;
    if ((start < fileStart) || (start > fileEnd)
            || (end < start) || (end > fileEnd)) {
        ALOGW("Bad offset range for %s: %#x..%#x", label,
                fileOffset(state, start), fileOffset(state, end));
        return false;
    }
    return true;
}

/*
 * Verify that a range of offsets, start inclusive to end exclusive,
 * are all valid. That is, the start must indicate a valid byte or may
 * point at the byte just past the end of the file (but no further),
 * and the end must be no less than the start and must also not point
 * beyond the byte just past the end of the file.
 *
 * Assumes "const CheckState* state".
 */
#define CHECK_OFFSET_RANGE(_start, _end) {                                  \
        const u1* _startPtr = (const u1*) filePointer(state, (_start));     \
        const u1* _endPtr = (const u1*) filePointer(state, (_end));         \
        if (!checkPtrRange(state, _startPtr, _endPtr,                       \
                        #_start ".." #_end)) {                              \
            return 0;                                                       \
        }                                                                   \
    }

/*
 * Verify that a pointer range, start inclusive to end exclusive, only
 * covers bytes in the file and doesn't point beyond the end of the
 * file. That is, the start must indicate a valid byte or may point at
 * the byte just past the end of the file (but no further), and the
 * end must be no less than the start and must also not point beyond
 * the byte just past the end of the file.
 *
 * Assumes "const CheckState* state".
 */
#define CHECK_PTR_RANGE(_start, _end) {                                     \
        if (!checkPtrRange(state, (_start), (_end), #_start ".." #_end)) {  \
            return 0;                                                       \
        }                                                                   \
    }

/*
 * Make sure a list of items fits entirely within the file.
 *
 * Assumes "const CheckState* state" and "typeof(_count) == typeof(_elemSize)"
 * If the type sizes or signs are mismatched, this will return 0.
 */
#define CHECK_LIST_SIZE(_ptr, _count, _elemSize) {                          \
        const u1* _start = (const u1*) (_ptr);                              \
        const u1* _end = _start + ((_count) * (_elemSize));                 \
        u4 _dummy;                                                          \
        if (__builtin_mul_overflow((_count), (_elemSize), &_dummy) ||       \
            !checkPtrRange(state, _start, _end, #_ptr)) {                   \
            return 0;                                                       \
        }                                                                   \
    }

/*
 * Swap a field that is known to hold an absolute DEX file offset. Note:
 * This does not check to see that the swapped offset points within the
 * mapped file, since that should be handled (with even more rigor) by
 * the cross-verification phase.
 *
 * Assumes "const CheckState* state".
 */
#define SWAP_OFFSET4(_field) {                                              \
        SWAP_FIELD4((_field));                                              \
    }

/*
 * Verify that an index falls in a valid range.
 */
#define CHECK_INDEX(_field, _limit) {                                       \
        if ((_field) >= (_limit)) {                                         \
            ALOGW("Bad index: %s(%u) > %s(%u)",                             \
                #_field, (u4)(_field), #_limit, (u4)(_limit));              \
            return 0;                                                       \
        }                                                                   \
    }

/*
 * Swap an index, and verify that it falls in a valid range.
 */
#define SWAP_INDEX2(_field, _limit) {                                       \
        SWAP_FIELD2((_field));                                              \
        CHECK_INDEX((_field), (_limit));                                    \
    }

/*
 * Verify that an index falls in a valid range or is kDexNoIndex.
 */
#define CHECK_INDEX_OR_NOINDEX(_field, _limit) {                            \
        if ((_field) != kDexNoIndex && (_field) >= (_limit)) {              \
            ALOGW("Bad index: %s(%u) > %s(%u)",                             \
                #_field, (u4)(_field), #_limit, (u4)(_limit));              \
            return 0;                                                       \
        }                                                                   \
    }

/*
 * Swap an index, and verify that it falls in a valid range.
 */
#define SWAP_INDEX4(_field, _limit) {                                       \
        SWAP_FIELD4((_field));                                              \
        CHECK_INDEX((_field), (_limit));                                    \
    }

/*
 * Swap an index, and verify that it falls in a valid range or is
 * kDexNoIndex.
 */
#define SWAP_INDEX4_OR_NOINDEX(_field, _limit) {                            \
        SWAP_FIELD4((_field));                                              \
        CHECK_INDEX_OR_NOINDEX((_field), (_limit));                         \
    }

/* Verify the definer of a given field_idx. */
static bool verifyFieldDefiner(const CheckState* state, u4 definingClass,
        u4 fieldIdx) {
    const DexFieldId* field = dexGetFieldId(state->pDexFile, fieldIdx);
    return field->classIdx == definingClass;
}

/* Verify the definer of a given method_idx. */
static bool verifyMethodDefiner(const CheckState* state, u4 definingClass,
        u4 methodIdx) {
    const DexMethodId* meth = dexGetMethodId(state->pDexFile, methodIdx);
    return meth->classIdx == definingClass;
}

/*
 * Calculate the required size (in elements) of the array pointed at by
 * pDefinedClassBits.
 */
static size_t calcDefinedClassBitsSize(const CheckState* state)
{
    // Divide typeIdsSize by 32 (0x20), rounding up.
    return (state->pHeader->typeIdsSize + 0x1f) >> 5;
}

/*
 * Set the given bit in pDefinedClassBits, returning its former value.
 */
static bool setDefinedClassBit(const CheckState* state, u4 typeIdx) {
    u4 arrayIdx = typeIdx >> 5;
    u4 bit = 1 << (typeIdx & 0x1f);
    u4* element = &state->pDefinedClassBits[arrayIdx];
    bool result = (*element & bit) != 0;

    *element |= bit;

    return result;
}

/*
 * Swap the header_item.
 */
static bool swapDexHeader(const CheckState* state, DexHeader* pHeader)
{
    CHECK_PTR_RANGE(pHeader, pHeader + 1);

    // magic is ok
    SWAP_FIELD4(pHeader->checksum);
    // signature is ok
    SWAP_FIELD4(pHeader->fileSize);
    SWAP_FIELD4(pHeader->headerSize);
    SWAP_FIELD4(pHeader->endianTag);
    SWAP_FIELD4(pHeader->linkSize);
    SWAP_OFFSET4(pHeader->linkOff);
    SWAP_OFFSET4(pHeader->mapOff);
    SWAP_FIELD4(pHeader->stringIdsSize);
    SWAP_OFFSET4(pHeader->stringIdsOff);
    SWAP_FIELD4(pHeader->typeIdsSize);
    SWAP_OFFSET4(pHeader->typeIdsOff);
    SWAP_FIELD4(pHeader->fieldIdsSize);
    SWAP_OFFSET4(pHeader->fieldIdsOff);
    SWAP_FIELD4(pHeader->methodIdsSize);
    SWAP_OFFSET4(pHeader->methodIdsOff);
    SWAP_FIELD4(pHeader->protoIdsSize);
    SWAP_OFFSET4(pHeader->protoIdsOff);
    SWAP_FIELD4(pHeader->classDefsSize);
    SWAP_OFFSET4(pHeader->classDefsOff);
    SWAP_FIELD4(pHeader->dataSize);
    SWAP_OFFSET4(pHeader->dataOff);

    if (pHeader->endianTag != kDexEndianConstant) {
        ALOGE("Unexpected endian_tag: %#x", pHeader->endianTag);
        return false;
    }

    // Assign variables so the diagnostic is prettier. (Hooray for macros.)
    u4 linkOff = pHeader->linkOff;
    u4 linkEnd = linkOff + pHeader->linkSize;
    u4 dataOff = pHeader->dataOff;
    u4 dataEnd = dataOff + pHeader->dataSize;
    CHECK_OFFSET_RANGE(linkOff, linkEnd);
    CHECK_OFFSET_RANGE(dataOff, dataEnd);

    /*
     * Note: The offsets and ranges of the other header items end up getting
     * checked during the first iteration over the map.
     */

    return true;
}

/* Check the header section for sanity. */
static bool checkHeaderSection(const CheckState* state, u4 sectionOffset,
        u4 sectionCount, u4* endOffset) {
    if (sectionCount != 1) {
        ALOGE("Multiple header items");
        return false;
    }

    if (sectionOffset != 0) {
        ALOGE("Header at %#x; not at start of file", sectionOffset);
        return false;
    }

    const DexHeader* pHeader = (const DexHeader*) filePointer(state, 0);
    *endOffset = pHeader->headerSize;
    return true;
}

/*
 * Helper for swapMap(), which turns a map type constant into a small
 * one-bit-on integer, suitable for use in an int-sized bit set.
 */
static u4 mapTypeToBitMask(int mapType) {
    switch (mapType) {
        case kDexTypeHeaderItem:               return 1 << 0;
        case kDexTypeStringIdItem:             return 1 << 1;
        case kDexTypeTypeIdItem:               return 1 << 2;
        case kDexTypeProtoIdItem:              return 1 << 3;
        case kDexTypeFieldIdItem:              return 1 << 4;
        case kDexTypeMethodIdItem:             return 1 << 5;
        case kDexTypeClassDefItem:             return 1 << 6;
        case kDexTypeMapList:                  return 1 << 7;
        case kDexTypeTypeList:                 return 1 << 8;
        case kDexTypeAnnotationSetRefList:     return 1 << 9;
        case kDexTypeAnnotationSetItem:        return 1 << 10;
        case kDexTypeClassDataItem:            return 1 << 11;
        case kDexTypeCodeItem:                 return 1 << 12;
        case kDexTypeStringDataItem:           return 1 << 13;
        case kDexTypeDebugInfoItem:            return 1 << 14;
        case kDexTypeAnnotationItem:           return 1 << 15;
        case kDexTypeEncodedArrayItem:         return 1 << 16;
        case kDexTypeAnnotationsDirectoryItem: return 1 << 17;
        case kDexTypeCallSiteIdItem:           return 1 << 18;
        case kDexTypeMethodHandleItem:         return 1 << 19;
        default: {
            ALOGE("Unknown map item type %04x", mapType);
            return 0;
        }
    }
}

/*
 * Helper for swapMap(), which indicates if an item type should appear
 * in the data section.
 */
static bool isDataSectionType(int mapType) {
    switch (mapType) {
        case kDexTypeHeaderItem:
        case kDexTypeStringIdItem:
        case kDexTypeTypeIdItem:
        case kDexTypeProtoIdItem:
        case kDexTypeFieldIdItem:
        case kDexTypeMethodIdItem:
        case kDexTypeClassDefItem: {
            return false;
        }
    }

    return true;
}

/*
 * Swap the map_list and verify what we can about it. Also, if verification
 * passes, allocate the state's DexDataMap.
 */
static bool swapMap(CheckState* state, DexMapList* pMap)
{
    DexMapItem* item = pMap->list;
    u4 count;
    u4 dataItemCount = 0; // Total count of items in the data section.
    u4 dataItemsLeft = state->pHeader->dataSize; // See use below.
    u4 usedBits = 0;      // Bit set: one bit per section
    bool first = true;
    u4 lastOffset = 0;

    SWAP_FIELD4(pMap->size);
    count = pMap->size;
    const u4 sizeOfItem = (u4) sizeof(DexMapItem);
    CHECK_LIST_SIZE(item, count, sizeOfItem);

    while (count--) {
        SWAP_FIELD2(item->type);
        SWAP_FIELD2(item->unused);
        SWAP_FIELD4(item->size);
        SWAP_OFFSET4(item->offset);

        if (first) {
            first = false;
        } else if (lastOffset >= item->offset) {
            ALOGE("Out-of-order map item: %#x then %#x",
                    lastOffset, item->offset);
            return false;
        }

        if (item->offset >= state->pHeader->fileSize) {
            ALOGE("Map item after end of file: %x, size %#x",
                    item->offset, state->pHeader->fileSize);
            return false;
        }

        if (isDataSectionType(item->type)) {
            u4 icount = item->size;

            /*
             * This sanity check on the data section items ensures that
             * there are no more items than the number of bytes in
             * the data section.
             */
            if (icount > dataItemsLeft) {
                ALOGE("Unrealistically many items in the data section: "
                        "at least %d", dataItemCount + icount);
                return false;
            }

            dataItemsLeft -= icount;
            dataItemCount += icount;
        }

        u4 bit = mapTypeToBitMask(item->type);

        if (bit == 0) {
            return false;
        }

        if ((usedBits & bit) != 0) {
            ALOGE("Duplicate map section of type %#x", item->type);
            return false;
        }

        if (item->type == kDexTypeCallSiteIdItem) {
            state->pCallSiteIds = item;
        } else if (item->type == kDexTypeMethodHandleItem) {
            state->pMethodHandleItems = item;
        }

        usedBits |= bit;
        lastOffset = item->offset;
        item++;
    }

    if ((usedBits & mapTypeToBitMask(kDexTypeHeaderItem)) == 0) {
        ALOGE("Map is missing header entry");
        return false;
    }

    if ((usedBits & mapTypeToBitMask(kDexTypeMapList)) == 0) {
        ALOGE("Map is missing map_list entry");
        return false;
    }

    if (((usedBits & mapTypeToBitMask(kDexTypeStringIdItem)) == 0)
            && ((state->pHeader->stringIdsOff != 0)
                    || (state->pHeader->stringIdsSize != 0))) {
        ALOGE("Map is missing string_ids entry");
        return false;
    }

    if (((usedBits & mapTypeToBitMask(kDexTypeTypeIdItem)) == 0)
            && ((state->pHeader->typeIdsOff != 0)
                    || (state->pHeader->typeIdsSize != 0))) {
        ALOGE("Map is missing type_ids entry");
        return false;
    }

    if (((usedBits & mapTypeToBitMask(kDexTypeProtoIdItem)) == 0)
            && ((state->pHeader->protoIdsOff != 0)
                    || (state->pHeader->protoIdsSize != 0))) {
        ALOGE("Map is missing proto_ids entry");
        return false;
    }

    if (((usedBits & mapTypeToBitMask(kDexTypeFieldIdItem)) == 0)
            && ((state->pHeader->fieldIdsOff != 0)
                    || (state->pHeader->fieldIdsSize != 0))) {
        ALOGE("Map is missing field_ids entry");
        return false;
    }

    if (((usedBits & mapTypeToBitMask(kDexTypeMethodIdItem)) == 0)
            && ((state->pHeader->methodIdsOff != 0)
                    || (state->pHeader->methodIdsSize != 0))) {
        ALOGE("Map is missing method_ids entry");
        return false;
    }

    if (((usedBits & mapTypeToBitMask(kDexTypeClassDefItem)) == 0)
            && ((state->pHeader->classDefsOff != 0)
                    || (state->pHeader->classDefsSize != 0))) {
        ALOGE("Map is missing class_defs entry");
        return false;
    }

    state->pDataMap = dexDataMapAlloc(dataItemCount);
    if (state->pDataMap == NULL) {
        ALOGE("Unable to allocate data map (size %#x)", dataItemCount);
        return false;
    }

    return true;
}

/* Check the map section for sanity. */
static bool checkMapSection(const CheckState* state, u4 sectionOffset,
        u4 sectionCount, u4* endOffset) {
    if (sectionCount != 1) {
        ALOGE("Multiple map list items");
        return false;
    }

    if (sectionOffset != state->pHeader->mapOff) {
        ALOGE("Map not at header-defined offset: %#x, expected %#x",
                sectionOffset, state->pHeader->mapOff);
        return false;
    }

    const DexMapList* pMap = (const DexMapList*) filePointer(state, sectionOffset);

    *endOffset =
        sectionOffset + sizeof(u4) + (pMap->size * sizeof(DexMapItem));
    return true;
}

/* Perform byte-swapping and intra-item verification on string_id_item. */
static void* swapStringIdItem(const CheckState* state, void* ptr) {
    DexStringId* item = (DexStringId*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_OFFSET4(item->stringDataOff);

    return item + 1;
}

/* Perform cross-item verification of string_id_item. */
static void* crossVerifyStringIdItem(const CheckState* state, void* ptr) {
    const DexStringId* item = (const DexStringId*) ptr;

    if (!dexDataMapVerify(state->pDataMap,
                    item->stringDataOff, kDexTypeStringDataItem)) {
        return NULL;
    }

    const DexStringId* item0 = (const DexStringId*) state->previousItem;
    if (item0 != NULL) {
        // Check ordering.
        const char* s0 = dexGetStringData(state->pDexFile, item0);
        const char* s1 = dexGetStringData(state->pDexFile, item);
        if (dexUtf8Cmp(s0, s1) >= 0) {
            ALOGE("Out-of-order string_ids: '%s' then '%s'", s0, s1);
            return NULL;
        }
    }

    return (void*) (item + 1);
}

/* Perform byte-swapping and intra-item verification on type_id_item. */
static void* swapTypeIdItem(const CheckState* state, void* ptr) {
    DexTypeId* item = (DexTypeId*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_INDEX4(item->descriptorIdx, state->pHeader->stringIdsSize);

    return item + 1;
}

/* Perform cross-item verification of type_id_item. */
static void* crossVerifyTypeIdItem(const CheckState* state, void* ptr) {
    const DexTypeId* item = (const DexTypeId*) ptr;
    const char* descriptor =
        dexStringById(state->pDexFile, item->descriptorIdx);

    if (!dexIsValidTypeDescriptor(descriptor)) {
        ALOGE("Invalid type descriptor: '%s'", descriptor);
        return NULL;
    }

    const DexTypeId* item0 = (const DexTypeId*) state->previousItem;
    if (item0 != NULL) {
        // Check ordering. This relies on string_ids being in order.
        if (item0->descriptorIdx >= item->descriptorIdx) {
            ALOGE("Out-of-order type_ids: %#x then %#x",
                    item0->descriptorIdx, item->descriptorIdx);
            return NULL;
        }
    }

    return (void*) (item + 1);
}

/* Perform byte-swapping and intra-item verification on proto_id_item. */
static void* swapProtoIdItem(const CheckState* state, void* ptr) {
    DexProtoId* item = (DexProtoId*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_INDEX4(item->shortyIdx, state->pHeader->stringIdsSize);
    SWAP_INDEX4(item->returnTypeIdx, state->pHeader->typeIdsSize);
    SWAP_OFFSET4(item->parametersOff);

    return item + 1;
}

/* Helper for crossVerifyProtoIdItem(), which checks a shorty character
 * to see if it is compatible with a type descriptor. Returns true if
 * so, false if not. */
static bool shortyDescMatch(char shorty, const char* descriptor, bool
        isReturnType) {
    switch (shorty) {
        case 'V': {
            if (!isReturnType) {
                ALOGE("Invalid use of void");
                return false;
            }
            FALLTHROUGH_INTENDED;
        }
        case 'B':
        case 'C':
        case 'D':
        case 'F':
        case 'I':
        case 'J':
        case 'S':
        case 'Z': {
            if ((descriptor[0] != shorty) || (descriptor[1] != '\0')) {
                ALOGE("Shorty vs. primitive type mismatch: '%c', '%s'",
                        shorty, descriptor);
                return false;
            }
            break;
        }
        case 'L': {
            if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
                ALOGE("Shorty vs. type mismatch: '%c', '%s'",
                        shorty, descriptor);
                return false;
            }
            break;
        }
        default: {
            ALOGE("Bogus shorty: '%c'", shorty);
            return false;
        }
    }

    return true;
}

/* Perform cross-item verification of proto_id_item. */
static void* crossVerifyProtoIdItem(const CheckState* state, void* ptr) {
    const DexProtoId* item = (const DexProtoId*) ptr;
    const char* shorty =
        dexStringById(state->pDexFile, item->shortyIdx);

    if (!dexDataMapVerify0Ok(state->pDataMap,
                    item->parametersOff, kDexTypeTypeList)) {
        return NULL;
    }

    if (!shortyDescMatch(*shorty,
                    dexStringByTypeIdx(state->pDexFile, item->returnTypeIdx),
                    true)) {
        return NULL;
    }

    u4 protoIdx = item - state->pDexFile->pProtoIds;
    DexProto proto = { state->pDexFile, protoIdx };
    DexParameterIterator iterator;

    dexParameterIteratorInit(&iterator, &proto);
    shorty++; // Skip the return type.

    for (;;) {
        const char *desc = dexParameterIteratorNextDescriptor(&iterator);

        if (desc == NULL) {
            break;
        }

        if (*shorty == '\0') {
            ALOGE("Shorty is too short");
            return NULL;
        }

        if (!shortyDescMatch(*shorty, desc, false)) {
            return NULL;
        }

        shorty++;
    }

    if (*shorty != '\0') {
        ALOGE("Shorty is too long");
        return NULL;
    }

    const DexProtoId* item0 = (const DexProtoId*) state->previousItem;
    if (item0 != NULL) {
        // Check ordering. This relies on type_ids being in order.
        if (item0->returnTypeIdx > item->returnTypeIdx) {
            ALOGE("Out-of-order proto_id return types");
            return NULL;
        } else if (item0->returnTypeIdx == item->returnTypeIdx) {
            bool badOrder = false;
            DexProto proto0 = { state->pDexFile, protoIdx - 1 };
            DexParameterIterator iterator0;

            dexParameterIteratorInit(&iterator, &proto);
            dexParameterIteratorInit(&iterator0, &proto0);

            for (;;) {
                u4 idx0 = dexParameterIteratorNextIndex(&iterator0);
                u4 idx1 = dexParameterIteratorNextIndex(&iterator);

                if (idx1 == kDexNoIndex) {
                    badOrder = true;
                    break;
                }

                if (idx0 == kDexNoIndex) {
                    break;
                }

                if (idx0 < idx1) {
                    break;
                } else if (idx0 > idx1) {
                    badOrder = true;
                    break;
                }
            }

            if (badOrder) {
                ALOGE("Out-of-order proto_id arguments");
                return NULL;
            }
        }
    }

    return (void*) (item + 1);
}

/* Perform byte-swapping and intra-item verification on field_id_item. */
static void* swapFieldIdItem(const CheckState* state, void* ptr) {
    DexFieldId* item = (DexFieldId*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_INDEX2(item->classIdx, state->pHeader->typeIdsSize);
    SWAP_INDEX2(item->typeIdx, state->pHeader->typeIdsSize);
    SWAP_INDEX4(item->nameIdx, state->pHeader->stringIdsSize);

    return item + 1;
}

/* Perform cross-item verification of field_id_item. */
static void* crossVerifyFieldIdItem(const CheckState* state, void* ptr) {
    const DexFieldId* item = (const DexFieldId*) ptr;
    const char* s;

    s = dexStringByTypeIdx(state->pDexFile, item->classIdx);
    if (!dexIsClassDescriptor(s)) {
        ALOGE("Invalid descriptor for class_idx: '%s'", s);
        return NULL;
    }

    s = dexStringByTypeIdx(state->pDexFile, item->typeIdx);
    if (!dexIsFieldDescriptor(s)) {
        ALOGE("Invalid descriptor for type_idx: '%s'", s);
        return NULL;
    }

    s = dexStringById(state->pDexFile, item->nameIdx);
    if (!dexIsValidMemberName(s)) {
        ALOGE("Invalid name: '%s'", s);
        return NULL;
    }

    const DexFieldId* item0 = (const DexFieldId*) state->previousItem;
    if (item0 != NULL) {
        // Check ordering. This relies on the other sections being in order.
        bool done = false;
        bool bogus = false;

        if (item0->classIdx > item->classIdx) {
            bogus = true;
            done = true;
        } else if (item0->classIdx < item->classIdx) {
            done = true;
        }

        if (!done) {
            if (item0->nameIdx > item->nameIdx) {
                bogus = true;
                done = true;
            } else if (item0->nameIdx < item->nameIdx) {
                done = true;
            }
        }

        if (!done) {
            if (item0->typeIdx >= item->typeIdx) {
                bogus = true;
            }
        }

        if (bogus) {
            ALOGE("Out-of-order field_ids");
            return NULL;
        }
    }

    return (void*) (item + 1);
}

/* Perform byte-swapping and intra-item verification on method_id_item. */
static void* swapMethodIdItem(const CheckState* state, void* ptr) {
    DexMethodId* item = (DexMethodId*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_INDEX2(item->classIdx, state->pHeader->typeIdsSize);
    SWAP_INDEX2(item->protoIdx, state->pHeader->protoIdsSize);
    SWAP_INDEX4(item->nameIdx, state->pHeader->stringIdsSize);

    return item + 1;
}

/* Perform cross-item verification of method_id_item. */
static void* crossVerifyMethodIdItem(const CheckState* state, void* ptr) {
    const DexMethodId* item = (const DexMethodId*) ptr;
    const char* s;

    s = dexStringByTypeIdx(state->pDexFile, item->classIdx);
    if (!dexIsReferenceDescriptor(s)) {
        ALOGE("Invalid descriptor for class_idx: '%s'", s);
        return NULL;
    }

    s = dexStringById(state->pDexFile, item->nameIdx);
    if (!dexIsValidMemberName(s)) {
        ALOGE("Invalid name: '%s'", s);
        return NULL;
    }

    const DexMethodId* item0 = (const DexMethodId*) state->previousItem;
    if (item0 != NULL) {
        // Check ordering. This relies on the other sections being in order.
        bool done = false;
        bool bogus = false;

        if (item0->classIdx > item->classIdx) {
            bogus = true;
            done = true;
        } else if (item0->classIdx < item->classIdx) {
            done = true;
        }

        if (!done) {
            if (item0->nameIdx > item->nameIdx) {
                bogus = true;
                done = true;
            } else if (item0->nameIdx < item->nameIdx) {
                done = true;
            }
        }

        if (!done) {
            if (item0->protoIdx >= item->protoIdx) {
                bogus = true;
            }
        }

        if (bogus) {
            ALOGE("Out-of-order method_ids");
            return NULL;
        }
    }

    return (void*) (item + 1);
}

/* Perform byte-swapping and intra-item verification on class_def_item. */
static void* swapClassDefItem(const CheckState* state, void* ptr) {
    DexClassDef* item = (DexClassDef*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_INDEX4(item->classIdx, state->pHeader->typeIdsSize);
    SWAP_FIELD4(item->accessFlags);
    SWAP_INDEX4_OR_NOINDEX(item->superclassIdx, state->pHeader->typeIdsSize);
    SWAP_OFFSET4(item->interfacesOff);
    SWAP_INDEX4_OR_NOINDEX(item->sourceFileIdx, state->pHeader->stringIdsSize);
    SWAP_OFFSET4(item->annotationsOff);
    SWAP_OFFSET4(item->classDataOff);

    if ((item->accessFlags & ~ACC_CLASS_MASK) != 0) {
        // The VM specification says that unknown flags should be ignored.
        ALOGV("Bogus class access flags %x", item->accessFlags);
        item->accessFlags &= ACC_CLASS_MASK;
    }

    return item + 1;
}

/* defined below */
static u4 findFirstClassDataDefiner(const CheckState* state,
        DexClassData* classData);
static u4 findFirstAnnotationsDirectoryDefiner(const CheckState* state,
        const DexAnnotationsDirectoryItem* dir);

/* Helper for crossVerifyClassDefItem(), which checks a class_data_item to
 * make sure all its references are to a given class. */
static bool verifyClassDataIsForDef(const CheckState* state, u4 offset,
        u4 definerIdx) {
    if (offset == 0) {
        return true;
    }

    const u1* data = (const u1*) filePointer(state, offset);
    DexClassData* classData = dexReadAndVerifyClassData(&data, NULL);

    if (classData == NULL) {
        // Shouldn't happen, but bail here just in case.
        return false;
    }

    /*
     * The class_data_item verification ensures that
     * it consistently refers to the same definer, so all we need to
     * do is check the first one.
     */
    u4 dataDefiner = findFirstClassDataDefiner(state, classData);
    bool result = (dataDefiner == definerIdx) || (dataDefiner == kDexNoIndex);

    free(classData);
    return result;
}

/* Helper for crossVerifyClassDefItem(), which checks an
 * annotations_directory_item to make sure all its references are to a
 * given class. */
static bool verifyAnnotationsDirectoryIsForDef(const CheckState* state,
        u4 offset, u4 definerIdx) {
    if (offset == 0) {
        return true;
    }

    const DexAnnotationsDirectoryItem* dir =
        (const DexAnnotationsDirectoryItem*) filePointer(state, offset);
    u4 annoDefiner = findFirstAnnotationsDirectoryDefiner(state, dir);

    return (annoDefiner == definerIdx) || (annoDefiner == kDexNoIndex);
}

/* Perform cross-item verification of class_def_item. */
static void* crossVerifyClassDefItem(const CheckState* state, void* ptr) {
    const DexClassDef* item = (const DexClassDef*) ptr;
    u4 classIdx = item->classIdx;
    const char* descriptor = dexStringByTypeIdx(state->pDexFile, classIdx);

    if (!dexIsClassDescriptor(descriptor)) {
        ALOGE("Invalid class: '%s'", descriptor);
        return NULL;
    }

    if (setDefinedClassBit(state, classIdx)) {
        ALOGE("Duplicate class definition: '%s'", descriptor);
        return NULL;
    }

    bool okay =
        dexDataMapVerify0Ok(state->pDataMap,
                item->interfacesOff, kDexTypeTypeList)
        && dexDataMapVerify0Ok(state->pDataMap,
                item->annotationsOff, kDexTypeAnnotationsDirectoryItem)
        && dexDataMapVerify0Ok(state->pDataMap,
                item->classDataOff, kDexTypeClassDataItem)
        && dexDataMapVerify0Ok(state->pDataMap,
                item->staticValuesOff, kDexTypeEncodedArrayItem);

    if (!okay) {
        return NULL;
    }

    if (item->superclassIdx != kDexNoIndex) {
        descriptor = dexStringByTypeIdx(state->pDexFile, item->superclassIdx);
        if (!dexIsClassDescriptor(descriptor)) {
            ALOGE("Invalid superclass: '%s'", descriptor);
            return NULL;
        }
    }

    const DexTypeList* interfaces =
        dexGetInterfacesList(state->pDexFile, item);
    if (interfaces != NULL) {
        u4 size = interfaces->size;
        u4 i;

        /*
         * Ensure that all interfaces refer to classes (not arrays or
         * primitives).
         */
        for (i = 0; i < size; i++) {
            descriptor = dexStringByTypeIdx(state->pDexFile,
                    dexTypeListGetIdx(interfaces, i));
            if (!dexIsClassDescriptor(descriptor)) {
                ALOGE("Invalid interface: '%s'", descriptor);
                return NULL;
            }
        }

        /*
         * Ensure that there are no duplicates. This is an O(N^2) test,
         * but in practice the number of interfaces implemented by any
         * given class is low. I will buy a milkshake for the
         * first person to show me a realistic case for which this test
         * would be unacceptably slow.
         */
        for (i = 1; i < size; i++) {
            u4 idx1 = dexTypeListGetIdx(interfaces, i);
            u4 j;
            for (j = 0; j < i; j++) {
                u4 idx2 = dexTypeListGetIdx(interfaces, j);
                if (idx1 == idx2) {
                    ALOGE("Duplicate interface: '%s'",
                            dexStringByTypeIdx(state->pDexFile, idx1));
                    return NULL;
                }
            }
        }
    }

    if (!verifyClassDataIsForDef(state, item->classDataOff, item->classIdx)) {
        ALOGE("Invalid class_data_item");
        return NULL;
    }

    if (!verifyAnnotationsDirectoryIsForDef(state, item->annotationsOff,
                    item->classIdx)) {
        ALOGE("Invalid annotations_directory_item");
        return NULL;
    }

    return (void*) (item + 1);
}

/* Perform cross-item verification of call_site_id. */
static void* crossVerifyCallSiteId(const CheckState* state, void* ptr) {
    const DexCallSiteId* item = (const DexCallSiteId*) ptr;
    if (state->pCallSiteIds == nullptr) {
        ALOGE("Verifying call site but expecting none");
        return NULL;
    }
    if (item->callSiteOff < state->pHeader->dataOff ||
        item->callSiteOff >= state->pHeader->dataOff + state->pHeader->dataSize) {
        ALOGE("Bad call site offset: %u", item->callSiteOff);
        return NULL;
    }
    return (void*) (item + 1);
}

/* Perform cross-item verification of method_handle_item. */
static void* crossVerifyMethodHandleItem(const CheckState* state, void* ptr) {
    const DexMethodHandleItem* item = (const DexMethodHandleItem*) ptr;
    if (state->pMethodHandleItems == nullptr) {
        ALOGE("Verifying method handle but expecting none");
        return NULL;
    }
    if (item->methodHandleType > (u2) MethodHandleType::INVOKE_INTERFACE) {
        ALOGE("Unknown method handle type: %u", item->methodHandleType);
        return NULL;
    }
    switch ((MethodHandleType) item->methodHandleType) {
        case MethodHandleType::STATIC_PUT:
        case MethodHandleType::STATIC_GET:
        case MethodHandleType::INSTANCE_PUT:
        case MethodHandleType::INSTANCE_GET:
            if (item->fieldOrMethodIdx >= state->pHeader->fieldIdsSize) {
                ALOGE("Method handle has invalid field id: %u\n", item->fieldOrMethodIdx);
                return NULL;
            }
            break;
        case MethodHandleType::INVOKE_STATIC:
        case MethodHandleType::INVOKE_INSTANCE:
        case MethodHandleType::INVOKE_CONSTRUCTOR:
        case MethodHandleType::INVOKE_DIRECT:
        case MethodHandleType::INVOKE_INTERFACE:
            if (item->fieldOrMethodIdx >= state->pHeader->methodIdsSize) {
                ALOGE("Method handle has invalid method id: %u\n", item->fieldOrMethodIdx);
                return NULL;
            }
            break;
    }
    return (void*) (item + 1);
}

/* Helper for swapAnnotationsDirectoryItem(), which performs
 * byte-swapping and intra-item verification on an
 * annotation_directory_item's field elements. */
static u1* swapFieldAnnotations(const CheckState* state, u4 count, u1* addr) {
    DexFieldAnnotationsItem* item = (DexFieldAnnotationsItem*) addr;
    bool first = true;
    u4 lastIdx = 0;

    const u4 sizeOfItem = (u4) sizeof(DexFieldAnnotationsItem);
    CHECK_LIST_SIZE(item, count, sizeOfItem);

    while (count--) {
        SWAP_INDEX4(item->fieldIdx, state->pHeader->fieldIdsSize);
        SWAP_OFFSET4(item->annotationsOff);

        if (first) {
            first = false;
        } else if (lastIdx >= item->fieldIdx) {
            ALOGE("Out-of-order field_idx: %#x then %#x", lastIdx,
                 item->fieldIdx);
            return NULL;
        }

        lastIdx = item->fieldIdx;
        item++;
    }

    return (u1*) item;
}

/* Helper for swapAnnotationsDirectoryItem(), which performs
 * byte-swapping and intra-item verification on an
 * annotation_directory_item's method elements. */
static u1* swapMethodAnnotations(const CheckState* state, u4 count, u1* addr) {
    DexMethodAnnotationsItem* item = (DexMethodAnnotationsItem*) addr;
    bool first = true;
    u4 lastIdx = 0;

    const u4 sizeOfItem = (u4) sizeof(DexMethodAnnotationsItem);
    CHECK_LIST_SIZE(item, count, sizeOfItem);

    while (count--) {
        SWAP_INDEX4(item->methodIdx, state->pHeader->methodIdsSize);
        SWAP_OFFSET4(item->annotationsOff);

        if (first) {
            first = false;
        } else if (lastIdx >= item->methodIdx) {
            ALOGE("Out-of-order method_idx: %#x then %#x", lastIdx,
                 item->methodIdx);
            return NULL;
        }

        lastIdx = item->methodIdx;
        item++;
    }

    return (u1*) item;
}

/* Helper for swapAnnotationsDirectoryItem(), which performs
 * byte-swapping and intra-item verification on an
 * annotation_directory_item's parameter elements. */
static u1* swapParameterAnnotations(const CheckState* state, u4 count,
        u1* addr) {
    DexParameterAnnotationsItem* item = (DexParameterAnnotationsItem*) addr;
    bool first = true;
    u4 lastIdx = 0;

    const u4 sizeOfItem = (u4) sizeof(DexParameterAnnotationsItem);
    CHECK_LIST_SIZE(item, count, sizeOfItem);

    while (count--) {
        SWAP_INDEX4(item->methodIdx, state->pHeader->methodIdsSize);
        SWAP_OFFSET4(item->annotationsOff);

        if (first) {
            first = false;
        } else if (lastIdx >= item->methodIdx) {
            ALOGE("Out-of-order method_idx: %#x then %#x", lastIdx,
                 item->methodIdx);
            return NULL;
        }

        lastIdx = item->methodIdx;
        item++;
    }

    return (u1*) item;
}

/* Perform byte-swapping and intra-item verification on
 * annotations_directory_item. */
static void* swapAnnotationsDirectoryItem(const CheckState* state, void* ptr) {
    DexAnnotationsDirectoryItem* item = (DexAnnotationsDirectoryItem*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_OFFSET4(item->classAnnotationsOff);
    SWAP_FIELD4(item->fieldsSize);
    SWAP_FIELD4(item->methodsSize);
    SWAP_FIELD4(item->parametersSize);

    u1* addr = (u1*) (item + 1);

    if (item->fieldsSize != 0) {
        addr = swapFieldAnnotations(state, item->fieldsSize, addr);
        if (addr == NULL) {
            return NULL;
        }
    }

    if (item->methodsSize != 0) {
        addr = swapMethodAnnotations(state, item->methodsSize, addr);
        if (addr == NULL) {
            return NULL;
        }
    }

    if (item->parametersSize != 0) {
        addr = swapParameterAnnotations(state, item->parametersSize, addr);
        if (addr == NULL) {
            return NULL;
        }
    }

    return addr;
}

static void* swapCallSiteId(const CheckState* state, void* ptr) {
    DexCallSiteId* item = (DexCallSiteId*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_OFFSET4(item->callSiteOff);

    return (item + 1);
}

static void* swapMethodHandleItem(const CheckState* state, void* ptr) {
    DexMethodHandleItem* item = (DexMethodHandleItem*) ptr;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_FIELD2(item->methodHandleType);
    SWAP_FIELD2(item->fieldOrMethodIdx);

    return (item + 1);
}


/* Helper for crossVerifyAnnotationsDirectoryItem(), which checks the
 * field elements. */
static const u1* crossVerifyFieldAnnotations(const CheckState* state, u4 count,
        const u1* addr, u4 definingClass) {
    const DexFieldAnnotationsItem* item = (DexFieldAnnotationsItem*) addr;

    while (count--) {
        if (!verifyFieldDefiner(state, definingClass, item->fieldIdx)) {
            return NULL;
        }
        if (!dexDataMapVerify(state->pDataMap, item->annotationsOff,
                        kDexTypeAnnotationSetItem)) {
            return NULL;
        }
        item++;
    }

    return (const u1*) item;
}

/* Helper for crossVerifyAnnotationsDirectoryItem(), which checks the
 * method elements. */
static const u1* crossVerifyMethodAnnotations(const CheckState* state,
        u4 count, const u1* addr, u4 definingClass) {
    const DexMethodAnnotationsItem* item = (DexMethodAnnotationsItem*) addr;

    while (count--) {
        if (!verifyMethodDefiner(state, definingClass, item->methodIdx)) {
            return NULL;
        }
        if (!dexDataMapVerify(state->pDataMap, item->annotationsOff,
                        kDexTypeAnnotationSetItem)) {
            return NULL;
        }
        item++;
    }

    return (const u1*) item;
}

/* Helper for crossVerifyAnnotationsDirectoryItem(), which checks the
 * parameter elements. */
static const u1* crossVerifyParameterAnnotations(const CheckState* state,
        u4 count, const u1* addr, u4 definingClass) {
    const DexParameterAnnotationsItem* item =
        (DexParameterAnnotationsItem*) addr;

    while (count--) {
        if (!verifyMethodDefiner(state, definingClass, item->methodIdx)) {
            return NULL;
        }
        if (!dexDataMapVerify(state->pDataMap, item->annotationsOff,
                        kDexTypeAnnotationSetRefList)) {
            return NULL;
        }
        item++;
    }

    return (const u1*) item;
}

/* Helper for crossVerifyClassDefItem() and
 * crossVerifyAnnotationsDirectoryItem(), which finds the type_idx of
 * the definer of the first item in the data. */
static u4 findFirstAnnotationsDirectoryDefiner(const CheckState* state,
        const DexAnnotationsDirectoryItem* dir) {
    if (dir->fieldsSize != 0) {
        const DexFieldAnnotationsItem* fields =
            dexGetFieldAnnotations(state->pDexFile, dir);
        const DexFieldId* field =
            dexGetFieldId(state->pDexFile, fields[0].fieldIdx);
        return field->classIdx;
    }

    if (dir->methodsSize != 0) {
        const DexMethodAnnotationsItem* methods =
            dexGetMethodAnnotations(state->pDexFile, dir);
        const DexMethodId* method =
            dexGetMethodId(state->pDexFile, methods[0].methodIdx);
        return method->classIdx;
    }

    if (dir->parametersSize != 0) {
        const DexParameterAnnotationsItem* parameters =
            dexGetParameterAnnotations(state->pDexFile, dir);
        const DexMethodId* method =
            dexGetMethodId(state->pDexFile, parameters[0].methodIdx);
        return method->classIdx;
    }

    return kDexNoIndex;
}

/* Perform cross-item verification of annotations_directory_item. */
static void* crossVerifyAnnotationsDirectoryItem(const CheckState* state,
        void* ptr) {
    const DexAnnotationsDirectoryItem* item = (const DexAnnotationsDirectoryItem*) ptr;
    u4 definingClass = findFirstAnnotationsDirectoryDefiner(state, item);

    if (!dexDataMapVerify0Ok(state->pDataMap,
                    item->classAnnotationsOff, kDexTypeAnnotationSetItem)) {
        return NULL;
    }

    const u1* addr = (const u1*) (item + 1);

    if (item->fieldsSize != 0) {
        addr = crossVerifyFieldAnnotations(state, item->fieldsSize, addr,
                definingClass);
        if (addr == NULL) {
            return NULL;
        }
    }

    if (item->methodsSize != 0) {
        addr = crossVerifyMethodAnnotations(state, item->methodsSize, addr,
                definingClass);
        if (addr == NULL) {
            return NULL;
        }
    }

    if (item->parametersSize != 0) {
        addr = crossVerifyParameterAnnotations(state, item->parametersSize,
                addr, definingClass);
        if (addr == NULL) {
            return NULL;
        }
    }

    return (void*) addr;
}

/* Perform byte-swapping and intra-item verification on type_list. */
static void* swapTypeList(const CheckState* state, void* ptr)
{
    DexTypeList* pTypeList = (DexTypeList*) ptr;
    DexTypeItem* pType;
    u4 count;

    CHECK_PTR_RANGE(pTypeList, pTypeList + 1);
    SWAP_FIELD4(pTypeList->size);
    count = pTypeList->size;
    pType = pTypeList->list;

    const u4 sizeOfItem = (u4) sizeof(DexTypeItem);
    CHECK_LIST_SIZE(pType, count, sizeOfItem);

    while (count--) {
        SWAP_INDEX2(pType->typeIdx, state->pHeader->typeIdsSize);
        pType++;
    }

    return pType;
}

/* Perform byte-swapping and intra-item verification on
 * annotation_set_ref_list. */
static void* swapAnnotationSetRefList(const CheckState* state, void* ptr) {
    DexAnnotationSetRefList* list = (DexAnnotationSetRefList*) ptr;
    DexAnnotationSetRefItem* item;
    u4 count;

    CHECK_PTR_RANGE(list, list + 1);
    SWAP_FIELD4(list->size);
    count = list->size;
    item = list->list;

    const u4 sizeOfItem = (u4) sizeof(DexAnnotationSetRefItem);
    CHECK_LIST_SIZE(item, count, sizeOfItem);

    while (count--) {
        SWAP_OFFSET4(item->annotationsOff);
        item++;
    }

    return item;
}

/* Perform cross-item verification of annotation_set_ref_list. */
static void* crossVerifyAnnotationSetRefList(const CheckState* state,
        void* ptr) {
    const DexAnnotationSetRefList* list = (const DexAnnotationSetRefList*) ptr;
    const DexAnnotationSetRefItem* item = list->list;
    int count = list->size;

    while (count--) {
        if (!dexDataMapVerify0Ok(state->pDataMap,
                        item->annotationsOff, kDexTypeAnnotationSetItem)) {
            return NULL;
        }
        item++;
    }

    return (void*) item;
}

/* Perform byte-swapping and intra-item verification on
 * annotation_set_item. */
static void* swapAnnotationSetItem(const CheckState* state, void* ptr) {
    DexAnnotationSetItem* set = (DexAnnotationSetItem*) ptr;
    u4* item;
    u4 count;

    CHECK_PTR_RANGE(set, set + 1);
    SWAP_FIELD4(set->size);
    count = set->size;
    item = set->entries;

    const u4 sizeOfItem = (u4) sizeof(u4);
    CHECK_LIST_SIZE(item, count, sizeOfItem);

    while (count--) {
        SWAP_OFFSET4(*item);
        item++;
    }

    return item;
}

/* Helper for crossVerifyAnnotationSetItem(), which extracts the type_idx
 * out of an annotation_item. */
static u4 annotationItemTypeIdx(const DexAnnotationItem* item) {
    const u1* data = item->annotation;
    return readUnsignedLeb128(&data);
}

/* Perform cross-item verification of annotation_set_item. */
static void* crossVerifyAnnotationSetItem(const CheckState* state, void* ptr) {
    const DexAnnotationSetItem* set = (const DexAnnotationSetItem*) ptr;
    int count = set->size;
    u4 lastIdx = 0;
    bool first = true;
    int i;

    for (i = 0; i < count; i++) {
        if (!dexDataMapVerify0Ok(state->pDataMap,
                        dexGetAnnotationOff(set, i), kDexTypeAnnotationItem)) {
            return NULL;
        }

        const DexAnnotationItem* annotation =
            dexGetAnnotationItem(state->pDexFile, set, i);
        u4 idx = annotationItemTypeIdx(annotation);

        if (first) {
            first = false;
        } else if (lastIdx >= idx) {
            ALOGE("Out-of-order entry types: %#x then %#x",
                    lastIdx, idx);
            return NULL;
        }

        lastIdx = idx;
    }

    return (void*) (set->entries + count);
}

/* Helper for verifyClassDataItem(), which checks a list of fields. */
static bool verifyFields(const CheckState* state, u4 size,
        DexField* fields, bool expectStatic) {
    u4 i;

    for (i = 0; i < size; i++) {
        DexField* field = &fields[i];
        u4 accessFlags = field->accessFlags;
        bool isStatic = (accessFlags & ACC_STATIC) != 0;

        CHECK_INDEX(field->fieldIdx, state->pHeader->fieldIdsSize);

        if (isStatic != expectStatic) {
            ALOGE("Field in wrong list @ %d", i);
            return false;
        }

        if ((accessFlags & ~ACC_FIELD_MASK) != 0) {
            // The VM specification says that unknown flags should be ignored.
            ALOGV("Bogus field access flags %x @ %d", accessFlags, i);
            field->accessFlags &= ACC_FIELD_MASK;
        }
    }

    return true;
}

/* Helper for verifyClassDataItem(), which checks a list of methods. */
static bool verifyMethods(const CheckState* state, u4 size,
        DexMethod* methods, bool expectDirect) {
    u4 i;

    for (i = 0; i < size; i++) {
        DexMethod* method = &methods[i];

        CHECK_INDEX(method->methodIdx, state->pHeader->methodIdsSize);

        u4 accessFlags = method->accessFlags;
        bool isDirect =
            (accessFlags & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR)) != 0;
        bool expectCode = (accessFlags & (ACC_NATIVE | ACC_ABSTRACT)) == 0;
        bool isSynchronized = (accessFlags & ACC_SYNCHRONIZED) != 0;
        bool allowSynchronized = (accessFlags & ACC_NATIVE) != 0;

        if (isDirect != expectDirect) {
            ALOGE("Method in wrong list @ %d", i);
            return false;
        }

        if (isSynchronized && !allowSynchronized) {
            ALOGE("Bogus method access flags (synchronization) %x @ %d", accessFlags, i);
            return false;
        }

        if ((accessFlags & ~ACC_METHOD_MASK) != 0) {
            // The VM specification says that unknown flags should be ignored.
            ALOGV("Bogus method access flags %x @ %d", accessFlags, i);
            method->accessFlags &= ACC_METHOD_MASK;
        }

        if (expectCode) {
            if (method->codeOff == 0) {
                ALOGE("Unexpected zero code_off for access_flags %x",
                        accessFlags);
                return false;
            }
        } else if (method->codeOff != 0) {
            ALOGE("Unexpected non-zero code_off %#x for access_flags %x",
                    method->codeOff, accessFlags);
            return false;
        }
    }

    return true;
}

/* Helper for verifyClassDataItem(), which does most of the work. */
static bool verifyClassDataItem0(const CheckState* state,
        DexClassData* classData) {
    bool okay;

    okay = verifyFields(state, classData->header.staticFieldsSize,
            classData->staticFields, true);

    if (!okay) {
        ALOGE("Trouble with static fields");
        return false;
    }

    verifyFields(state, classData->header.instanceFieldsSize,
            classData->instanceFields, false);

    if (!okay) {
        ALOGE("Trouble with instance fields");
        return false;
    }

    okay = verifyMethods(state, classData->header.directMethodsSize,
            classData->directMethods, true);

    if (!okay) {
        ALOGE("Trouble with direct methods");
        return false;
    }

    okay = verifyMethods(state, classData->header.virtualMethodsSize,
            classData->virtualMethods, false);

    if (!okay) {
        ALOGE("Trouble with virtual methods");
        return false;
    }

    return true;
}

/* Perform intra-item verification on class_data_item. */
static void* intraVerifyClassDataItem(const CheckState* state, void* ptr) {
    const u1* data = (const u1*) ptr;
    DexClassData* classData = dexReadAndVerifyClassData(&data, state->fileEnd);

    if (classData == NULL) {
        ALOGE("Unable to parse class_data_item");
        return NULL;
    }

    bool okay = verifyClassDataItem0(state, classData);

    free(classData);

    if (!okay) {
        return NULL;
    }

    return (void*) data;
}

/* Helper for crossVerifyClassDefItem() and
 * crossVerifyClassDataItem(), which finds the type_idx of the definer
 * of the first item in the data. */
static u4 findFirstClassDataDefiner(const CheckState* state,
        DexClassData* classData) {
    if (classData->header.staticFieldsSize != 0) {
        u4 fieldIdx = classData->staticFields[0].fieldIdx;
        const DexFieldId* field = dexGetFieldId(state->pDexFile, fieldIdx);
        return field->classIdx;
    }

    if (classData->header.instanceFieldsSize != 0) {
        u4 fieldIdx = classData->instanceFields[0].fieldIdx;
        const DexFieldId* field = dexGetFieldId(state->pDexFile, fieldIdx);
        return field->classIdx;
    }

    if (classData->header.directMethodsSize != 0) {
        u4 methodIdx = classData->directMethods[0].methodIdx;
        const DexMethodId* meth = dexGetMethodId(state->pDexFile, methodIdx);
        return meth->classIdx;
    }

    if (classData->header.virtualMethodsSize != 0) {
        u4 methodIdx = classData->virtualMethods[0].methodIdx;
        const DexMethodId* meth = dexGetMethodId(state->pDexFile, methodIdx);
        return meth->classIdx;
    }

    return kDexNoIndex;
}

/* Perform cross-item verification of class_data_item. */
static void* crossVerifyClassDataItem(const CheckState* state, void* ptr) {
    const u1* data = (const u1*) ptr;
    DexClassData* classData = dexReadAndVerifyClassData(&data, state->fileEnd);
    u4 definingClass = findFirstClassDataDefiner(state, classData);
    bool okay = true;
    u4 i;

    for (i = classData->header.staticFieldsSize; okay && (i > 0); /*i*/) {
        i--;
        const DexField* field = &classData->staticFields[i];
        okay = verifyFieldDefiner(state, definingClass, field->fieldIdx);
    }

    for (i = classData->header.instanceFieldsSize; okay && (i > 0); /*i*/) {
        i--;
        const DexField* field = &classData->instanceFields[i];
        okay = verifyFieldDefiner(state, definingClass, field->fieldIdx);
    }

    for (i = classData->header.directMethodsSize; okay && (i > 0); /*i*/) {
        i--;
        const DexMethod* meth = &classData->directMethods[i];
        okay = dexDataMapVerify0Ok(state->pDataMap, meth->codeOff,
                kDexTypeCodeItem)
            && verifyMethodDefiner(state, definingClass, meth->methodIdx);
    }

    for (i = classData->header.virtualMethodsSize; okay && (i > 0); /*i*/) {
        i--;
        const DexMethod* meth = &classData->virtualMethods[i];
        okay = dexDataMapVerify0Ok(state->pDataMap, meth->codeOff,
                kDexTypeCodeItem)
            && verifyMethodDefiner(state, definingClass, meth->methodIdx);
    }

    free(classData);

    if (!okay) {
        return NULL;
    }

    return (void*) data;
}

/* Helper for swapCodeItem(), which fills an array with all the valid
 * handlerOff values for catch handlers and also verifies the handler
 * contents. */
static u4 setHandlerOffsAndVerify(const CheckState* state,
        DexCode* code, u4 firstOffset, u4 handlersSize, u4* handlerOffs) {
    const u1* fileEnd = state->fileEnd;
    const u1* handlersBase = dexGetCatchHandlerData(code);
    u4 offset = firstOffset;
    bool okay = true;
    u4 i;

    for (i = 0; i < handlersSize; i++) {
        const u1* ptr = handlersBase + offset;
        int size = readAndVerifySignedLeb128(&ptr, fileEnd, &okay);
        bool catchAll;

        if (!okay) {
            ALOGE("Bogus size");
            return 0;
        }

        if ((size < -65536) || (size > 65536)) {
            ALOGE("Invalid size: %d", size);
            return 0;
        }

        if (size <= 0) {
            catchAll = true;
            size = -size;
        } else {
            catchAll = false;
        }

        handlerOffs[i] = offset;

        while (size-- > 0) {
            u4 typeIdx =
                readAndVerifyUnsignedLeb128(&ptr, fileEnd, &okay);

            if (!okay) {
                ALOGE("Bogus type_idx");
                return 0;
            }

            CHECK_INDEX(typeIdx, state->pHeader->typeIdsSize);

            u4 addr = readAndVerifyUnsignedLeb128(&ptr, fileEnd, &okay);

            if (!okay) {
                ALOGE("Bogus addr");
                return 0;
            }

            if (addr >= code->insnsSize) {
                ALOGE("Invalid addr: %#x", addr);
                return 0;
            }
        }

        if (catchAll) {
            u4 addr = readAndVerifyUnsignedLeb128(&ptr, fileEnd, &okay);

            if (!okay) {
                ALOGE("Bogus catch_all_addr");
                return 0;
            }

            if (addr >= code->insnsSize) {
                ALOGE("Invalid catch_all_addr: %#x", addr);
                return 0;
            }
        }

        offset = ptr - handlersBase;
    }

    return offset;
}

/* Helper for swapCodeItem(), which does all the try-catch related
 * swapping and verification. */
static void* swapTriesAndCatches(const CheckState* state, DexCode* code) {
    const u1* encodedHandlers = dexGetCatchHandlerData(code);
    const u1* encodedPtr = encodedHandlers;
    bool okay = true;
    u4 handlersSize =
        readAndVerifyUnsignedLeb128(&encodedPtr, state->fileEnd, &okay);

    if (!okay) {
        ALOGE("Bogus handlers_size");
        return NULL;
    }

    if ((handlersSize == 0) || (handlersSize >= 65536)) {
        ALOGE("Invalid handlers_size: %d", handlersSize);
        return NULL;
    }

    u4 handlerOffs[handlersSize]; // list of valid handlerOff values
    u4 endOffset = setHandlerOffsAndVerify(state, code,
            encodedPtr - encodedHandlers,
            handlersSize, handlerOffs);

    if (endOffset == 0) {
        return NULL;
    }

    DexTry* tries = (DexTry*) dexGetTries(code);
    u4 count = code->triesSize;
    u4 lastEnd = 0;

    const u4 sizeOfItem = (u4) sizeof(DexTry);
    CHECK_LIST_SIZE(tries, count, sizeOfItem);

    while (count--) {
        u4 i;

        SWAP_FIELD4(tries->startAddr);
        SWAP_FIELD2(tries->insnCount);
        SWAP_FIELD2(tries->handlerOff);

        if (tries->startAddr < lastEnd) {
            ALOGE("Out-of-order try");
            return NULL;
        }

        if (tries->startAddr >= code->insnsSize) {
            ALOGE("Invalid start_addr: %#x", tries->startAddr);
            return NULL;
        }

        for (i = 0; i < handlersSize; i++) {
            if (tries->handlerOff == handlerOffs[i]) {
                break;
            }
        }

        if (i == handlersSize) {
            ALOGE("Bogus handler offset: %#x", tries->handlerOff);
            return NULL;
        }

        lastEnd = tries->startAddr + tries->insnCount;

        if (lastEnd > code->insnsSize) {
            ALOGE("Invalid insn_count: %#x (end addr %#x)",
                    tries->insnCount, lastEnd);
            return NULL;
        }

        tries++;
    }

    return (u1*) encodedHandlers + endOffset;
}

/* Perform byte-swapping and intra-item verification on code_item. */
static void* swapCodeItem(const CheckState* state, void* ptr) {
    DexCode* item = (DexCode*) ptr;
    u2* insns;
    u4 count;

    CHECK_PTR_RANGE(item, item + 1);
    SWAP_FIELD2(item->registersSize);
    SWAP_FIELD2(item->insSize);
    SWAP_FIELD2(item->outsSize);
    SWAP_FIELD2(item->triesSize);
    SWAP_OFFSET4(item->debugInfoOff);
    SWAP_FIELD4(item->insnsSize);

    if (item->insSize > item->registersSize) {
        ALOGE("insSize (%u) > registersSize (%u)", item->insSize,
                item->registersSize);
        return NULL;
    }

    if ((item->outsSize > 5) && (item->outsSize > item->registersSize)) {
        /*
         * It's okay for outsSize to be up to five, even if registersSize
         * is smaller, since the short forms of method invocation allow
         * repetition of a register multiple times within a single parameter
         * list. Longer parameter lists, though, need to be represented
         * in-order in the register file.
         */
        ALOGE("outsSize (%u) > registersSize (%u)", item->outsSize,
                item->registersSize);
        return NULL;
    }

    count = item->insnsSize;
    insns = item->insns;

    const u4 sizeOfItem = (u4) sizeof(u2);
    CHECK_LIST_SIZE(insns, count, sizeOfItem);

    while (count--) {
        *insns = SWAP2(*insns);
        insns++;
    }

    if (item->triesSize == 0) {
        ptr = insns;
    } else {
        if ((((uintptr_t) insns) & 3) != 0) {
            // Four-byte alignment for the tries. Verify the spacer is a 0.
            if (*insns != 0) {
                ALOGE("Non-zero padding: %#x", (u4) *insns);
                return NULL;
            }
        }

        ptr = swapTriesAndCatches(state, item);
    }

    return ptr;
}

/* Perform intra-item verification on string_data_item. */
static void* intraVerifyStringDataItem(const CheckState* state, void* ptr) {
    const u1* fileEnd = state->fileEnd;
    const u1* data = (const u1*) ptr;
    bool okay = true;
    u4 utf16Size = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
    u4 i;

    if (!okay) {
        ALOGE("Bogus utf16_size");
        return NULL;
    }

    for (i = 0; i < utf16Size; i++) {
        if (data >= fileEnd) {
            ALOGE("String data would go beyond end-of-file");
            return NULL;
        }

        u1 byte1 = *(data++);

        // Switch on the high four bits.
        switch (byte1 >> 4) {
            case 0x00: {
                // Special case of bit pattern 0xxx.
                if (byte1 == 0) {
                    ALOGE("String shorter than indicated utf16_size %#x",
                            utf16Size);
                    return NULL;
                }
                break;
            }
            case 0x01:
            case 0x02:
            case 0x03:
            case 0x04:
            case 0x05:
            case 0x06:
            case 0x07: {
                // Bit pattern 0xxx. No need for any extra bytes or checks.
                break;
            }
            case 0x08:
            case 0x09:
            case 0x0a:
            case 0x0b:
            case 0x0f: {
                /*
                 * Bit pattern 10xx or 1111, which are illegal start bytes.
                 * Note: 1111 is valid for normal UTF-8, but not the
                 * modified UTF-8 used here.
                 */
                ALOGE("Illegal start byte %#x", byte1);
                return NULL;
            }
            case 0x0e: {
                // Bit pattern 1110, so there are two additional bytes.
                u1 byte2 = *(data++);
                if ((byte2 & 0xc0) != 0x80) {
                    ALOGE("Illegal continuation byte %#x", byte2);
                    return NULL;
                }
                u1 byte3 = *(data++);
                if ((byte3 & 0xc0) != 0x80) {
                    ALOGE("Illegal continuation byte %#x", byte3);
                    return NULL;
                }
                u2 value = ((byte1 & 0x0f) << 12) | ((byte2 & 0x3f) << 6)
                    | (byte3 & 0x3f);
                if (value < 0x800) {
                    ALOGE("Illegal representation for value %x", value);
                    return NULL;
                }
                break;
            }
            case 0x0c:
            case 0x0d: {
                // Bit pattern 110x, so there is one additional byte.
                u1 byte2 = *(data++);
                if ((byte2 & 0xc0) != 0x80) {
                    ALOGE("Illegal continuation byte %#x", byte2);
                    return NULL;
                }
                u2 value = ((byte1 & 0x1f) << 6) | (byte2 & 0x3f);
                if ((value != 0) && (value < 0x80)) {
                    ALOGE("Illegal representation for value %x", value);
                    return NULL;
                }
                break;
            }
        }
    }

    if (*(data++) != '\0') {
        ALOGE("String longer than indicated utf16_size %#x", utf16Size);
        return NULL;
    }

    return (void*) data;
}

/* Perform intra-item verification on debug_info_item. */
static void* intraVerifyDebugInfoItem(const CheckState* state, void* ptr) {
    const u1* fileEnd = state->fileEnd;
    const u1* data = (const u1*) ptr;
    bool okay = true;
    u4 i;

    readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);

    if (!okay) {
        ALOGE("Bogus line_start");
        return NULL;
    }

    u4 parametersSize =
        readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);

    if (!okay) {
        ALOGE("Bogus parameters_size");
        return NULL;
    }

    if (parametersSize > 65536) {
        ALOGE("Invalid parameters_size: %#x", parametersSize);
        return NULL;
    }

    for (i = 0; i < parametersSize; i++) {
        u4 parameterName =
            readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);

        if (!okay) {
            ALOGE("Bogus parameter_name");
            return NULL;
        }

        if (parameterName != 0) {
            parameterName--;
            CHECK_INDEX(parameterName, state->pHeader->stringIdsSize);
        }
    }

    bool done = false;
    while (!done) {
        u1 opcode = *(data++);

        switch (opcode) {
            case DBG_END_SEQUENCE: {
                done = true;
                break;
            }
            case DBG_ADVANCE_PC: {
                readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                break;
            }
            case DBG_ADVANCE_LINE: {
                readAndVerifySignedLeb128(&data, fileEnd, &okay);
                break;
            }
            case DBG_START_LOCAL: {
                u4 idx;
                u4 regNum = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (regNum >= 65536) {
                    okay = false;
                    break;
                }
                idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (idx != 0) {
                    idx--;
                    CHECK_INDEX(idx, state->pHeader->stringIdsSize);
                }
                idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (idx != 0) {
                    idx--;
                    CHECK_INDEX(idx, state->pHeader->stringIdsSize);
                }
                break;
            }
            case DBG_END_LOCAL:
            case DBG_RESTART_LOCAL: {
                u4 regNum = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (regNum >= 65536) {
                    okay = false;
                    break;
                }
                break;
            }
            case DBG_START_LOCAL_EXTENDED: {
                u4 idx;
                u4 regNum = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (regNum >= 65536) {
                    okay = false;
                    break;
                }
                idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (idx != 0) {
                    idx--;
                    CHECK_INDEX(idx, state->pHeader->stringIdsSize);
                }
                idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (idx != 0) {
                    idx--;
                    CHECK_INDEX(idx, state->pHeader->stringIdsSize);
                }
                idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (idx != 0) {
                    idx--;
                    CHECK_INDEX(idx, state->pHeader->stringIdsSize);
                }
                break;
            }
            case DBG_SET_FILE: {
                u4 idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
                if (!okay) break;
                if (idx != 0) {
                    idx--;
                    CHECK_INDEX(idx, state->pHeader->stringIdsSize);
                }
                break;
            }
            default: {
                // No arguments to parse for anything else.
            }
        }

        if (!okay) {
            ALOGE("Bogus syntax for opcode %02x", opcode);
            return NULL;
        }
    }

    return (void*) data;
}

/* defined below */
static const u1* verifyEncodedValue(const CheckState* state, const u1* data,
        bool crossVerify);
static const u1* verifyEncodedAnnotation(const CheckState* state,
        const u1* data, bool crossVerify);

/* Helper for verifyEncodedValue(), which reads a 1- to 4- byte unsigned
 * little endian value. */
static u4 readUnsignedLittleEndian(const CheckState* state, const u1** pData,
        u4 size) {
    const u1* data = *pData;
    u4 result = 0;
    u4 i;

    CHECK_PTR_RANGE(data, data + size);

    for (i = 0; i < size; i++) {
        result |= ((u4) *(data++)) << (i * 8);
    }

    *pData = data;
    return result;
}

/* Helper for *VerifyAnnotationItem() and *VerifyEncodedArrayItem(), which
 * verifies an encoded_array. */
static const u1* verifyEncodedArray(const CheckState* state,
        const u1* data, bool crossVerify) {
    bool okay = true;
    u4 size = readAndVerifyUnsignedLeb128(&data, state->fileEnd, &okay);

    if (!okay) {
        ALOGE("Bogus encoded_array size");
        return NULL;
    }

    while (size--) {
        data = verifyEncodedValue(state, data, crossVerify);
        if (data == NULL) {
            ALOGE("Bogus encoded_array value");
            return NULL;
        }
    }

    return data;
}

static u4 numberOfMethodHandles(const CheckState* state) {
    if (state->pMethodHandleItems != nullptr) {
        return state->pMethodHandleItems->size;
    }
    return 0;
}

/* Helper for *VerifyAnnotationItem() and *VerifyEncodedArrayItem(), which
 * verifies an encoded_value. */
static const u1* verifyEncodedValue(const CheckState* state,
        const u1* data, bool crossVerify) {
    CHECK_PTR_RANGE(data, data + 1);

    u1 headerByte = *(data++);
    u4 valueType = headerByte & kDexAnnotationValueTypeMask;
    u4 valueArg = headerByte >> kDexAnnotationValueArgShift;

    switch (valueType) {
        case kDexAnnotationByte: {
            if (valueArg != 0) {
                ALOGE("Bogus byte size %#x", valueArg);
                return NULL;
            }
            data++;
            break;
        }
        case kDexAnnotationShort:
        case kDexAnnotationChar: {
            if (valueArg > 1) {
                ALOGE("Bogus char/short size %#x", valueArg);
                return NULL;
            }
            data += valueArg + 1;
            break;
        }
        case kDexAnnotationInt:
        case kDexAnnotationFloat: {
            if (valueArg > 3) {
                ALOGE("Bogus int/float size %#x", valueArg);
                return NULL;
            }
            data += valueArg + 1;
            break;
        }
        case kDexAnnotationLong:
        case kDexAnnotationDouble: {
            data += valueArg + 1;
            break;
        }
        case kDexAnnotationMethodType: {
            if (valueArg > 3) {
                ALOGE("Bogus method type size %#x", valueArg);
                return NULL;
            }
            u4 idx = readUnsignedLittleEndian(state, &data, valueArg + 1);
            CHECK_INDEX(idx, state->pHeader->protoIdsSize);
            break;
        }
        case kDexAnnotationMethodHandle: {
            if (valueArg > 3) {
                ALOGE("Bogus method type size %#x", valueArg);
                return NULL;
            }
            u4 idx = readUnsignedLittleEndian(state, &data, valueArg + 1);
            CHECK_INDEX(idx, numberOfMethodHandles(state));
            break;
        }
        case kDexAnnotationString: {
            if (valueArg > 3) {
                ALOGE("Bogus string size %#x", valueArg);
                return NULL;
            }
            u4 idx = readUnsignedLittleEndian(state, &data, valueArg + 1);
            CHECK_INDEX(idx, state->pHeader->stringIdsSize);
            break;
        }
        case kDexAnnotationType: {
            if (valueArg > 3) {
                ALOGE("Bogus type size %#x", valueArg);
                return NULL;
            }
            u4 idx = readUnsignedLittleEndian(state, &data, valueArg + 1);
            CHECK_INDEX(idx, state->pHeader->typeIdsSize);
            break;
        }
        case kDexAnnotationField:
        case kDexAnnotationEnum: {
            if (valueArg > 3) {
                ALOGE("Bogus field/enum size %#x", valueArg);
                return NULL;
            }
            u4 idx = readUnsignedLittleEndian(state, &data, valueArg + 1);
            CHECK_INDEX(idx, state->pHeader->fieldIdsSize);
            break;
        }
        case kDexAnnotationMethod: {
            if (valueArg > 3) {
                ALOGE("Bogus method size %#x", valueArg);
                return NULL;
            }
            u4 idx = readUnsignedLittleEndian(state, &data, valueArg + 1);
            CHECK_INDEX(idx, state->pHeader->methodIdsSize);
            break;
        }
        case kDexAnnotationArray: {
            if (valueArg != 0) {
                ALOGE("Bogus array value_arg %#x", valueArg);
                return NULL;
            }
            data = verifyEncodedArray(state, data, crossVerify);
            break;
        }
        case kDexAnnotationAnnotation: {
            if (valueArg != 0) {
                ALOGE("Bogus annotation value_arg %#x", valueArg);
                return NULL;
            }
            data = verifyEncodedAnnotation(state, data, crossVerify);
            break;
        }
        case kDexAnnotationNull: {
            if (valueArg != 0) {
                ALOGE("Bogus null value_arg %#x", valueArg);
                return NULL;
            }
            // Nothing else to do for this type.
            break;
        }
        case kDexAnnotationBoolean: {
            if (valueArg > 1) {
                ALOGE("Bogus boolean value_arg %#x", valueArg);
                return NULL;
            }
            // Nothing else to do for this type.
            break;
        }
        default: {
            ALOGE("Bogus value_type %#x", valueType);
            return NULL;
        }
    }

    return data;
}

/* Helper for *VerifyAnnotationItem() and *VerifyEncodedArrayItem(), which
 * verifies an encoded_annotation. */
static const u1* verifyEncodedAnnotation(const CheckState* state,
        const u1* data, bool crossVerify) {
    const u1* fileEnd = state->fileEnd;
    bool okay = true;
    u4 idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);

    if (!okay) {
        ALOGE("Bogus encoded_annotation type_idx");
        return NULL;
    }

    CHECK_INDEX(idx, state->pHeader->typeIdsSize);

    if (crossVerify) {
        const char* descriptor = dexStringByTypeIdx(state->pDexFile, idx);
        if (!dexIsClassDescriptor(descriptor)) {
            ALOGE("Bogus annotation type: '%s'", descriptor);
            return NULL;
        }
    }

    u4 size = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);
    u4 lastIdx = 0;
    bool first = true;

    if (!okay) {
        ALOGE("Bogus encoded_annotation size");
        return NULL;
    }

    while (size--) {
        idx = readAndVerifyUnsignedLeb128(&data, fileEnd, &okay);

        if (!okay) {
            ALOGE("Bogus encoded_annotation name_idx");
            return NULL;
        }

        CHECK_INDEX(idx, state->pHeader->stringIdsSize);

        if (crossVerify) {
            const char* name = dexStringById(state->pDexFile, idx);
            if (!dexIsValidMemberName(name)) {
                ALOGE("Bogus annotation member name: '%s'", name);
                return NULL;
            }
        }

        if (first) {
            first = false;
        } else if (lastIdx >= idx) {
            ALOGE("Out-of-order encoded_annotation name_idx: %#x then %#x",
                    lastIdx, idx);
            return NULL;
        }

        data = verifyEncodedValue(state, data, crossVerify);
        lastIdx = idx;

        if (data == NULL) {
            return NULL;
        }
    }

    return data;
}

/* Perform intra-item verification on encoded_array_item. */
static void* intraVerifyEncodedArrayItem(const CheckState* state, void* ptr) {
    return (void*) verifyEncodedArray(state, (const u1*) ptr, false);
}

/* Perform intra-item verification on annotation_item. */
static void* intraVerifyAnnotationItem(const CheckState* state, void* ptr) {
    const u1* data = (const u1*) ptr;

    CHECK_PTR_RANGE(data, data + 1);

    switch (*(data++)) {
        case kDexVisibilityBuild:
        case kDexVisibilityRuntime:
        case kDexVisibilitySystem: {
            break;
        }
        default: {
            ALOGE("Bogus annotation visibility: %#x", *data);
            return NULL;
        }
    }

    return (void*) verifyEncodedAnnotation(state, data, false);
}

/*
 * Function to visit an individual top-level item type.
 */
typedef void* ItemVisitorFunction(const CheckState* state, void* ptr);

/*
 * Iterate over all the items in a section, optionally updating the
 * data map (done if mapType is passed as non-negative). The section
 * must consist of concatenated items of the same type.
 */
static bool iterateSectionWithOptionalUpdate(CheckState* state,
        u4 offset, u4 count, ItemVisitorFunction* func, u4 alignment,
        u4* nextOffset, int mapType) {
    u4 alignmentMask = alignment - 1;
    u4 i;

    state->previousItem = NULL;

    for (i = 0; i < count; i++) {
        u4 newOffset = (offset + alignmentMask) & ~alignmentMask;
        u1* ptr = (u1*) filePointer(state, newOffset);

        if (offset < newOffset) {
            ptr = (u1*) filePointer(state, offset);
            if (offset < newOffset) {
                CHECK_OFFSET_RANGE(offset, newOffset);
                while (offset < newOffset) {
                    if (*ptr != '\0') {
                        ALOGE("Non-zero padding 0x%02x @ %x", *ptr, offset);
                        return false;
                    }
                    ptr++;
                    offset++;
                }
            }
        }

        u1* newPtr = (u1*) func(state, ptr);
        newOffset = fileOffset(state, newPtr);

        if (newPtr == NULL) {
            ALOGE("Trouble with item %d @ offset %#x", i, offset);
            return false;
        }

        if (newOffset > state->fileLen) {
            ALOGE("Item %d @ offset %#x ends out of bounds", i, offset);
            return false;
        }

        if (mapType >= 0) {
            dexDataMapAdd(state->pDataMap, offset, mapType);
        }

        state->previousItem = ptr;
        offset = newOffset;
    }

    if (nextOffset != NULL) {
        *nextOffset = offset;
    }

    return true;
}

/*
 * Iterate over all the items in a section. The section must consist of
 * concatenated items of the same type. This variant will not update the data
 * map.
 */
static bool iterateSection(CheckState* state, u4 offset, u4 count,
        ItemVisitorFunction* func, u4 alignment, u4* nextOffset) {
    return iterateSectionWithOptionalUpdate(state, offset, count, func,
            alignment, nextOffset, -1);
}

/*
 * Like iterateSection(), but also check that the offset and count match
 * a given pair of expected values.
 */
static bool checkBoundsAndIterateSection(CheckState* state,
        u4 offset, u4 count, u4 expectedOffset, u4 expectedCount,
        ItemVisitorFunction* func, u4 alignment, u4* nextOffset) {
    if (offset != expectedOffset) {
        ALOGE("Bogus offset for section: got %#x; expected %#x",
                offset, expectedOffset);
        return false;
    }

    if (count != expectedCount) {
        ALOGE("Bogus size for section: got %#x; expected %#x",
                count, expectedCount);
        return false;
    }

    return iterateSection(state, offset, count, func, alignment, nextOffset);
}

/*
 * Like iterateSection(), but also update the data section map and
 * check that all the items fall within the data section.
 */
static bool iterateDataSection(CheckState* state, u4 offset, u4 count,
        ItemVisitorFunction* func, u4 alignment, u4* nextOffset, int mapType) {
    u4 dataStart = state->pHeader->dataOff;
    u4 dataEnd = dataStart + state->pHeader->dataSize;

    assert(nextOffset != NULL);

    if ((offset < dataStart) || (offset >= dataEnd)) {
        ALOGE("Bogus offset for data subsection: %#x", offset);
        return false;
    }

    if (!iterateSectionWithOptionalUpdate(state, offset, count, func,
                    alignment, nextOffset, mapType)) {
        return false;
    }

    if (*nextOffset > dataEnd) {
        ALOGE("Out-of-bounds end of data subsection: %#x", *nextOffset);
        return false;
    }

    return true;
}

/*
 * Byte-swap all items in the given map except the header and the map
 * itself, both of which should have already gotten swapped. This also
 * does all possible intra-item verification, that is, verification
 * that doesn't need to assume the sanctity of the contents of *other*
 * items. The intra-item limitation is because at the time an item is
 * asked to verify itself, it can't assume that the items it refers to
 * have been byte-swapped and verified.
 */
static bool swapEverythingButHeaderAndMap(CheckState* state,
        DexMapList* pMap) {
    const DexMapItem* item = pMap->list;
    u4 lastOffset = 0;
    u4 count = pMap->size;
    bool okay = true;

    while (okay && count--) {
        u4 sectionOffset = item->offset;
        u4 sectionCount = item->size;
        u2 type = item->type;

        if (lastOffset < sectionOffset) {
            CHECK_OFFSET_RANGE(lastOffset, sectionOffset);
            const u1* ptr = (const u1*) filePointer(state, lastOffset);
            while (lastOffset < sectionOffset) {
                if (*ptr != '\0') {
                    ALOGE("Non-zero padding 0x%02x before section start @ %x",
                            *ptr, lastOffset);
                    okay = false;
                    break;
                }
                ptr++;
                lastOffset++;
            }
        } else if (lastOffset > sectionOffset) {
            ALOGE("Section overlap or out-of-order map: %x, %x",
                    lastOffset, sectionOffset);
            okay = false;
        }

        if (!okay) {
            break;
        }

        switch (type) {
            case kDexTypeHeaderItem: {
                /*
                 * The header got swapped very early on, but do some
                 * additional sanity checking here.
                 */
                okay = checkHeaderSection(state, sectionOffset, sectionCount,
                        &lastOffset);
                break;
            }
            case kDexTypeStringIdItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, state->pHeader->stringIdsOff,
                        state->pHeader->stringIdsSize, swapStringIdItem,
                        sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeTypeIdItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, state->pHeader->typeIdsOff,
                        state->pHeader->typeIdsSize, swapTypeIdItem,
                        sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeProtoIdItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, state->pHeader->protoIdsOff,
                        state->pHeader->protoIdsSize, swapProtoIdItem,
                        sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeFieldIdItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, state->pHeader->fieldIdsOff,
                        state->pHeader->fieldIdsSize, swapFieldIdItem,
                        sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeMethodIdItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, state->pHeader->methodIdsOff,
                        state->pHeader->methodIdsSize, swapMethodIdItem,
                        sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeClassDefItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, state->pHeader->classDefsOff,
                        state->pHeader->classDefsSize, swapClassDefItem,
                        sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeCallSiteIdItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, sectionOffset, sectionCount,
                        swapCallSiteId, sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeMethodHandleItem: {
                okay = checkBoundsAndIterateSection(state, sectionOffset,
                        sectionCount, sectionOffset, sectionCount,
                        swapMethodHandleItem, sizeof(u4), &lastOffset);
                break;
            }
            case kDexTypeMapList: {
                /*
                 * The map section was swapped early on, but do some
                 * additional sanity checking here.
                 */
                okay = checkMapSection(state, sectionOffset, sectionCount,
                        &lastOffset);
                break;
            }
            case kDexTypeTypeList: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        swapTypeList, sizeof(u4), &lastOffset, type);
                break;
            }
            case kDexTypeAnnotationSetRefList: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        swapAnnotationSetRefList, sizeof(u4), &lastOffset,
                        type);
                break;
            }
            case kDexTypeAnnotationSetItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        swapAnnotationSetItem, sizeof(u4), &lastOffset, type);
                break;
            }
            case kDexTypeClassDataItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        intraVerifyClassDataItem, sizeof(u1), &lastOffset,
                        type);
                break;
            }
            case kDexTypeCodeItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        swapCodeItem, sizeof(u4), &lastOffset, type);
                break;
            }
            case kDexTypeStringDataItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        intraVerifyStringDataItem, sizeof(u1), &lastOffset,
                        type);
                break;
            }
            case kDexTypeDebugInfoItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        intraVerifyDebugInfoItem, sizeof(u1), &lastOffset,
                        type);
                break;
            }
            case kDexTypeAnnotationItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        intraVerifyAnnotationItem, sizeof(u1), &lastOffset,
                        type);
                break;
            }
            case kDexTypeEncodedArrayItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        intraVerifyEncodedArrayItem, sizeof(u1), &lastOffset,
                        type);
                break;
            }
            case kDexTypeAnnotationsDirectoryItem: {
                okay = iterateDataSection(state, sectionOffset, sectionCount,
                        swapAnnotationsDirectoryItem, sizeof(u4), &lastOffset,
                        type);
                break;
            }
            default: {
                ALOGE("Unknown map item type %04x", type);
                return false;
            }
        }

        if (!okay) {
            ALOGE("Swap of section type %04x failed", type);
        }

        item++;
    }

    return okay;
}

/*
 * Perform cross-item verification on everything that needs it. This
 * pass is only called after all items are byte-swapped and
 * intra-verified (checked for internal consistency).
 */
static bool crossVerifyEverything(CheckState* state, DexMapList* pMap)
{
    const DexMapItem* item = pMap->list;
    u4 count = pMap->size;
    bool okay = true;

    while (okay && count--) {
        u4 sectionOffset = item->offset;
        u4 sectionCount = item->size;

        switch (item->type) {
            case kDexTypeHeaderItem:
            case kDexTypeMapList:
            case kDexTypeTypeList:
            case kDexTypeCodeItem:
            case kDexTypeStringDataItem:
            case kDexTypeDebugInfoItem:
            case kDexTypeAnnotationItem:
            case kDexTypeEncodedArrayItem: {
                // There is no need for cross-item verification for these.
                break;
            }
            case kDexTypeStringIdItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyStringIdItem, sizeof(u4), NULL);
                break;
            }
            case kDexTypeTypeIdItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyTypeIdItem, sizeof(u4), NULL);
                break;
            }
            case kDexTypeProtoIdItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyProtoIdItem, sizeof(u4), NULL);
                break;
            }
            case kDexTypeFieldIdItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyFieldIdItem, sizeof(u4), NULL);
                break;
            }
            case kDexTypeMethodIdItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyMethodIdItem, sizeof(u4), NULL);
                break;
            }
            case kDexTypeClassDefItem: {
                // Allocate (on the stack) the "observed class_def" bits.
                size_t arraySize = calcDefinedClassBitsSize(state);
                u4 definedClassBits[arraySize];
                memset(definedClassBits, 0, arraySize * sizeof(u4));
                state->pDefinedClassBits = definedClassBits;

                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyClassDefItem, sizeof(u4), NULL);

                state->pDefinedClassBits = NULL;
                break;
            }
            case kDexTypeCallSiteIdItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyCallSiteId, sizeof(u4), NULL);
                break;
            }
            case kDexTypeMethodHandleItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyMethodHandleItem, sizeof(u4), NULL);
                break;
            }
            case kDexTypeAnnotationSetRefList: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyAnnotationSetRefList, sizeof(u4), NULL);
                break;
            }
            case kDexTypeAnnotationSetItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyAnnotationSetItem, sizeof(u4), NULL);
                break;
            }
            case kDexTypeClassDataItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyClassDataItem, sizeof(u1), NULL);
                break;
            }
            case kDexTypeAnnotationsDirectoryItem: {
                okay = iterateSection(state, sectionOffset, sectionCount,
                        crossVerifyAnnotationsDirectoryItem, sizeof(u4), NULL);
                break;
            }
            default: {
                ALOGE("Unknown map item type %04x", item->type);
                return false;
            }
        }

        if (!okay) {
            ALOGE("Cross-item verify of section type %04x failed",
                    item->type);
        }

        item++;
    }

    return okay;
}

/* (documented in header file) */
bool dexHasValidMagic(const DexHeader* pHeader)
{
    const u1* magic = pHeader->magic;
    const u1* version = &magic[4];

    if (memcmp(magic, DEX_MAGIC, 4) != 0) {
        ALOGE("ERROR: unrecognized magic number (%02x %02x %02x %02x)",
            magic[0], magic[1], magic[2], magic[3]);
        return false;
    }

    if ((memcmp(version, DEX_MAGIC_VERS, 4) != 0) &&
        (memcmp(version, DEX_MAGIC_VERS_API_13, 4) != 0) &&
        (memcmp(version, DEX_MAGIC_VERS_37, 4) != 0) &&
        (memcmp(version, DEX_MAGIC_VERS_38, 4) != 0) &&
        (memcmp(version, DEX_MAGIC_VERS_39, 4) != 0)) {
        /*
         * Magic was correct, but this is an unsupported older or
         * newer format variant.
         */
        ALOGE("ERROR: unsupported dex version (%02x %02x %02x %02x)",
            version[0], version[1], version[2], version[3]);
        return false;
    }

    return true;
}

/*
 * Fix the byte ordering of all fields in the DEX file, and do
 * structural verification. This is only required for code that opens
 * "raw" DEX files, such as the DEX optimizer.
 *
 * Returns 0 on success, nonzero on failure.
 */
int dexSwapAndVerify(u1* addr, size_t len)
{
    DexHeader* pHeader;
    CheckState state;
    bool okay = true;

    memset(&state, 0, sizeof(state));
    ALOGV("+++ swapping and verifying");

    /*
     * Note: The caller must have verified that "len" is at least as
     * large as a dex file header.
     */
    pHeader = (DexHeader*) addr;

    if (!dexHasValidMagic(pHeader)) {
        okay = false;
    }

    if (okay) {
        u4 expectedLen = SWAP4(pHeader->fileSize);
        if (len != expectedLen) {
            ALOGE("ERROR: Bad length: expected %u, got %zu", expectedLen, len);
            okay = false;
        }
    }

    if (okay) {
        /*
         * Compute the adler32 checksum and compare it to what's stored in
         * the file.  This isn't free, but chances are good that we just
         * unpacked this from a jar file and have all of the pages sitting
         * in memory, so it's pretty quick.
         *
         * This might be a big-endian system, so we need to do this before
         * we byte-swap the header.
         */
        uLong adler = adler32(0L, Z_NULL, 0);
        const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum);
        u4 storedFileSize = SWAP4(pHeader->fileSize);
        u4 expectedChecksum = SWAP4(pHeader->checksum);

        adler = adler32(adler, ((const u1*) pHeader) + nonSum,
                    storedFileSize - nonSum);

        if (adler != expectedChecksum) {
            ALOGE("ERROR: bad checksum (%08lx, expected %08x)",
                adler, expectedChecksum);
            okay = false;
        }
    }

    if (okay) {
        state.fileStart = addr;
        state.fileEnd = addr + len;
        state.fileLen = len;
        state.pDexFile = NULL;
        state.pDataMap = NULL;
        state.pDefinedClassBits = NULL;
        state.previousItem = NULL;

        /*
         * Swap the header and check the contents.
         */
        okay = swapDexHeader(&state, pHeader);
    }

    if (okay) {
        state.pHeader = pHeader;

        if (pHeader->headerSize < sizeof(DexHeader)) {
            ALOGE("ERROR: Small header size %d, struct %d",
                    pHeader->headerSize, (int) sizeof(DexHeader));
            okay = false;
        } else if (pHeader->headerSize > sizeof(DexHeader)) {
            ALOGW("WARNING: Large header size %d, struct %d",
                    pHeader->headerSize, (int) sizeof(DexHeader));
            // keep going?
        }
    }

    if (okay) {
        /*
         * Look for the map. Swap it and then use it to find and swap
         * everything else.
         */
        if (pHeader->mapOff != 0) {
            DexFile dexFile;
            DexMapList* pDexMap = (DexMapList*) (addr + pHeader->mapOff);

            okay = okay && swapMap(&state, pDexMap);
            okay = okay && swapEverythingButHeaderAndMap(&state, pDexMap);

            dexFileSetupBasicPointers(&dexFile, addr);
            state.pDexFile = &dexFile;

            okay = okay && crossVerifyEverything(&state, pDexMap);
        } else {
            ALOGE("ERROR: No map found; impossible to byte-swap and verify");
            okay = false;
        }
    }

    if (!okay) {
        ALOGE("ERROR: Byte swap + verify failed");
    }

    if (state.pDataMap != NULL) {
        dexDataMapFree(state.pDataMap);
    }

    return !okay;       // 0 == success
}

/*
 * Detect the file type of the given memory buffer via magic number.
 * Call dexSwapAndVerify() on an unoptimized DEX file, do nothing
 * but return successfully on an optimized DEX file, and report an
 * error for all other cases.
 *
 * Returns 0 on success, nonzero on failure.
 */
int dexSwapAndVerifyIfNecessary(u1* addr, size_t len)
{
    if (memcmp(addr, DEX_OPT_MAGIC, 4) == 0) {
        // It is an optimized dex file.
        return 0;
    }

    if (memcmp(addr, DEX_MAGIC, 4) == 0) {
        // It is an unoptimized dex file.
        return dexSwapAndVerify(addr, len);
    }

    ALOGE("ERROR: Bad magic number (0x%02x %02x %02x %02x)",
             addr[0], addr[1], addr[2], addr[3]);

    return 1;
}
