From c6aada9c5789b2777b19c522d3cd5052bbe784a4 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 13 Jan 2017 15:34:14 -0800 Subject: LoadedArsc: Support feature splits. Test: make libandroidfw_tests Change-Id: I278273e688da597f4af86dd55f87750501ef8154 --- libs/androidfw/LoadedArsc.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'libs/androidfw/LoadedArsc.cpp') diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index e17a3a6ff0a1..c7d0fa5b0cf3 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -116,7 +116,10 @@ bool LoadedPackage::FindEntry(uint8_t type_idx, uint16_t entry_idx, const ResTab LoadedArscEntry* out_entry, ResTable_config* out_selected_config, uint32_t* out_flags) const { ATRACE_CALL(); - const TypeSpecPtr& ptr = type_specs_[type_idx]; + + // If the type IDs are offset in this package, we need to take that into account when searching + // for a type. + const TypeSpecPtr& ptr = type_specs_[type_idx - type_id_offset_]; if (ptr == nullptr) { return false; } @@ -334,6 +337,15 @@ std::unique_ptr LoadedPackage::Load(const Chunk& chunk) { loaded_package->dynamic_ = true; } + if (header->header.headerSize >= sizeof(ResTable_package)) { + uint32_t type_id_offset = dtohl(header->typeIdOffset); + if (type_id_offset > std::numeric_limits::max()) { + LOG(ERROR) << "Type ID offset in RES_TABLE_PACKAGE_TYPE is too large."; + return {}; + } + loaded_package->type_id_offset_ = static_cast(type_id_offset); + } + util::ReadUtf16StringFromDevice(header->name, arraysize(header->name), &loaded_package->package_name_); @@ -385,7 +397,6 @@ std::unique_ptr LoadedPackage::Load(const Chunk& chunk) { LOG(ERROR) << "Too many type configurations, overflow detected."; return {}; } - loaded_package->type_specs_.editItemAt(last_type_idx) = std::move(type_spec_ptr); types_builder = {}; @@ -403,6 +414,12 @@ std::unique_ptr LoadedPackage::Load(const Chunk& chunk) { return {}; } + if (loaded_package->type_id_offset_ + static_cast(type_spec->id) > + std::numeric_limits::max()) { + LOG(ERROR) << "Chunk RES_TABLE_TYPE_SPEC_TYPE has out of range ID."; + return {}; + } + // The data portion of this chunk contains entry_count 32bit entries, // each one representing a set of flags. // Here we only validate that the chunk is well formed. -- cgit v1.2.3-59-g8ed1b