Loading libs/androidfw/AssetManager2.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -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]); } } } } Loading libs/androidfw/ResourceTypes.cpp +21 −11 Original line number Diff line number Diff line Loading @@ -6998,17 +6998,27 @@ status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { } status_t DynamicRefTable::lookupResourceValue(Res_value* value) const { uint8_t resolvedType; if (value->dataType == Res_value::TYPE_ATTRIBUTE || value->dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE) { 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; } } else if (value->dataType == Res_value::TYPE_REFERENCE || value->dataType == Res_value::TYPE_DYNAMIC_REFERENCE) { resolvedType = Res_value::TYPE_REFERENCE; } else { // 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; } Loading libs/androidfw/tests/DynamicRefTable_test.cpp +50 −8 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -51,24 +71,46 @@ TEST(DynamicRefTableTest, LookupDynamicReferences) { ASSERT_EQ(shared_table.lookupResourceValue(&value), NO_ERROR); EXPECT_EQ(value.data, 0x05010000); // Regular application DynamicRefTable app_table(0x7f, /* appAsLib */ false); app_table.addMapping(0x03, 0x05); Res_value value3; 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_REFERENCE; 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); app_table.addMapping(0x03, 0x05); Res_value value3; value3.dataType = Res_value::TYPE_REFERENCE; value3.data = 0x03010000; ASSERT_EQ(app_table.lookupResourceValue(&value3), NO_ERROR); EXPECT_EQ(value3.data, 0x05010000); 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 Loading
libs/androidfw/AssetManager2.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -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]); } } } } Loading
libs/androidfw/ResourceTypes.cpp +21 −11 Original line number Diff line number Diff line Loading @@ -6998,17 +6998,27 @@ status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { } status_t DynamicRefTable::lookupResourceValue(Res_value* value) const { uint8_t resolvedType; if (value->dataType == Res_value::TYPE_ATTRIBUTE || value->dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE) { 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; } } else if (value->dataType == Res_value::TYPE_REFERENCE || value->dataType == Res_value::TYPE_DYNAMIC_REFERENCE) { resolvedType = Res_value::TYPE_REFERENCE; } else { // 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; } Loading
libs/androidfw/tests/DynamicRefTable_test.cpp +50 −8 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -51,24 +71,46 @@ TEST(DynamicRefTableTest, LookupDynamicReferences) { ASSERT_EQ(shared_table.lookupResourceValue(&value), NO_ERROR); EXPECT_EQ(value.data, 0x05010000); // Regular application DynamicRefTable app_table(0x7f, /* appAsLib */ false); app_table.addMapping(0x03, 0x05); Res_value value3; 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_REFERENCE; 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); app_table.addMapping(0x03, 0x05); Res_value value3; value3.dataType = Res_value::TYPE_REFERENCE; value3.data = 0x03010000; ASSERT_EQ(app_table.lookupResourceValue(&value3), NO_ERROR); EXPECT_EQ(value3.data, 0x05010000); 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