summaryrefslogtreecommitdiff
path: root/libs/androidfw/LoadedArsc.cpp
diff options
context:
space:
mode:
author Adam Lesinski <adamlesinski@google.com> 2017-01-13 15:34:14 -0800
committer Adam Lesinski <adamlesinski@google.com> 2017-01-27 16:52:53 -0800
commitc6aada9c5789b2777b19c522d3cd5052bbe784a4 (patch)
treee78d92b927ba7fb951c0898fe28957a19671a684 /libs/androidfw/LoadedArsc.cpp
parent90572a4ab8ac393c57e896be3c608e634866ed38 (diff)
LoadedArsc: Support feature splits.
Test: make libandroidfw_tests Change-Id: I278273e688da597f4af86dd55f87750501ef8154
Diffstat (limited to 'libs/androidfw/LoadedArsc.cpp')
-rw-r--r--libs/androidfw/LoadedArsc.cpp21
1 files changed, 19 insertions, 2 deletions
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> 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<uint8_t>::max()) {
+ LOG(ERROR) << "Type ID offset in RES_TABLE_PACKAGE_TYPE is too large.";
+ return {};
+ }
+ loaded_package->type_id_offset_ = static_cast<int>(type_id_offset);
+ }
+
util::ReadUtf16StringFromDevice(header->name, arraysize(header->name),
&loaded_package->package_name_);
@@ -385,7 +397,6 @@ std::unique_ptr<LoadedPackage> 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> LoadedPackage::Load(const Chunk& chunk) {
return {};
}
+ if (loaded_package->type_id_offset_ + static_cast<int>(type_spec->id) >
+ std::numeric_limits<uint8_t>::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.