diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2020-10-19 17:57:33 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-10-19 17:57:33 +0000 |
commit | 72864d29300adb65c1b677a676ab96de9440d1b0 (patch) | |
tree | 715f9c7a9dbf1ad9aaf806cf1202a829fafc61fa /libs/androidfw/Idmap.cpp | |
parent | b3230cd639be832c1650e419d5b91aef9f94a324 (diff) | |
parent | 70e02d428565b1cb9882ad2aa04ba7636fa3f099 (diff) |
Merge changes I1d3e5e66,I86b869af,Iab4d3902,I645ee722
* changes:
Fix <overlay-config-signature> comments
Fix non-inclusive OMS test language
Remove malloc/free for inline overlay values
OMS: Add config_signature policy handling
Diffstat (limited to 'libs/androidfw/Idmap.cpp')
-rw-r--r-- | libs/androidfw/Idmap.cpp | 121 |
1 files changed, 69 insertions, 52 deletions
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp index 5f231ffe4786..4e03ce5d9584 100644 --- a/libs/androidfw/Idmap.cpp +++ b/libs/androidfw/Idmap.cpp @@ -36,16 +36,12 @@ using ::android::base::StringPrintf; namespace android { -static bool compare_target_entries(const Idmap_target_entry &e1, const uint32_t target_id) { - return dtohl(e1.target_id) < target_id; -} - -static bool compare_overlay_entries(const Idmap_overlay_entry& e1, const uint32_t overlay_id) { - return dtohl(e1.overlay_id) < overlay_id; +uint32_t round_to_4_bytes(uint32_t size) { + return size + (4U - (size % 4U)) % 4U; } size_t Idmap_header::Size() const { - return sizeof(Idmap_header) + sizeof(uint8_t) * dtohl(debug_info_size); + return sizeof(Idmap_header) + sizeof(uint8_t) * round_to_4_bytes(dtohl(debug_info_size)); } OverlayStringPool::OverlayStringPool(const LoadedIdmap* loaded_idmap) @@ -88,7 +84,10 @@ OverlayDynamicRefTable::OverlayDynamicRefTable(const Idmap_data_header* data_hea status_t OverlayDynamicRefTable::lookupResourceId(uint32_t* resId) const { const Idmap_overlay_entry* first_entry = entries_; const Idmap_overlay_entry* end_entry = entries_ + dtohl(data_header_->overlay_entry_count); - auto entry = std::lower_bound(first_entry, end_entry, *resId, compare_overlay_entries); + auto entry = std::lower_bound(first_entry, end_entry, *resId, + [](const Idmap_overlay_entry& e1, const uint32_t overlay_id) { + return dtohl(e1.overlay_id) < overlay_id; + }); if (entry == end_entry || dtohl(entry->overlay_id) != *resId) { // A mapping for the target resource id could not be found. @@ -96,7 +95,7 @@ status_t OverlayDynamicRefTable::lookupResourceId(uint32_t* resId) const { } *resId = (0x00FFFFFFU & dtohl(entry->target_id)) - | (((uint32_t) target_assigned_package_id_) << 24); + | (((uint32_t) target_assigned_package_id_) << 24U); return NO_ERROR; } @@ -106,62 +105,58 @@ status_t OverlayDynamicRefTable::lookupResourceIdNoRewrite(uint32_t* resId) cons IdmapResMap::IdmapResMap(const Idmap_data_header* data_header, const Idmap_target_entry* entries, + const Idmap_target_entry_inline* inline_entries, uint8_t target_assigned_package_id, const OverlayDynamicRefTable* overlay_ref_table) : data_header_(data_header), entries_(entries), + inline_entries_(inline_entries), target_assigned_package_id_(target_assigned_package_id), - overlay_ref_table_(overlay_ref_table) { }; + overlay_ref_table_(overlay_ref_table) { } IdmapResMap::Result IdmapResMap::Lookup(uint32_t target_res_id) const { - if ((target_res_id >> 24) != target_assigned_package_id_) { + if ((target_res_id >> 24U) != target_assigned_package_id_) { // The resource id must have the same package id as the target package. return {}; } // The resource ids encoded within the idmap are build-time resource ids. target_res_id = (0x00FFFFFFU & target_res_id) - | (((uint32_t) data_header_->target_package_id) << 24); - - const Idmap_target_entry* first_entry = entries_; - const Idmap_target_entry* end_entry = entries_ + dtohl(data_header_->target_entry_count); - auto entry = std::lower_bound(first_entry, end_entry, target_res_id, compare_target_entries); - - if (entry == end_entry || dtohl(entry->target_id) != target_res_id) { - // A mapping for the target resource id could not be found. - return {}; - } - - // A reference should be treated as an alias of the resource. Instead of returning the table - // entry, return the alias resource id to look up. The alias resource might not reside within the - // overlay package, so the resource id must be fixed with the dynamic reference table of the - // overlay before returning. - if (entry->type == Res_value::TYPE_REFERENCE - || entry->type == Res_value::TYPE_DYNAMIC_REFERENCE) { - uint32_t overlay_resource_id = dtohl(entry->value); - + | (((uint32_t) data_header_->target_package_id) << 24U); + + // Check if the target resource is mapped to an overlay resource. + auto first_entry = entries_; + auto end_entry = entries_ + dtohl(data_header_->target_entry_count); + auto entry = std::lower_bound(first_entry, end_entry, target_res_id, + [](const Idmap_target_entry &e, const uint32_t target_id) { + return dtohl(e.target_id) < target_id; + }); + + if (entry != end_entry && dtohl(entry->target_id) == target_res_id) { + uint32_t overlay_resource_id = dtohl(entry->overlay_id); // Lookup the resource without rewriting the overlay resource id back to the target resource id // being looked up. overlay_ref_table_->lookupResourceIdNoRewrite(&overlay_resource_id); return Result(overlay_resource_id); } - // Copy the type and value into the ResTable_entry structure needed by asset manager. - uint16_t malloc_size = sizeof(ResTable_entry) + sizeof(Res_value); - auto table_entry = reinterpret_cast<ResTable_entry*>(malloc(malloc_size)); - memset(table_entry, 0, malloc_size); - table_entry->size = htods(sizeof(ResTable_entry)); - - auto table_value = reinterpret_cast<Res_value*>(reinterpret_cast<uint8_t*>(table_entry) - + sizeof(ResTable_entry)); - table_value->dataType = entry->type; - table_value->data = entry->value; - - return Result(ResTable_entry_handle::managed(table_entry, [](auto p) { free(p); })); + // Check if the target resources is mapped to an inline table entry. + auto first_inline_entry = inline_entries_; + auto end_inline_entry = inline_entries_ + dtohl(data_header_->target_inline_entry_count); + auto inline_entry = std::lower_bound(first_inline_entry, end_inline_entry, target_res_id, + [](const Idmap_target_entry_inline &e, + const uint32_t target_id) { + return dtohl(e.target_id) < target_id; + }); + + if (inline_entry != end_inline_entry && dtohl(inline_entry->target_id) == target_res_id) { + return Result(inline_entry->value); + } + return {}; } static bool is_word_aligned(const void* data) { - return (reinterpret_cast<uintptr_t>(data) & 0x03) == 0; + return (reinterpret_cast<uintptr_t>(data) & 0x03U) == 0U; } static bool IsValidIdmapHeader(const StringPiece& data) { @@ -175,7 +170,7 @@ static bool IsValidIdmapHeader(const StringPiece& data) { return false; } - const Idmap_header* header = reinterpret_cast<const Idmap_header*>(data.data()); + auto header = reinterpret_cast<const Idmap_header*>(data.data()); if (dtohl(header->magic) != kIdmapMagic) { LOG(ERROR) << StringPrintf("Invalid Idmap file: bad magic value (was 0x%08x, expected 0x%08x)", dtohl(header->magic), kIdmapMagic); @@ -198,11 +193,13 @@ LoadedIdmap::LoadedIdmap(std::string&& idmap_path, const Idmap_header* header, const Idmap_data_header* data_header, const Idmap_target_entry* target_entries, + const Idmap_target_entry_inline* target_inline_entries, const Idmap_overlay_entry* overlay_entries, ResStringPool* string_pool) : header_(header), data_header_(data_header), target_entries_(target_entries), + target_inline_entries_(target_inline_entries), overlay_entries_(overlay_entries), string_pool_(string_pool), idmap_path_(std::move(idmap_path)), @@ -233,7 +230,7 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa data_ptr += sizeof(*data_header); data_size -= sizeof(*data_header); - // Make sure there is enough space for the target entries declared in the header. + // Make sure there is enough space for the target entries declared in the header const auto target_entries = reinterpret_cast<const Idmap_target_entry*>(data_ptr); if (data_size / sizeof(Idmap_target_entry) < static_cast<size_t>(dtohl(data_header->target_entry_count))) { @@ -248,6 +245,21 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa data_ptr += target_entry_size_bytes; data_size -= target_entry_size_bytes; + // Make sure there is enough space for the target entries declared in the header. + const auto target_inline_entries = reinterpret_cast<const Idmap_target_entry_inline*>(data_ptr); + if (data_size / sizeof(Idmap_target_entry_inline) < + static_cast<size_t>(dtohl(data_header->target_inline_entry_count))) { + LOG(ERROR) << StringPrintf("Idmap too small for the number of target inline entries (%d)", + (int)dtohl(data_header->target_inline_entry_count)); + return {}; + } + + // Advance the data pointer past the target entries. + const size_t target_inline_entry_size_bytes = + (dtohl(data_header->target_inline_entry_count) * sizeof(Idmap_target_entry_inline)); + data_ptr += target_inline_entry_size_bytes; + data_size -= target_inline_entry_size_bytes; + // Make sure there is enough space for the overlay entries declared in the header. const auto overlay_entries = reinterpret_cast<const Idmap_overlay_entry*>(data_ptr); if (data_size / sizeof(Idmap_overlay_entry) < @@ -257,22 +269,26 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa return {}; } - // Advance the data pointer past the target entries. + // Advance the data pointer past the overlay entries. const size_t overlay_entry_size_bytes = (dtohl(data_header->overlay_entry_count) * sizeof(Idmap_overlay_entry)); data_ptr += overlay_entry_size_bytes; data_size -= overlay_entry_size_bytes; // Read the idmap string pool that holds the value of inline string entries. - if (data_size < dtohl(data_header->string_pool_length)) { + uint32_t string_pool_size = dtohl(*reinterpret_cast<const uint32_t*>(data_ptr)); + data_ptr += sizeof(uint32_t); + data_size -= sizeof(uint32_t); + + if (data_size < string_pool_size) { LOG(ERROR) << StringPrintf("Idmap too small for string pool (length %d)", - (int)dtohl(data_header->string_pool_length)); + (int)string_pool_size); return {}; } auto idmap_string_pool = util::make_unique<ResStringPool>(); - if (dtohl(data_header->string_pool_length) > 0) { - status_t err = idmap_string_pool->setTo(data_ptr, dtohl(data_header->string_pool_length)); + if (string_pool_size > 0) { + status_t err = idmap_string_pool->setTo(data_ptr, string_pool_size); if (err != NO_ERROR) { LOG(ERROR) << "idmap string pool corrupt."; return {}; @@ -280,9 +296,10 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa } // Can't use make_unique because LoadedIdmap constructor is private. - std::unique_ptr<LoadedIdmap> loaded_idmap = std::unique_ptr<LoadedIdmap>( + auto loaded_idmap = std::unique_ptr<LoadedIdmap>( new LoadedIdmap(idmap_path.to_string(), getFileModDate(idmap_path.data()), header, - data_header, target_entries, overlay_entries, idmap_string_pool.release())); + data_header, target_entries, target_inline_entries, overlay_entries, + idmap_string_pool.release())); return std::move(loaded_idmap); } |