Only resolve non-dynamic resource references
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 resources.
Bug: 116486668
Bug: 116620612
Test: libandroidfw_tests & manual test of broken apps
& atest FieldsClassificationTest#testGetAlgorith
Change-Id: Icb827796a65072a39452dbe577d5e18f085ea4e2
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user