idmap2: include AndroidManifest.xml in CRCs
The CRCs stored in the idmap file header are copies of the zip file CRC for the
resources.arsc entry in the target and overlay package apks, and are used to
quickly check if either package's contents has changed, which in turn means the
idmap file must be recreated.
With the introduction of named targets, just checking the resources.arsc file is no
longer sufficient: an overlay package could be installed with targetName="a" and
updated to targetName="b". This change is not reflected in the resources.arsc file,
only in the AndroidManifest.xml.
To account for this, update the CRC in the idmap file header from
CRC(resources.arsc)
to
CRC(resources.arsc) ^ CRC(AndroidManifest.xml)
Test: make idmap2_tests
Bug: 119761809
Change-Id: Ieb0c6b466ac23eb81a2670a32309fa46ade5c5c8
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index fa5ac8e..b19d7a9 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -117,6 +117,12 @@
return loaded_arsc.GetPackageById(id);
}
+Result<uint32_t> GetCrc(const ZipFile& zip) {
+ const Result<uint32_t> a = zip.Crc("resources.arsc");
+ const Result<uint32_t> b = zip.Crc("AndroidManifest.xml");
+ return a && b ? Result<uint32_t>(*a ^ *b) : kResultError;
+}
+
} // namespace
std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) {
@@ -153,7 +159,7 @@
return false;
}
- Result<uint32_t> target_crc = target_zip->Crc("resources.arsc");
+ Result<uint32_t> target_crc = GetCrc(*target_zip);
if (!target_crc) {
out_error << "error: failed to get target crc" << std::endl;
return false;
@@ -173,7 +179,7 @@
return false;
}
- Result<uint32_t> overlay_crc = overlay_zip->Crc("resources.arsc");
+ Result<uint32_t> overlay_crc = GetCrc(*overlay_zip);
if (!overlay_crc) {
out_error << "error: failed to get overlay crc" << std::endl;
return false;
@@ -356,14 +362,14 @@
header->magic_ = kIdmapMagic;
header->version_ = kIdmapCurrentVersion;
- Result<uint32_t> crc = target_zip->Crc("resources.arsc");
+ Result<uint32_t> crc = GetCrc(*target_zip);
if (!crc) {
out_error << "error: failed to get zip crc for target" << std::endl;
return nullptr;
}
header->target_crc_ = *crc;
- crc = overlay_zip->Crc("resources.arsc");
+ crc = GetCrc(*overlay_zip);
if (!crc) {
out_error << "error: failed to get zip crc for overlay" << std::endl;
return nullptr;