diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 76fe807320ec9..5aded246522fb 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -4333,7 +4333,8 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui const uint32_t pkg_id = pkg->package->id << 24; for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) { - ssize_t offset = -1; + ssize_t first = -1; + ssize_t last = -1; const Type* typeConfigs = pkg->getType(typeIndex); ssize_t mapIndex = map.add(); if (mapIndex < 0) { @@ -4347,6 +4348,8 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui resource_name resName; if (!this->getResourceName(resID, &resName)) { ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID); + // add dummy value, or trimming leading/trailing zeroes later will fail + vector.push(0); continue; } @@ -4360,11 +4363,12 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui overlayPackage.size()); if (overlayResID != 0) { overlayResID = pkg_id | (0x00ffffff & overlayResID); + last = Res_GETENTRY(resID); + if (first == -1) { + first = Res_GETENTRY(resID); + } } vector.push(overlayResID); - if (overlayResID != 0 && offset == -1) { - offset = Res_GETENTRY(resID); - } #if 0 if (overlayResID != 0) { ALOGD("%s/%s 0x%08x -> 0x%08x\n", @@ -4375,13 +4379,16 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui #endif } - if (offset != -1) { - // shave off leading and trailing entries which lack overlay values - vector.removeItemsAt(0, offset); - vector.insertAt((uint32_t)offset, 0, 1); - while (vector.top() == 0) { - vector.pop(); + if (first != -1) { + // shave off trailing entries which lack overlay values + const size_t last_past_one = last + 1; + if (last_past_one < vector.size()) { + vector.removeItemsAt(last_past_one, vector.size() - last_past_one); } + // shave off leading entries which lack overlay values + vector.removeItemsAt(0, first); + // store offset to first overlaid resource ID of this type + vector.insertAt((uint32_t)first, 0, 1); // reserve space for number and offset of entries, and the actual entries *outSize += (2 + vector.size()) * sizeof(uint32_t); } else { @@ -4419,6 +4426,10 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui if (N == 0) { continue; } + if (N == 1) { // vector expected to hold (offset) + (N > 0 entries) + ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i); + return UNKNOWN_ERROR; + } *data++ = htodl(N - 1); // do not count the offset (which is vector's first element) for (size_t j = 0; j < N; ++j) { const uint32_t& overlayResID = vector.itemAt(j); diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 20e221d0ed5af..770b02797cecd 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -2661,6 +2661,12 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) const bool filterable = (typeName != mipmap16); const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; + + // Until a non-NO_ENTRY value has been written for a resource, + // that resource is invalid; validResources[i] represents + // the item at t->getOrderedConfigs().itemAt(i). + Vector validResources; + validResources.insertAt(false, 0, N); // First write the typeSpec chunk, containing information about // each resource entry in this type. @@ -2797,6 +2803,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) if (amt < 0) { return amt; } + validResources.editItemAt(ei) = true; } else { index[ei] = htodl(ResTable_type::NO_ENTRY); } @@ -2807,6 +2814,14 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) (((uint8_t*)data->editData()) + typeStart); tHeader->header.size = htodl(data->getSize()-typeStart); } + + for (size_t i = 0; i < N; ++i) { + if (!validResources[i]) { + sp c = t->getOrderedConfigs().itemAt(i); + fprintf(stderr, "warning: no entries written for %s/%s\n", + String8(typeName).string(), String8(c->getName()).string()); + } + } } // Fill in the rest of the package information.