diff options
Diffstat (limited to 'libs/androidfw/LoadedArsc.cpp')
-rw-r--r-- | libs/androidfw/LoadedArsc.cpp | 339 |
1 files changed, 142 insertions, 197 deletions
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index 2fc3b05011c2..70bb441f94cb 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -38,7 +38,7 @@ #include "androidfw/ResourceUtils.h" #include "androidfw/Util.h" -using android::base::StringPrintf; +using ::android::base::StringPrintf; namespace android { @@ -51,17 +51,17 @@ namespace { // the Type structs. class TypeSpecPtrBuilder { public: - explicit TypeSpecPtrBuilder(incfs::verified_map_ptr<ResTable_typeSpec> header) + explicit TypeSpecPtrBuilder(const ResTable_typeSpec* header) : header_(header) { } - void AddType(incfs::verified_map_ptr<ResTable_type> type) { + void AddType(const ResTable_type* type) { types_.push_back(type); } TypeSpecPtr Build() { // Check for overflow. - using ElementType = incfs::verified_map_ptr<ResTable_type>; + using ElementType = const ResTable_type*; if ((std::numeric_limits<size_t>::max() - sizeof(TypeSpec)) / sizeof(ElementType) < types_.size()) { return {}; @@ -77,8 +77,8 @@ class TypeSpecPtrBuilder { private: DISALLOW_COPY_AND_ASSIGN(TypeSpecPtrBuilder); - incfs::verified_map_ptr<ResTable_typeSpec> header_; - std::vector<incfs::verified_map_ptr<ResTable_type>> types_; + const ResTable_typeSpec* header_; + std::vector<const ResTable_type*> types_; }; } // namespace @@ -88,7 +88,7 @@ LoadedPackage::~LoadedPackage() = default; // Precondition: The header passed in has already been verified, so reading any fields and trusting // the ResChunk_header is safe. -static bool VerifyResTableType(incfs::map_ptr<ResTable_type> header) { +static bool VerifyResTableType(const ResTable_type* header) { if (header->id == 0) { LOG(ERROR) << "RES_TABLE_TYPE_TYPE has invalid ID 0."; return false; @@ -115,99 +115,89 @@ static bool VerifyResTableType(incfs::map_ptr<ResTable_type> header) { return false; } - if (entries_offset & 0x03U) { + if (entries_offset & 0x03) { LOG(ERROR) << "RES_TABLE_TYPE_TYPE entries start at unaligned address."; return false; } return true; } -static base::expected<std::monostate, NullOrIOError> VerifyResTableEntry( - incfs::verified_map_ptr<ResTable_type> type, uint32_t entry_offset) { +static bool VerifyResTableEntry(const ResTable_type* type, uint32_t entry_offset) { // Check that the offset is aligned. - if (UNLIKELY(entry_offset & 0x03U)) { + if (entry_offset & 0x03) { LOG(ERROR) << "Entry at offset " << entry_offset << " is not 4-byte aligned."; - return base::unexpected(std::nullopt); + return false; } // Check that the offset doesn't overflow. - if (UNLIKELY(entry_offset > std::numeric_limits<uint32_t>::max() - dtohl(type->entriesStart))) { + if (entry_offset > std::numeric_limits<uint32_t>::max() - dtohl(type->entriesStart)) { // Overflow in offset. LOG(ERROR) << "Entry at offset " << entry_offset << " is too large."; - return base::unexpected(std::nullopt); + return false; } const size_t chunk_size = dtohl(type->header.size); entry_offset += dtohl(type->entriesStart); - if (UNLIKELY(entry_offset > chunk_size - sizeof(ResTable_entry))) { + if (entry_offset > chunk_size - sizeof(ResTable_entry)) { LOG(ERROR) << "Entry at offset " << entry_offset << " is too large. No room for ResTable_entry."; - return base::unexpected(std::nullopt); + return false; } - auto entry = type.offset(entry_offset).convert<ResTable_entry>(); - if (UNLIKELY(!entry)) { - return base::unexpected(IOError::PAGES_MISSING); - } + const ResTable_entry* entry = reinterpret_cast<const ResTable_entry*>( + reinterpret_cast<const uint8_t*>(type) + entry_offset); const size_t entry_size = dtohs(entry->size); - if (UNLIKELY(entry_size < sizeof(entry.value()))) { + if (entry_size < sizeof(*entry)) { LOG(ERROR) << "ResTable_entry size " << entry_size << " at offset " << entry_offset << " is too small."; - return base::unexpected(std::nullopt); + return false; } - if (UNLIKELY(entry_size > chunk_size || entry_offset > chunk_size - entry_size)) { + if (entry_size > chunk_size || entry_offset > chunk_size - entry_size) { LOG(ERROR) << "ResTable_entry size " << entry_size << " at offset " << entry_offset << " is too large."; - return base::unexpected(std::nullopt); + return false; } if (entry_size < sizeof(ResTable_map_entry)) { // There needs to be room for one Res_value struct. - if (UNLIKELY(entry_offset + entry_size > chunk_size - sizeof(Res_value))) { + if (entry_offset + entry_size > chunk_size - sizeof(Res_value)) { LOG(ERROR) << "No room for Res_value after ResTable_entry at offset " << entry_offset << " for type " << (int)type->id << "."; - return base::unexpected(std::nullopt); - } - - auto value = entry.offset(entry_size).convert<Res_value>(); - if (UNLIKELY(!value)) { - return base::unexpected(IOError::PAGES_MISSING); + return false; } + const Res_value* value = + reinterpret_cast<const Res_value*>(reinterpret_cast<const uint8_t*>(entry) + entry_size); const size_t value_size = dtohs(value->size); - if (UNLIKELY(value_size < sizeof(Res_value))) { + if (value_size < sizeof(Res_value)) { LOG(ERROR) << "Res_value at offset " << entry_offset << " is too small."; - return base::unexpected(std::nullopt); + return false; } - if (UNLIKELY(value_size > chunk_size || entry_offset + entry_size > chunk_size - value_size)) { + if (value_size > chunk_size || entry_offset + entry_size > chunk_size - value_size) { LOG(ERROR) << "Res_value size " << value_size << " at offset " << entry_offset << " is too large."; - return base::unexpected(std::nullopt); + return false; } } else { - auto map = entry.convert<ResTable_map_entry>(); - if (UNLIKELY(!map)) { - return base::unexpected(IOError::PAGES_MISSING); - } - + const ResTable_map_entry* map = reinterpret_cast<const ResTable_map_entry*>(entry); const size_t map_entry_count = dtohl(map->count); size_t map_entries_start = entry_offset + entry_size; - if (UNLIKELY(map_entries_start & 0x03U)) { + if (map_entries_start & 0x03) { LOG(ERROR) << "Map entries at offset " << entry_offset << " start at unaligned offset."; - return base::unexpected(std::nullopt); + return false; } // Each entry is sizeof(ResTable_map) big. - if (UNLIKELY(map_entry_count > ((chunk_size - map_entries_start) / sizeof(ResTable_map)))) { + if (map_entry_count > ((chunk_size - map_entries_start) / sizeof(ResTable_map))) { LOG(ERROR) << "Too many map entries in ResTable_map_entry at offset " << entry_offset << "."; - return base::unexpected(std::nullopt); + return false; } } - return {}; + return true; } LoadedPackage::iterator::iterator(const LoadedPackage* lp, size_t ti, size_t ei) @@ -243,125 +233,99 @@ uint32_t LoadedPackage::iterator::operator*() const { entryIndex_); } -base::expected<incfs::map_ptr<ResTable_entry>, NullOrIOError> LoadedPackage::GetEntry( - incfs::verified_map_ptr<ResTable_type> type_chunk, uint16_t entry_index) { - base::expected<uint32_t, NullOrIOError> entry_offset = GetEntryOffset(type_chunk, entry_index); - if (UNLIKELY(!entry_offset.has_value())) { - return base::unexpected(entry_offset.error()); +const ResTable_entry* LoadedPackage::GetEntry(const ResTable_type* type_chunk, + uint16_t entry_index) { + uint32_t entry_offset = GetEntryOffset(type_chunk, entry_index); + if (entry_offset == ResTable_type::NO_ENTRY) { + return nullptr; } - return GetEntryFromOffset(type_chunk, entry_offset.value()); + return GetEntryFromOffset(type_chunk, entry_offset); } -base::expected<uint32_t, NullOrIOError> LoadedPackage::GetEntryOffset( - incfs::verified_map_ptr<ResTable_type> type_chunk, uint16_t entry_index) { +uint32_t LoadedPackage::GetEntryOffset(const ResTable_type* type_chunk, uint16_t entry_index) { // The configuration matches and is better than the previous selection. // Find the entry value if it exists for this configuration. const size_t entry_count = dtohl(type_chunk->entryCount); const size_t offsets_offset = dtohs(type_chunk->header.headerSize); // Check if there is the desired entry in this type. + if (type_chunk->flags & ResTable_type::FLAG_SPARSE) { // This is encoded as a sparse map, so perform a binary search. - bool error = false; - auto sparse_indices = type_chunk.offset(offsets_offset) - .convert<ResTable_sparseTypeEntry>().iterator(); - auto sparse_indices_end = sparse_indices + entry_count; - auto result = std::lower_bound(sparse_indices, sparse_indices_end, entry_index, - [&error](const incfs::map_ptr<ResTable_sparseTypeEntry>& entry, - uint16_t entry_idx) { - if (UNLIKELY(!entry)) { - return error = true; - } - return dtohs(entry->idx) < entry_idx; - }); - - if (result == sparse_indices_end) { + const ResTable_sparseTypeEntry* sparse_indices = + reinterpret_cast<const ResTable_sparseTypeEntry*>( + reinterpret_cast<const uint8_t*>(type_chunk) + offsets_offset); + const ResTable_sparseTypeEntry* sparse_indices_end = sparse_indices + entry_count; + const ResTable_sparseTypeEntry* result = + std::lower_bound(sparse_indices, sparse_indices_end, entry_index, + [](const ResTable_sparseTypeEntry& entry, uint16_t entry_idx) { + return dtohs(entry.idx) < entry_idx; + }); + + if (result == sparse_indices_end || dtohs(result->idx) != entry_index) { // No entry found. - return base::unexpected(std::nullopt); - } - - const incfs::verified_map_ptr<ResTable_sparseTypeEntry> entry = (*result).verified(); - if (dtohs(entry->idx) != entry_index) { - if (error) { - return base::unexpected(IOError::PAGES_MISSING); - } - return base::unexpected(std::nullopt); + return ResTable_type::NO_ENTRY; } // Extract the offset from the entry. Each offset must be a multiple of 4 so we store it as // the real offset divided by 4. - return uint32_t{dtohs(entry->offset)} * 4u; + return uint32_t{dtohs(result->offset)} * 4u; } // This type is encoded as a dense array. if (entry_index >= entry_count) { // This entry cannot be here. - return base::unexpected(std::nullopt); + return ResTable_type::NO_ENTRY; } - const auto entry_offset_ptr = type_chunk.offset(offsets_offset).convert<uint32_t>() + entry_index; - if (UNLIKELY(!entry_offset_ptr)) { - return base::unexpected(IOError::PAGES_MISSING); - } - - const uint32_t value = dtohl(entry_offset_ptr.value()); - if (value == ResTable_type::NO_ENTRY) { - return base::unexpected(std::nullopt); - } - - return value; + const uint32_t* entry_offsets = reinterpret_cast<const uint32_t*>( + reinterpret_cast<const uint8_t*>(type_chunk) + offsets_offset); + return dtohl(entry_offsets[entry_index]); } -base::expected<incfs::map_ptr<ResTable_entry>, NullOrIOError> LoadedPackage::GetEntryFromOffset( - incfs::verified_map_ptr<ResTable_type> type_chunk, uint32_t offset) { - auto valid = VerifyResTableEntry(type_chunk, offset); - if (UNLIKELY(!valid.has_value())) { - return base::unexpected(valid.error()); +const ResTable_entry* LoadedPackage::GetEntryFromOffset(const ResTable_type* type_chunk, + uint32_t offset) { + if (UNLIKELY(!VerifyResTableEntry(type_chunk, offset))) { + return nullptr; } - return type_chunk.offset(offset + dtohl(type_chunk->entriesStart)).convert<ResTable_entry>(); + return reinterpret_cast<const ResTable_entry*>(reinterpret_cast<const uint8_t*>(type_chunk) + + offset + dtohl(type_chunk->entriesStart)); } -base::expected<std::monostate, IOError> LoadedPackage::CollectConfigurations( - bool exclude_mipmap, std::set<ResTable_config>* out_configs) const { +void LoadedPackage::CollectConfigurations(bool exclude_mipmap, + std::set<ResTable_config>* out_configs) const { + const static std::u16string kMipMap = u"mipmap"; const size_t type_count = type_specs_.size(); for (size_t i = 0; i < type_count; i++) { const TypeSpecPtr& type_spec = type_specs_[i]; - if (type_spec == nullptr) { - continue; - } - if (exclude_mipmap) { - const int type_idx = type_spec->type_spec->id - 1; - const auto type_name16 = type_string_pool_.stringAt(type_idx); - if (UNLIKELY(IsIOError(type_name16))) { - return base::unexpected(GetIOError(type_name16.error())); - } - if (type_name16.has_value()) { - if (strncmp16(type_name16->data(), u"mipmap", type_name16->size()) == 0) { - // This is a mipmap type, skip collection. - continue; + if (type_spec != nullptr) { + if (exclude_mipmap) { + const int type_idx = type_spec->type_spec->id - 1; + size_t type_name_len; + const char16_t* type_name16 = type_string_pool_.stringAt(type_idx, &type_name_len); + if (type_name16 != nullptr) { + if (kMipMap.compare(0, std::u16string::npos, type_name16, type_name_len) == 0) { + // This is a mipmap type, skip collection. + continue; + } } - } - - const auto type_name = type_string_pool_.string8At(type_idx); - if (UNLIKELY(IsIOError(type_name))) { - return base::unexpected(GetIOError(type_name.error())); - } - if (type_name.has_value()) { - if (strncmp(type_name->data(), "mipmap", type_name->size()) == 0) { - // This is a mipmap type, skip collection. - continue; + const char* type_name = type_string_pool_.string8At(type_idx, &type_name_len); + if (type_name != nullptr) { + if (strncmp(type_name, "mipmap", type_name_len) == 0) { + // This is a mipmap type, skip collection. + continue; + } } } - } - const auto iter_end = type_spec->types + type_spec->type_count; - for (auto iter = type_spec->types; iter != iter_end; ++iter) { - ResTable_config config; - config.copyFromDtoH((*iter)->config); - out_configs->insert(config); + const auto iter_end = type_spec->types + type_spec->type_count; + for (auto iter = type_spec->types; iter != iter_end; ++iter) { + ResTable_config config; + config.copyFromDtoH((*iter)->config); + out_configs->insert(config); + } } } - return {}; } void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const { @@ -384,53 +348,43 @@ void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out } } -base::expected<uint32_t, NullOrIOError> LoadedPackage::FindEntryByName( - const std::u16string& type_name, const std::u16string& entry_name) const { - const base::expected<size_t, NullOrIOError> type_idx = type_string_pool_.indexOfString( - type_name.data(), type_name.size()); - if (!type_idx.has_value()) { - return base::unexpected(type_idx.error()); +uint32_t LoadedPackage::FindEntryByName(const std::u16string& type_name, + const std::u16string& entry_name) const { + ssize_t type_idx = type_string_pool_.indexOfString(type_name.data(), type_name.size()); + if (type_idx < 0) { + return 0u; } - const base::expected<size_t, NullOrIOError> key_idx = key_string_pool_.indexOfString( - entry_name.data(), entry_name.size()); - if (!key_idx.has_value()) { - return base::unexpected(key_idx.error()); + ssize_t key_idx = key_string_pool_.indexOfString(entry_name.data(), entry_name.size()); + if (key_idx < 0) { + return 0u; } - const TypeSpec* type_spec = type_specs_[*type_idx].get(); + const TypeSpec* type_spec = type_specs_[type_idx].get(); if (type_spec == nullptr) { - return base::unexpected(std::nullopt); + return 0u; } const auto iter_end = type_spec->types + type_spec->type_count; for (auto iter = type_spec->types; iter != iter_end; ++iter) { - const incfs::verified_map_ptr<ResTable_type>& type = *iter; - + const ResTable_type* type = *iter; size_t entry_count = dtohl(type->entryCount); for (size_t entry_idx = 0; entry_idx < entry_count; entry_idx++) { - auto entry_offset_ptr = type.offset(dtohs(type->header.headerSize)).convert<uint32_t>() + - entry_idx; - if (!entry_offset_ptr) { - return base::unexpected(IOError::PAGES_MISSING); - } - - auto offset = dtohl(entry_offset_ptr.value()); + const uint32_t* entry_offsets = reinterpret_cast<const uint32_t*>( + reinterpret_cast<const uint8_t*>(type) + dtohs(type->header.headerSize)); + const uint32_t offset = dtohl(entry_offsets[entry_idx]); if (offset != ResTable_type::NO_ENTRY) { - auto entry = type.offset(dtohl(type->entriesStart) + offset).convert<ResTable_entry>(); - if (!entry) { - return base::unexpected(IOError::PAGES_MISSING); - } - - if (dtohl(entry->key.index) == static_cast<uint32_t>(*key_idx)) { + const ResTable_entry* entry = reinterpret_cast<const ResTable_entry*>( + reinterpret_cast<const uint8_t*>(type) + dtohl(type->entriesStart) + offset); + if (dtohl(entry->key.index) == static_cast<uint32_t>(key_idx)) { // The package ID will be overridden by the caller (due to runtime assignment of package // IDs for shared libraries). - return make_resid(0x00, *type_idx + type_id_offset_ + 1, entry_idx); + return make_resid(0x00, type_idx + type_id_offset_ + 1, entry_idx); } } } } - return base::unexpected(std::nullopt); + return 0u; } const LoadedPackage* LoadedArsc::GetPackageById(uint8_t package_id) const { @@ -451,8 +405,8 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, // was added. constexpr size_t kMinPackageSize = sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset); - const incfs::map_ptr<ResTable_package> header = chunk.header<ResTable_package, kMinPackageSize>(); - if (!header) { + const ResTable_package* header = chunk.header<ResTable_package, kMinPackageSize>(); + if (header == nullptr) { LOG(ERROR) << "RES_TABLE_PACKAGE_TYPE too small."; return {}; } @@ -499,13 +453,10 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, const Chunk child_chunk = iter.Next(); switch (child_chunk.type()) { case RES_STRING_POOL_TYPE: { - const auto pool_address = child_chunk.header<ResChunk_header>(); - if (!pool_address) { - LOG(ERROR) << "RES_STRING_POOL_TYPE is incomplete due to incremental installation."; - return {}; - } - - if (pool_address == header.offset(dtohl(header->typeStrings)).convert<ResChunk_header>()) { + const uintptr_t pool_address = + reinterpret_cast<uintptr_t>(child_chunk.header<ResChunk_header>()); + const uintptr_t header_address = reinterpret_cast<uintptr_t>(header); + if (pool_address == header_address + dtohl(header->typeStrings)) { // This string pool is the type string pool. status_t err = loaded_package->type_string_pool_.setTo( child_chunk.header<ResStringPool_header>(), child_chunk.size()); @@ -513,8 +464,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, LOG(ERROR) << "RES_STRING_POOL_TYPE for types corrupt."; return {}; } - } else if (pool_address == header.offset(dtohl(header->keyStrings)) - .convert<ResChunk_header>()) { + } else if (pool_address == header_address + dtohl(header->keyStrings)) { // This string pool is the key string pool. status_t err = loaded_package->key_string_pool_.setTo( child_chunk.header<ResStringPool_header>(), child_chunk.size()); @@ -528,8 +478,8 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, } break; case RES_TABLE_TYPE_SPEC_TYPE: { - const auto type_spec = child_chunk.header<ResTable_typeSpec>(); - if (!type_spec) { + const ResTable_typeSpec* type_spec = child_chunk.header<ResTable_typeSpec>(); + if (type_spec == nullptr) { LOG(ERROR) << "RES_TABLE_TYPE_SPEC_TYPE too small."; return {}; } @@ -564,7 +514,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, std::unique_ptr<TypeSpecPtrBuilder>& builder_ptr = type_builder_map[type_spec->id - 1]; if (builder_ptr == nullptr) { - builder_ptr = util::make_unique<TypeSpecPtrBuilder>(type_spec.verified()); + builder_ptr = util::make_unique<TypeSpecPtrBuilder>(type_spec); loaded_package->resource_ids_.set(type_spec->id, entry_count); } else { LOG(WARNING) << StringPrintf("RES_TABLE_TYPE_SPEC_TYPE already defined for ID %02x", @@ -573,8 +523,8 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, } break; case RES_TABLE_TYPE_TYPE: { - const auto type = child_chunk.header<ResTable_type, kResTableTypeMinSize>(); - if (!type) { + const ResTable_type* type = child_chunk.header<ResTable_type, kResTableTypeMinSize>(); + if (type == nullptr) { LOG(ERROR) << "RES_TABLE_TYPE_TYPE too small."; return {}; } @@ -586,7 +536,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, // Type chunks must be preceded by their TypeSpec chunks. std::unique_ptr<TypeSpecPtrBuilder>& builder_ptr = type_builder_map[type->id - 1]; if (builder_ptr != nullptr) { - builder_ptr->AddType(type.verified()); + builder_ptr->AddType(type); } else { LOG(ERROR) << StringPrintf( "RES_TABLE_TYPE_TYPE with ID %02x found without preceding RES_TABLE_TYPE_SPEC_TYPE.", @@ -596,8 +546,8 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, } break; case RES_TABLE_LIBRARY_TYPE: { - const auto lib = child_chunk.header<ResTable_lib_header>(); - if (!lib) { + const ResTable_lib_header* lib = child_chunk.header<ResTable_lib_header>(); + if (lib == nullptr) { LOG(ERROR) << "RES_TABLE_LIBRARY_TYPE too small."; return {}; } @@ -609,13 +559,10 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, loaded_package->dynamic_package_map_.reserve(dtohl(lib->count)); - const auto entry_begin = child_chunk.data_ptr().convert<ResTable_lib_entry>(); - const auto entry_end = entry_begin + dtohl(lib->count); + const ResTable_lib_entry* const entry_begin = + reinterpret_cast<const ResTable_lib_entry*>(child_chunk.data_ptr()); + const ResTable_lib_entry* const entry_end = entry_begin + dtohl(lib->count); for (auto entry_iter = entry_begin; entry_iter != entry_end; ++entry_iter) { - if (!entry_iter) { - return {}; - } - std::string package_name; util::ReadUtf16StringFromDevice(entry_iter->packageName, arraysize(entry_iter->packageName), &package_name); @@ -633,16 +580,17 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, } break; case RES_TABLE_OVERLAYABLE_TYPE: { - const auto overlayable = child_chunk.header<ResTable_overlayable_header>(); - if (!overlayable) { + const ResTable_overlayable_header* header = + child_chunk.header<ResTable_overlayable_header>(); + if (header == nullptr) { LOG(ERROR) << "RES_TABLE_OVERLAYABLE_TYPE too small."; return {}; } std::string name; - util::ReadUtf16StringFromDevice(overlayable->name, arraysize(overlayable->name), &name); + util::ReadUtf16StringFromDevice(header->name, arraysize(header->name), &name); std::string actor; - util::ReadUtf16StringFromDevice(overlayable->actor, arraysize(overlayable->actor), &actor); + util::ReadUtf16StringFromDevice(header->actor, arraysize(header->actor), &actor); if (loaded_package->overlayable_map_.find(name) != loaded_package->overlayable_map_.end()) { @@ -658,9 +606,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, switch (overlayable_child_chunk.type()) { case RES_TABLE_OVERLAYABLE_POLICY_TYPE: { - const auto policy_header = + const ResTable_overlayable_policy_header* policy_header = overlayable_child_chunk.header<ResTable_overlayable_policy_header>(); - if (!policy_header) { + if (policy_header == nullptr) { LOG(ERROR) << "RES_TABLE_OVERLAYABLE_POLICY_TYPE too small."; return {}; } @@ -673,12 +621,10 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, // Retrieve all the resource ids belonging to this policy chunk std::unordered_set<uint32_t> ids; - const auto ids_begin = overlayable_child_chunk.data_ptr().convert<ResTable_ref>(); + const auto ids_begin = + reinterpret_cast<const ResTable_ref*>(overlayable_child_chunk.data_ptr()); const auto ids_end = ids_begin + dtohl(policy_header->entry_count); for (auto id_iter = ids_begin; id_iter != ids_end; ++id_iter) { - if (!id_iter) { - return {}; - } ids.insert(dtohl(id_iter->ident)); } @@ -687,7 +633,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, overlayable_info.name = name; overlayable_info.actor = actor; overlayable_info.policy_flags = policy_header->policy_flags; - loaded_package->overlayable_infos_.emplace_back(overlayable_info, ids); + loaded_package->overlayable_infos_.push_back(std::make_pair(overlayable_info, ids)); loaded_package->defines_overlayable_ = true; break; } @@ -737,8 +683,8 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, package_property_t property_flags) { - incfs::map_ptr<ResTable_header> header = chunk.header<ResTable_header>(); - if (!header) { + const ResTable_header* header = chunk.header<ResTable_header>(); + if (header == nullptr) { LOG(ERROR) << "RES_TABLE_TYPE too small."; return false; } @@ -801,8 +747,7 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, return true; } -std::unique_ptr<const LoadedArsc> LoadedArsc::Load(incfs::map_ptr<void> data, - const size_t length, +std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data, const LoadedIdmap* loaded_idmap, const package_property_t property_flags) { ATRACE_NAME("LoadedArsc::Load"); @@ -810,7 +755,7 @@ std::unique_ptr<const LoadedArsc> LoadedArsc::Load(incfs::map_ptr<void> data, // Not using make_unique because the constructor is private. std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc()); - ChunkIterator iter(data, length); + ChunkIterator iter(data.data(), data.size()); while (iter.HasNext()) { const Chunk chunk = iter.Next(); switch (chunk.type()) { |