Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cfbbe06 authored by Lajos Molnar's avatar Lajos Molnar Committed by Automerger Merge Worker
Browse files

Merge "stagefright/foundation: Increase AMessage max item count to 256" into sc-dev am: b24894a1

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/15119284

Change-Id: Ibee63082dccb85cf0de2d847e80f0d97f2bfcb44
parents 5e9d4a5d b24894a1
Loading
Loading
Loading
Loading
+81 −69
Original line number Diff line number Diff line
@@ -54,13 +54,11 @@ status_t AReplyToken::setReply(const sp<AMessage> &reply) {

AMessage::AMessage(void)
    : mWhat(0),
      mTarget(0),
      mNumItems(0) {
      mTarget(0) {
}

AMessage::AMessage(uint32_t what, const sp<const AHandler> &handler)
    : mWhat(what),
      mNumItems(0) {
    : mWhat(what) {
    setTarget(handler);
}

@@ -89,13 +87,13 @@ void AMessage::setTarget(const sp<const AHandler> &handler) {
}

void AMessage::clear() {
    for (size_t i = 0; i < mNumItems; ++i) {
        Item *item = &mItems[i];
        delete[] item->mName;
        item->mName = NULL;
        freeItemValue(item);
    // Item needs to be handled delicately
    for (Item &item : mItems) {
        delete[] item.mName;
        item.mName = NULL;
        freeItemValue(&item);
    }
    mNumItems = 0;
    mItems.clear();
}

void AMessage::freeItemValue(Item *item) {
@@ -157,7 +155,7 @@ inline size_t AMessage::findItemIndex(const char *name, size_t len) const {
    size_t memchecks = 0;
#endif
    size_t i = 0;
    for (; i < mNumItems; i++) {
    for (; i < mItems.size(); i++) {
        if (len != mItems[i].mNameLength) {
            continue;
        }
@@ -172,7 +170,7 @@ inline size_t AMessage::findItemIndex(const char *name, size_t len) const {
    {
        Mutex::Autolock _l(gLock);
        ++gFindItemCalls;
        gAverageNumItems += mNumItems;
        gAverageNumItems += mItems.size();
        gAverageNumMemChecks += memchecks;
        gAverageNumChecks += i;
        reportStats();
@@ -188,20 +186,26 @@ void AMessage::Item::setName(const char *name, size_t len) {
    memcpy((void*)mName, name, len + 1);
}

AMessage::Item::Item(const char *name, size_t len)
    : mType(kTypeInt32) {
    // mName and mNameLength are initialized by setName
    setName(name, len);
}

AMessage::Item *AMessage::allocateItem(const char *name) {
    size_t len = strlen(name);
    size_t i = findItemIndex(name, len);
    Item *item;

    if (i < mNumItems) {
    if (i < mItems.size()) {
        item = &mItems[i];
        freeItemValue(item);
    } else {
        CHECK(mNumItems < kMaxNumItems);
        i = mNumItems++;
        CHECK(mItems.size() < kMaxNumItems);
        i = mItems.size();
        // place a 'blank' item at the end - this is of type kTypeInt32
        mItems.emplace_back(name, len);
        item = &mItems[i];
        item->mType = kTypeInt32;
        item->setName(name, len);
    }

    return item;
@@ -210,7 +214,7 @@ AMessage::Item *AMessage::allocateItem(const char *name) {
const AMessage::Item *AMessage::findItem(
        const char *name, Type type) const {
    size_t i = findItemIndex(name, strlen(name));
    if (i < mNumItems) {
    if (i < mItems.size()) {
        const Item *item = &mItems[i];
        return item->mType == type ? item : NULL;

@@ -220,7 +224,7 @@ const AMessage::Item *AMessage::findItem(

bool AMessage::findAsFloat(const char *name, float *value) const {
    size_t i = findItemIndex(name, strlen(name));
    if (i < mNumItems) {
    if (i < mItems.size()) {
        const Item *item = &mItems[i];
        switch (item->mType) {
            case kTypeFloat:
@@ -247,7 +251,7 @@ bool AMessage::findAsFloat(const char *name, float *value) const {

bool AMessage::findAsInt64(const char *name, int64_t *value) const {
    size_t i = findItemIndex(name, strlen(name));
    if (i < mNumItems) {
    if (i < mItems.size()) {
        const Item *item = &mItems[i];
        switch (item->mType) {
            case kTypeInt64:
@@ -265,15 +269,16 @@ bool AMessage::findAsInt64(const char *name, int64_t *value) const {

bool AMessage::contains(const char *name) const {
    size_t i = findItemIndex(name, strlen(name));
    return i < mNumItems;
    return i < mItems.size();
}

#define BASIC_TYPE(NAME,FIELDNAME,TYPENAME)                             \
void AMessage::set##NAME(const char *name, TYPENAME value) {            \
    Item *item = allocateItem(name);                                    \
                                                                        \
    if (item) {                                                         \
        item->mType = kType##NAME;                                      \
        item->u.FIELDNAME = value;                                      \
    }                                                                   \
}                                                                       \
                                                                        \
/* NOLINT added to avoid incorrect warning/fix from clang.tidy */       \
@@ -298,9 +303,11 @@ BASIC_TYPE(Pointer,ptrValue,void *)
void AMessage::setString(
        const char *name, const char *s, ssize_t len) {
    Item *item = allocateItem(name);
    if (item) {
        item->mType = kTypeString;
        item->u.stringValue = new AString(s, len < 0 ? strlen(s) : len);
    }
}

void AMessage::setString(
        const char *name, const AString &s) {
@@ -310,11 +317,13 @@ void AMessage::setString(
void AMessage::setObjectInternal(
        const char *name, const sp<RefBase> &obj, Type type) {
    Item *item = allocateItem(name);
    if (item) {
        item->mType = type;

        if (obj != NULL) { obj->incStrong(this); }
        item->u.refValue = obj.get();
    }
}

void AMessage::setObject(const char *name, const sp<RefBase> &obj) {
    setObjectInternal(name, obj, kTypeObject);
@@ -326,16 +335,19 @@ void AMessage::setBuffer(const char *name, const sp<ABuffer> &buffer) {

void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
    Item *item = allocateItem(name);
    if (item) {
        item->mType = kTypeMessage;

        if (obj != NULL) { obj->incStrong(this); }
        item->u.refValue = obj.get();
    }
}

void AMessage::setRect(
        const char *name,
        int32_t left, int32_t top, int32_t right, int32_t bottom) {
    Item *item = allocateItem(name);
    if (item) {
        item->mType = kTypeRect;

        item->u.rectValue.mLeft = left;
@@ -343,6 +355,7 @@ void AMessage::setRect(
        item->u.rectValue.mRight = right;
        item->u.rectValue.mBottom = bottom;
    }
}

bool AMessage::findString(const char *name, AString *value) const {
    const Item *item = findItem(name, kTypeString);
@@ -466,18 +479,18 @@ bool AMessage::senderAwaitsResponse(sp<AReplyToken> *replyToken) {

sp<AMessage> AMessage::dup() const {
    sp<AMessage> msg = new AMessage(mWhat, mHandler.promote());
    msg->mNumItems = mNumItems;
    msg->mItems = mItems;

#ifdef DUMP_STATS
    {
        Mutex::Autolock _l(gLock);
        ++gDupCalls;
        gAverageDupItems += mNumItems;
        gAverageDupItems += mItems.size();
        reportStats();
    }
#endif

    for (size_t i = 0; i < mNumItems; ++i) {
    for (size_t i = 0; i < mItems.size(); ++i) {
        const Item *from = &mItems[i];
        Item *to = &msg->mItems[i];

@@ -560,7 +573,7 @@ AString AMessage::debugString(int32_t indent) const {
    }
    s.append(") = {\n");

    for (size_t i = 0; i < mNumItems; ++i) {
    for (size_t i = 0; i < mItems.size(); ++i) {
        const Item &item = mItems[i];

        switch (item.mType) {
@@ -653,19 +666,20 @@ sp<AMessage> AMessage::FromParcel(const Parcel &parcel, size_t maxNestingLevel)
    sp<AMessage> msg = new AMessage();
    msg->setWhat(what);

    msg->mNumItems = static_cast<size_t>(parcel.readInt32());
    if (msg->mNumItems > kMaxNumItems) {
    size_t numItems = static_cast<size_t>(parcel.readInt32());
    if (numItems > kMaxNumItems) {
        ALOGE("Too large number of items clipped.");
        msg->mNumItems = kMaxNumItems;
        numItems = kMaxNumItems;
    }
    msg->mItems.resize(numItems);

    for (size_t i = 0; i < msg->mNumItems; ++i) {
    for (size_t i = 0; i < msg->mItems.size(); ++i) {
        Item *item = &msg->mItems[i];

        const char *name = parcel.readCString();
        if (name == NULL) {
            ALOGE("Failed reading name for an item. Parsing aborted.");
            msg->mNumItems = i;
            msg->mItems.resize(i);
            break;
        }

@@ -709,7 +723,7 @@ sp<AMessage> AMessage::FromParcel(const Parcel &parcel, size_t maxNestingLevel)
                if (stringValue == NULL) {
                    ALOGE("Failed reading string value from a parcel. "
                        "Parsing aborted.");
                    msg->mNumItems = i;
                    msg->mItems.resize(i);
                    continue;
                    // The loop will terminate subsequently.
                } else {
@@ -754,11 +768,9 @@ sp<AMessage> AMessage::FromParcel(const Parcel &parcel, size_t maxNestingLevel)

void AMessage::writeToParcel(Parcel *parcel) const {
    parcel->writeInt32(static_cast<int32_t>(mWhat));
    parcel->writeInt32(static_cast<int32_t>(mNumItems));

    for (size_t i = 0; i < mNumItems; ++i) {
        const Item &item = mItems[i];
    parcel->writeInt32(static_cast<int32_t>(mItems.size()));

    for (const Item &item : mItems) {
        parcel->writeCString(item.mName);
        parcel->writeInt32(static_cast<int32_t>(item.mType));

@@ -828,8 +840,7 @@ sp<AMessage> AMessage::changesFrom(const sp<const AMessage> &other, bool deep) c
        diff->setTarget(mHandler.promote());
    }

    for (size_t i = 0; i < mNumItems; ++i) {
        const Item &item = mItems[i];
    for (const Item &item : mItems) {
        const Item *oitem = other->findItem(item.mName, item.mType);
        switch (item.mType) {
            case kTypeInt32:
@@ -936,11 +947,11 @@ sp<AMessage> AMessage::changesFrom(const sp<const AMessage> &other, bool deep) c
}

size_t AMessage::countEntries() const {
    return mNumItems;
    return mItems.size();
}

const char *AMessage::getEntryNameAt(size_t index, Type *type) const {
    if (index >= mNumItems) {
    if (index >= mItems.size()) {
        *type = kTypeInt32;

        return NULL;
@@ -953,7 +964,7 @@ const char *AMessage::getEntryNameAt(size_t index, Type *type) const {

AMessage::ItemData AMessage::getEntryAt(size_t index) const {
    ItemData it;
    if (index < mNumItems) {
    if (index < mItems.size()) {
        switch (mItems[index].mType) {
            case kTypeInt32:    it.set(mItems[index].u.int32Value); break;
            case kTypeInt64:    it.set(mItems[index].u.int64Value); break;
@@ -986,7 +997,7 @@ AMessage::ItemData AMessage::getEntryAt(size_t index) const {
}

status_t AMessage::setEntryNameAt(size_t index, const char *name) {
    if (index >= mNumItems) {
    if (index >= mItems.size()) {
        return BAD_INDEX;
    }
    if (name == nullptr) {
@@ -996,7 +1007,7 @@ status_t AMessage::setEntryNameAt(size_t index, const char *name) {
        return OK; // name has not changed
    }
    size_t len = strlen(name);
    if (findItemIndex(name, len) < mNumItems) {
    if (findItemIndex(name, len) < mItems.size()) {
        return ALREADY_EXISTS;
    }
    delete[] mItems[index].mName;
@@ -1011,7 +1022,7 @@ status_t AMessage::setEntryAt(size_t index, const ItemData &item) {
    sp<AMessage> msgValue;
    sp<ABuffer> bufValue;

    if (index >= mNumItems) {
    if (index >= mItems.size()) {
        return BAD_INDEX;
    }
    if (!item.used()) {
@@ -1060,21 +1071,22 @@ status_t AMessage::setEntryAt(size_t index, const ItemData &item) {
}

status_t AMessage::removeEntryAt(size_t index) {
    if (index >= mNumItems) {
    if (index >= mItems.size()) {
        return BAD_INDEX;
    }
    // delete entry data and objects
    --mNumItems;
    delete[] mItems[index].mName;
    mItems[index].mName = nullptr;
    freeItemValue(&mItems[index]);

    // swap entry with last entry and clear last entry's data
    if (index < mNumItems) {
        mItems[index] = mItems[mNumItems];
        mItems[mNumItems].mName = nullptr;
        mItems[mNumItems].mType = kTypeInt32;
    size_t lastIndex = mItems.size() - 1;
    if (index < lastIndex) {
        mItems[index] = mItems[lastIndex];
        mItems[lastIndex].mName = nullptr;
        mItems[lastIndex].mType = kTypeInt32;
    }
    mItems.pop_back();
    return OK;
}

@@ -1083,7 +1095,7 @@ status_t AMessage::removeEntryByName(const char *name) {
        return BAD_VALUE;
    }
    size_t index = findEntryByName(name);
    if (index >= mNumItems) {
    if (index >= mItems.size()) {
        return BAD_INDEX;
    }
    return removeEntryAt(index);
@@ -1093,7 +1105,7 @@ void AMessage::setItem(const char *name, const ItemData &item) {
    if (item.used()) {
        Item *it = allocateItem(name);
        if (it != nullptr) {
            setEntryAt(it - mItems, item);
            setEntryAt(it - &mItems[0], item);
        }
    }
}
@@ -1108,11 +1120,11 @@ void AMessage::extend(const sp<AMessage> &other) {
        return;
    }

    for (size_t ix = 0; ix < other->mNumItems; ++ix) {
    for (size_t ix = 0; ix < other->mItems.size(); ++ix) {
        Item *it = allocateItem(other->mItems[ix].mName);
        if (it != nullptr) {
            ItemData data = other->getEntryAt(ix);
            setEntryAt(it - mItems, data);
            setEntryAt(it - &mItems[0], data);
        }
    }
}
+29 −3
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>

#include <vector>

namespace android {

struct ABuffer;
@@ -95,6 +97,7 @@ struct AMessage : public RefBase {

    void setTarget(const sp<const AHandler> &handler);

    // removes all items
    void clear();

    void setInt32(const char *name, int32_t value);
@@ -302,16 +305,39 @@ private:
        size_t      mNameLength;
        Type mType;
        void setName(const char *name, size_t len);
        Item() : mName(nullptr), mNameLength(0), mType(kTypeInt32) { }
        Item(const char *name, size_t length);
    };

    enum {
        kMaxNumItems = 64
        kMaxNumItems = 256
    };
    Item mItems[kMaxNumItems];
    size_t mNumItems;
    std::vector<Item> mItems;

    /**
     * Allocates an item with the given key |name|. If the key already exists, the corresponding
     * item value is freed. Otherwise a new item is added.
     *
     * This method currently asserts if the number of elements would exceed the max number of
     * elements allowed (kMaxNumItems). This is a security precaution to avoid arbitrarily large
     * AMessage structures.
     *
     * @todo(b/192153245) Either revisit this security precaution, or change the behavior to
     *      silently ignore keys added after the max number of elements are reached.
     *
     * @note All previously returned Item* pointers are deemed invalid after this call. (E.g. from
     *       allocateItem or findItem)
     *
     * @param name the key for the requested item.
     *
     * @return Item* a pointer to the item.
     */
    Item *allocateItem(const char *name);

    /** Frees the value for the item. */
    void freeItemValue(Item *item);

    /** Finds an item with given key |name| and |type|. Returns nullptr if item is not found. */
    const Item *findItem(const char *name, Type type) const;

    void setObjectInternal(