Merge "Fix segfault with sparse encoding" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
829f7d5ebf
@@ -384,7 +384,16 @@ base::expected<uint32_t, NullOrIOError> LoadedPackage::FindEntryByName(
|
|||||||
return base::unexpected(IOError::PAGES_MISSING);
|
return base::unexpected(IOError::PAGES_MISSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offset = dtohl(entry_offset_ptr.value());
|
uint32_t offset;
|
||||||
|
uint16_t res_idx;
|
||||||
|
if (type->flags & ResTable_type::FLAG_SPARSE) {
|
||||||
|
auto sparse_entry = entry_offset_ptr.convert<ResTable_sparseTypeEntry>();
|
||||||
|
offset = dtohs(sparse_entry->offset) * 4u;
|
||||||
|
res_idx = dtohs(sparse_entry->idx);
|
||||||
|
} else {
|
||||||
|
offset = dtohl(entry_offset_ptr.value());
|
||||||
|
res_idx = entry_idx;
|
||||||
|
}
|
||||||
if (offset != ResTable_type::NO_ENTRY) {
|
if (offset != ResTable_type::NO_ENTRY) {
|
||||||
auto entry = type.offset(dtohl(type->entriesStart) + offset).convert<ResTable_entry>();
|
auto entry = type.offset(dtohl(type->entriesStart) + offset).convert<ResTable_entry>();
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
@@ -394,7 +403,7 @@ base::expected<uint32_t, NullOrIOError> LoadedPackage::FindEntryByName(
|
|||||||
if (dtohl(entry->key.index) == static_cast<uint32_t>(*key_idx)) {
|
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
|
// The package ID will be overridden by the caller (due to runtime assignment of package
|
||||||
// IDs for shared libraries).
|
// 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, res_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,38 @@ TEST(LoadedArscTest, LoadSparseEntryApp) {
|
|||||||
ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
|
ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(LoadedArscTest, FindSparseEntryApp) {
|
||||||
|
std::string contents;
|
||||||
|
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/sparse/sparse.apk", "resources.arsc",
|
||||||
|
&contents));
|
||||||
|
|
||||||
|
std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(),
|
||||||
|
contents.length());
|
||||||
|
ASSERT_THAT(loaded_arsc, NotNull());
|
||||||
|
|
||||||
|
const LoadedPackage* package =
|
||||||
|
loaded_arsc->GetPackageById(get_package_id(sparse::R::string::only_v26));
|
||||||
|
ASSERT_THAT(package, NotNull());
|
||||||
|
|
||||||
|
const uint8_t type_index = get_type_id(sparse::R::string::only_v26) - 1;
|
||||||
|
const uint16_t entry_index = get_entry_id(sparse::R::string::only_v26);
|
||||||
|
|
||||||
|
const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
|
||||||
|
ASSERT_THAT(type_spec, NotNull());
|
||||||
|
ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));
|
||||||
|
|
||||||
|
// Ensure that AAPT2 sparsely encoded the v26 config as expected.
|
||||||
|
auto type_entry = std::find_if(
|
||||||
|
type_spec->type_entries.begin(), type_spec->type_entries.end(),
|
||||||
|
[](const TypeSpec::TypeEntry& x) { return x.config.sdkVersion == 26; });
|
||||||
|
ASSERT_NE(type_entry, type_spec->type_entries.end());
|
||||||
|
ASSERT_NE(type_entry->type->flags & ResTable_type::FLAG_SPARSE, 0);
|
||||||
|
|
||||||
|
// Test fetching a resource with only sparsely encoded configs by name.
|
||||||
|
auto id = package->FindEntryByName(u"string", u"only_v26");
|
||||||
|
ASSERT_EQ(id.value(), fix_package_id(sparse::R::string::only_v26, 0));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(LoadedArscTest, LoadSharedLibrary) {
|
TEST(LoadedArscTest, LoadSharedLibrary) {
|
||||||
std::string contents;
|
std::string contents;
|
||||||
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc",
|
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc",
|
||||||
|
|||||||
@@ -27,21 +27,22 @@ struct R {
|
|||||||
struct integer {
|
struct integer {
|
||||||
enum : uint32_t {
|
enum : uint32_t {
|
||||||
foo_0 = 0x7f010000,
|
foo_0 = 0x7f010000,
|
||||||
foo_1 = 0x7f010000,
|
foo_1 = 0x7f010001,
|
||||||
foo_2 = 0x7f010000,
|
foo_2 = 0x7f010002,
|
||||||
foo_3 = 0x7f010000,
|
foo_3 = 0x7f010003,
|
||||||
foo_4 = 0x7f010000,
|
foo_4 = 0x7f010004,
|
||||||
foo_5 = 0x7f010000,
|
foo_5 = 0x7f010005,
|
||||||
foo_6 = 0x7f010000,
|
foo_6 = 0x7f010006,
|
||||||
foo_7 = 0x7f010000,
|
foo_7 = 0x7f010007,
|
||||||
foo_8 = 0x7f010000,
|
foo_8 = 0x7f010008,
|
||||||
foo_9 = 0x7f010000,
|
foo_9 = 0x7f010009,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct string {
|
struct string {
|
||||||
enum : uint32_t {
|
enum : uint32_t {
|
||||||
foo_999 = 0x7f0203e7,
|
foo_999 = 0x7f0203e7,
|
||||||
|
only_v26 = 0x7f0203e8
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,5 +14,7 @@ do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo "</resources>" >> $OUTPUT_default
|
echo "</resources>" >> $OUTPUT_default
|
||||||
|
|
||||||
|
echo " <string name=\"only_v26\">only v26</string>" >> $OUTPUT_v26
|
||||||
echo "</resources>" >> $OUTPUT_v26
|
echo "</resources>" >> $OUTPUT_v26
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -333,4 +333,5 @@
|
|||||||
<string name="foo_993">9930</string>
|
<string name="foo_993">9930</string>
|
||||||
<string name="foo_996">9960</string>
|
<string name="foo_996">9960</string>
|
||||||
<string name="foo_999">9990</string>
|
<string name="foo_999">9990</string>
|
||||||
|
<string name="only_v26">only v26</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user