diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index 288ba32c47a6f..9e6948878b1de 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -162,6 +162,13 @@ void AssetManager2::DumpToLog() const { LOG(INFO) << base::StringPrintf("PG (%02x): ", package_group.dynamic_ref_table.mAssignedPackageId) << list; + + for (size_t i = 0; i < 256; i++) { + if (package_group.dynamic_ref_table.mLookupTable[i] != 0) { + LOG(INFO) << base::StringPrintf(" e[0x%02x] -> 0x%02x", (uint8_t) i, + package_group.dynamic_ref_table.mLookupTable[i]); + } + } } } diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index dc4a0a706baec..388548b174f98 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -6998,18 +6998,28 @@ status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { } status_t DynamicRefTable::lookupResourceValue(Res_value* value) const { - uint8_t resolvedType; + uint8_t resolvedType = Res_value::TYPE_REFERENCE; + switch (value->dataType) { + case Res_value::TYPE_ATTRIBUTE: + resolvedType = Res_value::TYPE_ATTRIBUTE; + // fallthrough + case Res_value::TYPE_REFERENCE: + // Only resolve non-dynamic references and attributes if the package is loaded as a + // library or if a shared library is attempting to retrieve its own resource + if (!(mAppAsLib || (Res_GETPACKAGE(value->data) + 1) == 0)) { + return NO_ERROR; + } - if (value->dataType == Res_value::TYPE_ATTRIBUTE - || value->dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE) { - resolvedType = Res_value::TYPE_ATTRIBUTE; - - } else if (value->dataType == Res_value::TYPE_REFERENCE - || value->dataType == Res_value::TYPE_DYNAMIC_REFERENCE) { - resolvedType = Res_value::TYPE_REFERENCE; - - } else { - return NO_ERROR; + // If the package is loaded as shared library, the resource reference + // also need to be fixed. + break; + case Res_value::TYPE_DYNAMIC_ATTRIBUTE: + resolvedType = Res_value::TYPE_ATTRIBUTE; + // fallthrough + case Res_value::TYPE_DYNAMIC_REFERENCE: + break; + default: + return NO_ERROR; } status_t err = lookupResourceId(&value->data); diff --git a/libs/androidfw/tests/DynamicRefTable_test.cpp b/libs/androidfw/tests/DynamicRefTable_test.cpp index df44e343b2b45..5acc46a3c0d95 100644 --- a/libs/androidfw/tests/DynamicRefTable_test.cpp +++ b/libs/androidfw/tests/DynamicRefTable_test.cpp @@ -40,6 +40,26 @@ TEST(DynamicRefTableTest, LookupSharedLibSelfReferences) { EXPECT_EQ(value2.data, 0x02010000); }; +TEST(DynamicRefTableTest, LookupSharedLibSelfAttributes) { + // Shared library + DynamicRefTable shared_table(0x03, /* appAsLib */ false); + shared_table.addMapping(0x00, 0x03); + Res_value value; + value.dataType = Res_value::TYPE_ATTRIBUTE; + value.data = 0x00010000; + ASSERT_EQ(shared_table.lookupResourceValue(&value), NO_ERROR); + EXPECT_EQ(value.data, 0x03010000); + + // App loaded as a shared library + DynamicRefTable shared_app_table(0x04, /* appAsLib */ true); + shared_app_table.addMapping(0x7f, 0x04); + Res_value value2; + value2.dataType = Res_value::TYPE_ATTRIBUTE; + value2.data = 0x7f010000; + ASSERT_EQ(shared_app_table.lookupResourceValue(&value2), NO_ERROR); + EXPECT_EQ(value2.data, 0x04010000); +}; + TEST(DynamicRefTableTest, LookupDynamicReferences) { // Shared library DynamicRefTable shared_table(0x2, /* appAsLib */ false); @@ -51,24 +71,46 @@ TEST(DynamicRefTableTest, LookupDynamicReferences) { ASSERT_EQ(shared_table.lookupResourceValue(&value), NO_ERROR); EXPECT_EQ(value.data, 0x05010000); - // App loaded as a shared library - DynamicRefTable shared_app_table(0x2, /* appAsLib */ true); - shared_app_table.addMapping(0x03, 0x05); - shared_app_table.addMapping(0x7f, 0x2); - Res_value value2; - value2.dataType = Res_value::TYPE_DYNAMIC_REFERENCE; - value2.data = 0x03010000; - ASSERT_EQ(shared_app_table.lookupResourceValue(&value2), NO_ERROR); - EXPECT_EQ(value2.data, 0x05010000); - // Regular application DynamicRefTable app_table(0x7f, /* appAsLib */ false); app_table.addMapping(0x03, 0x05); Res_value value3; - value3.dataType = Res_value::TYPE_REFERENCE; + value3.dataType = Res_value::TYPE_DYNAMIC_REFERENCE; value3.data = 0x03010000; ASSERT_EQ(app_table.lookupResourceValue(&value3), NO_ERROR); EXPECT_EQ(value3.data, 0x05010000); }; +TEST(DynamicRefTableTest, LookupDynamicAttributes) { +// App loaded as a shared library + DynamicRefTable shared_app_table(0x2, /* appAsLib */ true); + shared_app_table.addMapping(0x03, 0x05); + shared_app_table.addMapping(0x7f, 0x2); + Res_value value2; + value2.dataType = Res_value::TYPE_DYNAMIC_ATTRIBUTE; + value2.data = 0x03010000; + ASSERT_EQ(shared_app_table.lookupResourceValue(&value2), NO_ERROR); + EXPECT_EQ(value2.data, 0x05010000); +} + +TEST(DynamicRefTableTest, DoNotLookupNonDynamicReferences) { + // Regular application + DynamicRefTable app_table(0x7f, /* appAsLib */ false); + Res_value value; + value.dataType = Res_value::TYPE_REFERENCE; + value.data = 0x03010000; + ASSERT_EQ(app_table.lookupResourceValue(&value), NO_ERROR); + EXPECT_EQ(value.data, 0x03010000); +}; + +TEST(DynamicRefTableTest, DoNotLookupNonDynamicAttributes) { + // App with custom package id + DynamicRefTable custom_app_table(0x8f, /* appAsLib */ false); + Res_value value2; + value2.dataType = Res_value::TYPE_ATTRIBUTE; + value2.data = 0x03010000; + ASSERT_EQ(custom_app_table.lookupResourceValue(&value2), NO_ERROR); + EXPECT_EQ(value2.data, 0x03010000); +}; + } // namespace android \ No newline at end of file