From 0699f1de6a684644b2debf82d55dfbcbc9387679 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Thu, 3 Dec 2020 15:41:42 -0800 Subject: [PATCH] Remove idmap path 256 length limit Overlay and target package paths can be longer than 256 characters. Currently, the idmap will fail to be generated if either path is longer than 256 characters. This change removes the 256 character limit and makes parsing variable length strings easier in libandroidfw. Bug: 174676094 Test: idmap2_tests && libandroidfw_tests Change-Id: Ic240cdb8700566b2ac2ade08da58bea852e4ae0c --- cmds/idmap2/idmap2/CommandUtils.cpp | 4 +- cmds/idmap2/idmap2/Lookup.cpp | 12 +- cmds/idmap2/idmap2d/Idmap2Service.cpp | 2 +- .../include/idmap2/BinaryStreamVisitor.h | 1 - cmds/idmap2/include/idmap2/Idmap.h | 37 ++- cmds/idmap2/include/idmap2/RawPrintVisitor.h | 4 +- cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp | 11 +- cmds/idmap2/libidmap2/Idmap.cpp | 87 ++---- cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp | 4 +- cmds/idmap2/libidmap2/RawPrintVisitor.cpp | 46 ++-- cmds/idmap2/libidmap2/ResourceMapping.cpp | 4 +- cmds/idmap2/tests/IdmapTests.cpp | 114 +++----- cmds/idmap2/tests/RawPrintVisitorTests.cpp | 8 +- cmds/idmap2/tests/TestHelpers.h | 104 +++----- libs/androidfw/ApkAssets.cpp | 2 +- libs/androidfw/AssetManager2.cpp | 3 +- libs/androidfw/Idmap.cpp | 250 ++++++++++-------- libs/androidfw/include/androidfw/Idmap.h | 28 +- .../include/androidfw/ResourceTypes.h | 52 +--- libs/androidfw/include/androidfw/Util.h | 6 +- .../tests/data/overlay/overlay.idmap | Bin 1092 -> 636 bytes 21 files changed, 340 insertions(+), 439 deletions(-) diff --git a/cmds/idmap2/idmap2/CommandUtils.cpp b/cmds/idmap2/idmap2/CommandUtils.cpp index 8f5845bf2e53e..45f37962331b3 100644 --- a/cmds/idmap2/idmap2/CommandUtils.cpp +++ b/cmds/idmap2/idmap2/CommandUtils.cpp @@ -39,8 +39,8 @@ Result Verify(const std::string& idmap_path, const std::string& target_pat return Error("failed to parse idmap header"); } - const auto header_ok = header->IsUpToDate(target_path.c_str(), overlay_path.c_str(), - fulfilled_policies, enforce_overlayable); + const auto header_ok = + header->IsUpToDate(target_path, overlay_path, fulfilled_policies, enforce_overlayable); if (!header_ok) { return Error(header_ok.GetError(), "idmap not up to date"); } diff --git a/cmds/idmap2/idmap2/Lookup.cpp b/cmds/idmap2/idmap2/Lookup.cpp index 437180d3d1bef..64e49307c0df5 100644 --- a/cmds/idmap2/idmap2/Lookup.cpp +++ b/cmds/idmap2/idmap2/Lookup.cpp @@ -188,29 +188,27 @@ Result Lookup(const std::vector& args) { } if (i == 0) { - target_path = idmap_header->GetTargetPath().to_string(); + target_path = idmap_header->GetTargetPath(); auto target_apk = ApkAssets::Load(target_path); if (!target_apk) { return Error("failed to read target apk from %s", target_path.c_str()); } apk_assets.push_back(std::move(target_apk)); - auto manifest_info = ExtractOverlayManifestInfo(idmap_header->GetOverlayPath().to_string(), - true /* assert_overlay */); + auto manifest_info = + ExtractOverlayManifestInfo(idmap_header->GetOverlayPath(), true /* assert_overlay */); if (!manifest_info) { return manifest_info.GetError(); } target_package_name = (*manifest_info).target_package; } else if (target_path != idmap_header->GetTargetPath()) { return Error("different target APKs (expected target APK %s but %s has target APK %s)", - target_path.c_str(), idmap_path.c_str(), - idmap_header->GetTargetPath().to_string().c_str()); + target_path.c_str(), idmap_path.c_str(), idmap_header->GetTargetPath().c_str()); } auto overlay_apk = ApkAssets::LoadOverlay(idmap_path); if (!overlay_apk) { - return Error("failed to read overlay apk from %s", - idmap_header->GetOverlayPath().to_string().c_str()); + return Error("failed to read overlay apk from %s", idmap_header->GetOverlayPath().c_str()); } apk_assets.push_back(std::move(overlay_apk)); } diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 15e22a3410cfa..8a7272c073b94 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -156,7 +156,7 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path, } auto up_to_date = - header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), target_crc, overlay_crc, + header->IsUpToDate(target_apk_path overlay_apk_path, target_crc, overlay_crc, ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); *_aidl_return = static_cast(up_to_date); diff --git a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h index bf31cbf8d4f73..5e189f2c13404 100644 --- a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h +++ b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h @@ -39,7 +39,6 @@ class BinaryStreamVisitor : public Visitor { void Write8(uint8_t value); void Write16(uint16_t value); void Write32(uint32_t value); - void WriteString256(const StringPiece& value); void WriteString(const StringPiece& value); std::ostream& stream_; }; diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index a35fad9d686c0..3163e40a7bffa 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -37,13 +37,12 @@ * overlay_entry_count := * overlay_id := * overlay_package_id := - * overlay_path := string256 + * overlay_path := string * padding(n) := [n] * Res_value::size := * Res_value::type := * Res_value::value := * string := + padding(n) - * string256 := [256] * string_pool := string * string_pool_index := * string_pool_length := @@ -52,7 +51,7 @@ * target_inline_entry_count := * target_id := * target_package_id := - * target_path := string256 + * target_path := string * value_type := * value_data := * version := @@ -87,10 +86,6 @@ static constexpr const uint32_t kIdmapMagic = android::kIdmapMagic; // current version of the idmap binary format; must be incremented when the format is changed static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVersion; -// strings in the idmap are encoded char arrays of length 'kIdmapStringLength' (including mandatory -// terminating null) -static constexpr const size_t kIdmapStringLength = 256; - // Retrieves a crc generated using all of the files within the zip that can affect idmap generation. Result GetPackageCrc(const ZipFile& zip_info); @@ -122,26 +117,26 @@ class IdmapHeader { return enforce_overlayable_; } - inline StringPiece GetTargetPath() const { - return StringPiece(target_path_); + const std::string& GetTargetPath() const { + return target_path_; } - inline StringPiece GetOverlayPath() const { - return StringPiece(overlay_path_); + const std::string& GetOverlayPath() const { + return overlay_path_; } - inline const std::string& GetDebugInfo() const { + const std::string& GetDebugInfo() const { return debug_info_; } // Invariant: anytime the idmap data encoding is changed, the idmap version // field *must* be incremented. Because of this, we know that if the idmap // header is up-to-date the entire file is up-to-date. - Result IsUpToDate(const char* target_path, const char* overlay_path, + Result IsUpToDate(const std::string& target_path, const std::string& overlay_path, + PolicyBitmask fulfilled_policies, bool enforce_overlayable) const; + Result IsUpToDate(const std::string& target_path, const std::string& overlay_path, + uint32_t target_crc, uint32_t overlay_crc, PolicyBitmask fulfilled_policies, bool enforce_overlayable) const; - Result IsUpToDate(const char* target_path, const char* overlay_path, uint32_t target_crc, - uint32_t overlay_crc, PolicyBitmask fulfilled_policies, - bool enforce_overlayable) const; void accept(Visitor* v) const; @@ -155,8 +150,8 @@ class IdmapHeader { uint32_t overlay_crc_; uint32_t fulfilled_policies_; bool enforce_overlayable_; - char target_path_[kIdmapStringLength]; - char overlay_path_[kIdmapStringLength]; + std::string target_path_; + std::string overlay_path_; std::string debug_info_; friend Idmap; @@ -291,8 +286,7 @@ class Idmap { void accept(Visitor* v) const; private: - Idmap() { - } + Idmap() = default; std::unique_ptr header_; std::vector> data_; @@ -302,8 +296,7 @@ class Idmap { class Visitor { public: - virtual ~Visitor() { - } + virtual ~Visitor() = default; virtual void visit(const Idmap& idmap) = 0; virtual void visit(const IdmapHeader& header) = 0; virtual void visit(const IdmapData& data) = 0; diff --git a/cmds/idmap2/include/idmap2/RawPrintVisitor.h b/cmds/idmap2/include/idmap2/RawPrintVisitor.h index 58edc99715fd0..45835164ef8e8 100644 --- a/cmds/idmap2/include/idmap2/RawPrintVisitor.h +++ b/cmds/idmap2/include/idmap2/RawPrintVisitor.h @@ -44,7 +44,9 @@ class RawPrintVisitor : public Visitor { void print(uint8_t value, const char* fmt, ...); void print(uint16_t value, const char* fmt, ...); void print(uint32_t value, const char* fmt, ...); - void print(const std::string& value, size_t encoded_size, const char* fmt, ...); + void print(const std::string& value, bool print_value, const char* fmt, ...); + void align(); + void pad(size_t padding); std::ostream& stream_; std::vector> apk_assets_; diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp index 726f6c5c2c99a..5db09baca5d5a 100644 --- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp +++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp @@ -38,13 +38,6 @@ void BinaryStreamVisitor::Write32(uint32_t value) { stream_.write(reinterpret_cast(&x), sizeof(uint32_t)); } -void BinaryStreamVisitor::WriteString256(const StringPiece& value) { - char buf[kIdmapStringLength]; - memset(buf, 0, sizeof(buf)); - memcpy(buf, value.data(), std::min(value.size(), sizeof(buf))); - stream_.write(buf, sizeof(buf)); -} - void BinaryStreamVisitor::WriteString(const StringPiece& value) { // pad with null to nearest word boundary; size_t padding_size = CalculatePadding(value.size()); @@ -64,8 +57,8 @@ void BinaryStreamVisitor::visit(const IdmapHeader& header) { Write32(header.GetOverlayCrc()); Write32(header.GetFulfilledPolicies()); Write32(static_cast(header.GetEnforceOverlayable())); - WriteString256(header.GetTargetPath()); - WriteString256(header.GetOverlayPath()); + WriteString(header.GetTargetPath()); + WriteString(header.GetOverlayPath()); WriteString(header.GetDebugInfo()); } diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 1129413584b2a..4745cc6cdc331 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -69,38 +69,26 @@ bool WARN_UNUSED Read32(std::istream& stream, uint32_t* out) { return false; } -// a string is encoded as a kIdmapStringLength char array; the array is always null-terminated -bool WARN_UNUSED ReadString256(std::istream& stream, char out[kIdmapStringLength]) { - char buf[kIdmapStringLength]; - memset(buf, 0, sizeof(buf)); - if (!stream.read(buf, sizeof(buf))) { - return false; - } - if (buf[sizeof(buf) - 1] != '\0') { - return false; - } - memcpy(out, buf, sizeof(buf)); - return true; -} - -Result ReadString(std::istream& stream) { +bool WARN_UNUSED ReadString(std::istream& stream, std::string* out) { uint32_t size; if (!Read32(stream, &size)) { - return Error("failed to read string size"); + return false; } if (size == 0) { - return std::string(""); + *out = ""; + return true; } std::string buf(size, '\0'); if (!stream.read(buf.data(), size)) { - return Error("failed to read string of size %u", size); + return false; } uint32_t padding_size = CalculatePadding(size); std::string padding(padding_size, '\0'); if (!stream.read(padding.data(), padding_size)) { - return Error("failed to read string padding of size %u", padding_size); + return false; } - return buf; + *out = buf; + return true; } } // namespace @@ -119,28 +107,23 @@ std::unique_ptr IdmapHeader::FromBinaryStream(std::istream& s if (!Read32(stream, &idmap_header->magic_) || !Read32(stream, &idmap_header->version_) || !Read32(stream, &idmap_header->target_crc_) || !Read32(stream, &idmap_header->overlay_crc_) || !Read32(stream, &idmap_header->fulfilled_policies_) || - !Read32(stream, &enforce_overlayable) || !ReadString256(stream, idmap_header->target_path_) || - !ReadString256(stream, idmap_header->overlay_path_)) { + !Read32(stream, &enforce_overlayable) || !ReadString(stream, &idmap_header->target_path_) || + !ReadString(stream, &idmap_header->overlay_path_) || + !ReadString(stream, &idmap_header->debug_info_)) { return nullptr; } idmap_header->enforce_overlayable_ = enforce_overlayable != 0U; - - auto debug_str = ReadString(stream); - if (!debug_str) { - return nullptr; - } - idmap_header->debug_info_ = std::move(*debug_str); - return std::move(idmap_header); } -Result IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path, +Result IdmapHeader::IsUpToDate(const std::string& target_path, + const std::string& overlay_path, PolicyBitmask fulfilled_policies, bool enforce_overlayable) const { const std::unique_ptr target_zip = ZipFile::Open(target_path); if (!target_zip) { - return Error("failed to open target %s", target_path); + return Error("failed to open target %s", target_path.c_str()); } const Result target_crc = GetPackageCrc(*target_zip); @@ -150,7 +133,7 @@ Result IdmapHeader::IsUpToDate(const char* target_path, const char* overla const std::unique_ptr overlay_zip = ZipFile::Open(overlay_path); if (!overlay_zip) { - return Error("failed to overlay target %s", overlay_path); + return Error("failed to overlay target %s", overlay_path.c_str()); } const Result overlay_crc = GetPackageCrc(*overlay_zip); @@ -162,9 +145,9 @@ Result IdmapHeader::IsUpToDate(const char* target_path, const char* overla enforce_overlayable); } -Result IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path, - uint32_t target_crc, uint32_t overlay_crc, - PolicyBitmask fulfilled_policies, +Result IdmapHeader::IsUpToDate(const std::string& target_path, + const std::string& overlay_path, uint32_t target_crc, + uint32_t overlay_crc, PolicyBitmask fulfilled_policies, bool enforce_overlayable) const { if (magic_ != kIdmapMagic) { return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); @@ -194,14 +177,14 @@ Result IdmapHeader::IsUpToDate(const char* target_path, const char* overla enforce_overlayable ? "true" : "false", enforce_overlayable_ ? "true" : "false"); } - if (strcmp(target_path, target_path_) != 0) { - return Error("bad target path: idmap version %s, file system version %s", target_path, - target_path_); + if (target_path != target_path_) { + return Error("bad target path: idmap version %s, file system version %s", target_path.c_str(), + target_path_.c_str()); } - if (strcmp(overlay_path, overlay_path_) != 0) { - return Error("bad overlay path: idmap version %s, file system version %s", overlay_path, - overlay_path_); + if (overlay_path != overlay_path_) { + return Error("bad overlay path: idmap version %s, file system version %s", overlay_path.c_str(), + overlay_path_.c_str()); } return Unit{}; @@ -262,12 +245,9 @@ std::unique_ptr IdmapData::FromBinaryStream(std::istream& strea } // Read raw string pool bytes. - auto string_pool_data = ReadString(stream); - if (!string_pool_data) { + if (!ReadString(stream, &data->string_pool_data_)) { return nullptr; } - data->string_pool_data_ = std::move(*string_pool_data); - return std::move(data); } @@ -368,23 +348,10 @@ Result> Idmap::FromApkAssets(const ApkAssets& targe return Error(crc.GetError(), "failed to get zip CRC for overlay"); } header->overlay_crc_ = *crc; - header->fulfilled_policies_ = fulfilled_policies; header->enforce_overlayable_ = enforce_overlayable; - - if (target_apk_path.size() > sizeof(header->target_path_)) { - return Error("target apk path \"%s\" longer than maximum size %zu", target_apk_path.c_str(), - sizeof(header->target_path_)); - } - memset(header->target_path_, 0, sizeof(header->target_path_)); - memcpy(header->target_path_, target_apk_path.data(), target_apk_path.size()); - - if (overlay_apk_path.size() > sizeof(header->overlay_path_)) { - return Error("overlay apk path \"%s\" longer than maximum size %zu", overlay_apk_path.c_str(), - sizeof(header->target_path_)); - } - memset(header->overlay_path_, 0, sizeof(header->overlay_path_)); - memcpy(header->overlay_path_, overlay_apk_path.data(), overlay_apk_path.size()); + header->target_path_ = target_apk_path; + header->overlay_path_ = overlay_apk_path; auto overlay_info = utils::ExtractOverlayManifestInfo(overlay_apk_path); if (!overlay_info) { diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp index 3037a791328e3..f56d3d21e25b6 100644 --- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp @@ -49,12 +49,12 @@ void PrettyPrintVisitor::visit(const IdmapHeader& header) { } } - if (auto target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string())) { + if (auto target_apk_ = ApkAssets::Load(header.GetTargetPath())) { target_am_.SetApkAssets({target_apk_.get()}); apk_assets_.push_back(std::move(target_apk_)); } - if (auto overlay_apk = ApkAssets::Load(header.GetOverlayPath().to_string())) { + if (auto overlay_apk = ApkAssets::Load(header.GetOverlayPath())) { overlay_am_.SetApkAssets({overlay_apk.get()}); apk_assets_.push_back(std::move(overlay_apk)); } diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp index 82f5d26cbbb31..d7f073944542e 100644 --- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp @@ -43,20 +43,17 @@ void RawPrintVisitor::visit(const IdmapHeader& header) { print(header.GetFulfilledPolicies(), "fulfilled policies: %s", PoliciesToDebugString(header.GetFulfilledPolicies()).c_str()); print(static_cast(header.GetEnforceOverlayable()), "enforce overlayable"); - print(header.GetTargetPath().to_string(), kIdmapStringLength, "target path"); - print(header.GetOverlayPath().to_string(), kIdmapStringLength, "overlay path"); + print(header.GetTargetPath(), true /* print_value */, "target path"); + print(header.GetOverlayPath(), true /* print_value */, "overlay path"); + print(header.GetDebugInfo(), false /* print_value */, "debug info"); - uint32_t debug_info_size = header.GetDebugInfo().size(); - print(debug_info_size, "debug info size"); - print("...", debug_info_size + CalculatePadding(debug_info_size), "debug info"); - - auto target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string()); + auto target_apk_ = ApkAssets::Load(header.GetTargetPath()); if (target_apk_) { target_am_.SetApkAssets({target_apk_.get()}); apk_assets_.push_back(std::move(target_apk_)); } - auto overlay_apk_ = ApkAssets::Load(header.GetOverlayPath().to_string()); + auto overlay_apk_ = ApkAssets::Load(header.GetOverlayPath()); if (overlay_apk_) { overlay_am_.SetApkAssets({overlay_apk_.get()}); apk_assets_.push_back(std::move(overlay_apk_)); @@ -100,7 +97,7 @@ void RawPrintVisitor::visit(const IdmapData& data ATTRIBUTE_UNUSED) { print(target_entry.target_id, "target id"); } - print("...", sizeof(Res_value::size) + sizeof(Res_value::res0), "padding"); + pad(sizeof(Res_value::size) + sizeof(Res_value::res0)); print(target_entry.value.data_type, "type: %s", utils::DataTypeToString(target_entry.value.data_type).data()); @@ -143,15 +140,13 @@ void RawPrintVisitor::visit(const IdmapData& data ATTRIBUTE_UNUSED) { } } - uint32_t string_pool_size = data.GetStringPoolData().size(); - print(string_pool_size, "string pool size"); - print("...", string_pool_size + CalculatePadding(string_pool_size), "string pool"); + print(data.GetStringPoolData(), false /* print_value */, "string pool"); } void RawPrintVisitor::visit(const IdmapData::Header& header) { print(header.GetTargetPackageId(), "target package id"); print(header.GetOverlayPackageId(), "overlay package id"); - print("...", sizeof(Idmap_data_header::p0), "padding"); + align(); print(header.GetTargetEntryCount(), "target entry count"); print(header.GetTargetInlineEntryCount(), "target inline entry count"); print(header.GetOverlayEntryCount(), "overlay entry count"); @@ -168,7 +163,6 @@ void RawPrintVisitor::print(uint8_t value, const char* fmt, ...) { stream_ << base::StringPrintf("%08zx: %02x", offset_, value) << " " << comment << std::endl; - offset_ += sizeof(uint8_t); } @@ -181,7 +175,6 @@ void RawPrintVisitor::print(uint16_t value, const char* fmt, ...) { va_end(ap); stream_ << base::StringPrintf("%08zx: %04x", offset_, value) << " " << comment << std::endl; - offset_ += sizeof(uint16_t); } @@ -194,22 +187,35 @@ void RawPrintVisitor::print(uint32_t value, const char* fmt, ...) { va_end(ap); stream_ << base::StringPrintf("%08zx: %08x", offset_, value) << " " << comment << std::endl; - offset_ += sizeof(uint32_t); } // NOLINTNEXTLINE(cert-dcl50-cpp) -void RawPrintVisitor::print(const std::string& value, size_t encoded_size, const char* fmt, ...) { +void RawPrintVisitor::print(const std::string& value, bool print_value, const char* fmt, ...) { va_list ap; va_start(ap, fmt); std::string comment; base::StringAppendV(&comment, fmt, ap); va_end(ap); - stream_ << base::StringPrintf("%08zx: ", offset_) << "........ " << comment << ": " << value - << std::endl; + stream_ << base::StringPrintf("%08zx: %08x", offset_, (uint32_t)value.size()) << " " << comment + << " size" << std::endl; + offset_ += sizeof(uint32_t); - offset_ += encoded_size; + stream_ << base::StringPrintf("%08zx: ", offset_) << "........ " << comment; + offset_ += value.size() + CalculatePadding(value.size()); + + if (print_value) { + stream_ << ": " << value; + } + stream_ << std::endl; } +void RawPrintVisitor::align() { + offset_ += CalculatePadding(offset_); +} + +void RawPrintVisitor::pad(size_t padding) { + offset_ += padding; +} } // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp index d777cbfa9a14c..9abb9e458902a 100644 --- a/cmds/idmap2/libidmap2/ResourceMapping.cpp +++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp @@ -230,8 +230,8 @@ Result ResourceMapping::CreateResourceMappingLegacy( base::StringPrintf("%s:%s", target_package->GetPackageName().c_str(), name->c_str()); auto target_resource_result = target_am->GetResourceId(full_name); if (!target_resource_result.has_value()) { - log_info.Warning(LogMessage() << "failed to find resource \"" << full_name - << "\" in target resources"); + log_info.Warning(LogMessage() + << "failed to find resource \"" << full_name << "\" in target resources"); continue; } diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index 9b42a2781b58f..7be1602ccf40d 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -35,7 +35,6 @@ #include "idmap2/LogInfo.h" using android::Res_value; -using ::testing::IsNull; using ::testing::NotNull; using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; @@ -66,29 +65,18 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) { std::unique_ptr header = IdmapHeader::FromBinaryStream(stream); ASSERT_THAT(header, NotNull()); ASSERT_EQ(header->GetMagic(), 0x504d4449U); - ASSERT_EQ(header->GetVersion(), 0x05U); + ASSERT_EQ(header->GetVersion(), 0x06U); ASSERT_EQ(header->GetTargetCrc(), 0x1234U); ASSERT_EQ(header->GetOverlayCrc(), 0x5678U); ASSERT_EQ(header->GetFulfilledPolicies(), 0x11); ASSERT_EQ(header->GetEnforceOverlayable(), true); - ASSERT_EQ(header->GetTargetPath().to_string(), "targetX.apk"); - ASSERT_EQ(header->GetOverlayPath().to_string(), "overlayX.apk"); + ASSERT_EQ(header->GetTargetPath(), "targetX.apk"); + ASSERT_EQ(header->GetOverlayPath(), "overlayX.apk"); ASSERT_EQ(header->GetDebugInfo(), "debug"); } -TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) { - std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); - // overwrite the target path string, including the terminating null, with '.' - for (size_t i = 0x18; i < 0x118; i++) { - raw[i] = '.'; - } - std::istringstream stream(raw); - std::unique_ptr header = IdmapHeader::FromBinaryStream(stream); - ASSERT_THAT(header, IsNull()); -} - TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) { - const size_t offset = 0x224; + const size_t offset = idmap_raw_data_offset; std::string raw(reinterpret_cast(idmap_raw_data + offset), idmap_raw_data_len - offset); std::istringstream stream(raw); @@ -100,7 +88,7 @@ TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) { } TEST(IdmapTests, CreateIdmapDataFromBinaryStream) { - const size_t offset = 0x224; + const size_t offset = idmap_raw_data_offset; std::string raw(reinterpret_cast(idmap_raw_data + offset), idmap_raw_data_len - offset); std::istringstream stream(raw); @@ -136,13 +124,13 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) { ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); - ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x05U); + ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x06U); ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U); ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U); ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), 0x11); ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true); - ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), "targetX.apk"); - ASSERT_EQ(idmap->GetHeader()->GetOverlayPath().to_string(), "overlayX.apk"); + ASSERT_EQ(idmap->GetHeader()->GetTargetPath(), idmap_raw_data_target_path); + ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), idmap_raw_data_overlay_path); const std::vector>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); @@ -195,12 +183,12 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) { ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); - ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x05U); + ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x06U); ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC); ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC); ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), PolicyFlags::PUBLIC); ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true); - ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path); + ASSERT_EQ(idmap->GetHeader()->GetTargetPath(), target_apk_path); ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path); } @@ -370,38 +358,19 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) { ASSERT_EQ(overlay_entries.size(), 0U); } -TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) { - std::string target_apk_path(GetTestDataPath()); - for (int i = 0; i < 32; i++) { - target_apk_path += "/target/../"; - } - target_apk_path += "/target/target.apk"; - ASSERT_GT(target_apk_path.size(), kIdmapStringLength); - std::unique_ptr target_apk = ApkAssets::Load(target_apk_path); - ASSERT_THAT(target_apk, NotNull()); - - const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk"); - std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); - ASSERT_THAT(overlay_apk, NotNull()); - - const auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); - ASSERT_FALSE(result); -} - TEST(IdmapTests, IdmapHeaderIsUpToDate) { fclose(stderr); // silence expected warnings from libandroidfw - const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); - std::unique_ptr target_apk = ApkAssets::Load(target_apk_path); - ASSERT_THAT(target_apk, NotNull()); + const std::string target_apk_path = idmap_raw_data_target_path; + const std::string overlay_apk_path = idmap_raw_data_overlay_path; + const PolicyBitmask policies = idmap_raw_data_policies; + const uint32_t target_crc = idmap_raw_data_target_crc; + const uint32_t overlay_crc = idmap_raw_data_overlay_crc; - const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk"); - std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); - ASSERT_THAT(overlay_apk, NotNull()); + std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); + std::istringstream raw_stream(raw); - auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); + auto result = Idmap::FromBinaryStream(raw_stream); ASSERT_TRUE(result); const auto idmap = std::move(*result); @@ -411,8 +380,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { std::unique_ptr header = IdmapHeader::FromBinaryStream(stream); ASSERT_THAT(header, NotNull()); - ASSERT_TRUE(header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_TRUE(header->IsUpToDate(target_apk_path, overlay_apk_path, idmap_raw_data_target_crc, + overlay_crc, policies, /* enforce_overlayable */ true)); // magic: bytes (0x0, 0x03) std::string bad_magic_string(stream.str()); @@ -425,8 +394,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_magic_stream); ASSERT_THAT(bad_magic_header, NotNull()); ASSERT_NE(header->GetMagic(), bad_magic_header->GetMagic()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, /* enforce_overlayable */ true)); // version: bytes (0x4, 0x07) std::string bad_version_string(stream.str()); @@ -439,8 +408,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_version_stream); ASSERT_THAT(bad_version_header, NotNull()); ASSERT_NE(header->GetVersion(), bad_version_header->GetVersion()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, /* enforce_overlayable */ true)); // target crc: bytes (0x8, 0xb) std::string bad_target_crc_string(stream.str()); @@ -453,8 +422,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_target_crc_stream); ASSERT_THAT(bad_target_crc_header, NotNull()); ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, /* enforce_overlayable */ true)); // overlay crc: bytes (0xc, 0xf) std::string bad_overlay_crc_string(stream.str()); @@ -467,8 +436,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_overlay_crc_stream); ASSERT_THAT(bad_overlay_crc_header, NotNull()); ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, /* enforce_overlayable */ true)); // fulfilled policy: bytes (0x10, 0x13) std::string bad_policy_string(stream.str()); @@ -481,8 +450,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_policy_stream); ASSERT_THAT(bad_policy_header, NotNull()); ASSERT_NE(header->GetFulfilledPolicies(), bad_policy_header->GetFulfilledPolicies()); - ASSERT_FALSE(bad_policy_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_policy_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, + /* enforce_overlayable */ true)); // enforce overlayable: bytes (0x14) std::string bad_enforce_string(stream.str()); @@ -492,30 +462,32 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_enforce_stream); ASSERT_THAT(bad_enforce_header, NotNull()); ASSERT_NE(header->GetEnforceOverlayable(), bad_enforce_header->GetEnforceOverlayable()); - ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, + /* enforce_overlayable */ true)); - // target path: bytes (0x18, 0x117) + // target path: bytes (0x1c, 0x27) std::string bad_target_path_string(stream.str()); - bad_target_path_string[0x18] = '\0'; + bad_target_path_string[0x1c] = '\0'; std::stringstream bad_target_path_stream(bad_target_path_string); std::unique_ptr bad_target_path_header = IdmapHeader::FromBinaryStream(bad_target_path_stream); ASSERT_THAT(bad_target_path_header, NotNull()); ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, /* enforce_overlayable */ true)); - // overlay path: bytes (0x118, 0x217) + // overlay path: bytes (0x2c, 0x37) std::string bad_overlay_path_string(stream.str()); - bad_overlay_path_string[0x118] = '\0'; + bad_overlay_path_string[0x33] = '\0'; std::stringstream bad_overlay_path_stream(bad_overlay_path_string); std::unique_ptr bad_overlay_path_header = IdmapHeader::FromBinaryStream(bad_overlay_path_stream); ASSERT_THAT(bad_overlay_path_header, NotNull()); ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_overlay_path_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc, + overlay_crc, policies, + /* enforce_overlayable */ true)); } class TestVisitor : public Visitor { diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index 95bd94733ab37..b7ea22aa4a2e9 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -65,7 +65,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { (*idmap)->accept(&visitor); ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str()); - ASSERT_CONTAINS_REGEX(ADDRESS "00000005 version\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000006 version\n", stream.str()); ASSERT_CONTAINS_REGEX( StringPrintf(ADDRESS "%s target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING), stream.str()); @@ -85,7 +85,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "000000b4 string pool size\n", stream.str()); - ASSERT_CONTAINS_REGEX("000002bc: ........ string pool: ...\n", stream.str()); + ASSERT_CONTAINS_REGEX("000001bc: ........ string pool\n", stream.str()); } TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { @@ -102,7 +102,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { (*idmap)->accept(&visitor); ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str()); - ASSERT_CONTAINS_REGEX(ADDRESS "00000005 version\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000006 version\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "00001234 target crc\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "00005678 overlay crc\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "00000011 fulfilled policies: public|signature\n", stream.str()); @@ -121,7 +121,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 overlay id\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "7f030002 target id\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "00000004 string pool size\n", stream.str()); - ASSERT_CONTAINS_REGEX("00000278: ........ string pool: ...\n", stream.str()); + ASSERT_CONTAINS_REGEX("00000098: ........ string pool\n", stream.str()); } } // namespace android::idmap2 diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h index d0a8e3db8ecae..5c934a33ebb66 100644 --- a/cmds/idmap2/tests/TestHelpers.h +++ b/cmds/idmap2/tests/TestHelpers.h @@ -30,7 +30,7 @@ const unsigned char idmap_raw_data[] = { 0x49, 0x44, 0x4d, 0x50, // 0x4: version - 0x05, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, // 0x8: target crc 0x34, 0x12, 0x00, 0x00, @@ -44,125 +44,107 @@ const unsigned char idmap_raw_data[] = { // 0x14: enforce overlayable 0x01, 0x00, 0x00, 0x00, - // 0x18: target path "targetX.apk" - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x18: target path length + 0x0b, 0x00, 0x00, 0x00, - // 0x118: overlay path "overlayX.apk" - 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x1c: target path "targetX.apk" + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, - // 0x218: debug string + // 0x28: overlay path length + 0x0c, 0x00, 0x00, 0x00, + + // 0x2c: overlay path "overlayX.apk" + 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x58, 0x2e, 0x61, 0x70, 0x6b, + + // 0x38: debug string // string length, 0x05, 0x00, 0x00, 0x00, - // 0x21c string contents "debug\0\0\0" (padded to word alignment) + // 0x3c string contents "debug\0\0\0" (padded to word alignment) 0x64, 0x65, 0x62, 0x75, 0x67, 0x00, 0x00, 0x00, // DATA HEADER - // 0x224: target_package_id + // 0x44: target_package_id 0x7f, - // 0x225: overlay_package_id + // 0x45: overlay_package_id 0x7f, - // 0x226: padding + // 0x46: padding 0x00, 0x00, - // 0x228: target_entry_count + // 0x48: target_entry_count 0x03, 0x00, 0x00, 0x00, - // 0x22c: target_inline_entry_count + // 0x4c: target_inline_entry_count 0x01, 0x00, 0x00, 0x00, - // 0x230: overlay_entry_count + // 0x50: overlay_entry_count 0x03, 0x00, 0x00, 0x00, - // 0x234: string_pool_offset + // 0x54: string_pool_offset 0x00, 0x00, 0x00, 0x00, // TARGET ENTRIES - // 0x238: target id (0x7f020000) + // 0x58: target id (0x7f020000) 0x00, 0x00, 0x02, 0x7f, - // 0x23c: overlay_id (0x7f020000) + // 0x5c: overlay_id (0x7f020000) 0x00, 0x00, 0x02, 0x7f, - // 0x240: target id (0x7f030000) + // 0x60: target id (0x7f030000) 0x00, 0x00, 0x03, 0x7f, - // 0x244: overlay_id (0x7f030000) + // 0x64: overlay_id (0x7f030000) 0x00, 0x00, 0x03, 0x7f, - // 0x248: target id (0x7f030002) + // 0x68: target id (0x7f030002) 0x02, 0x00, 0x03, 0x7f, - // 0x24c: overlay_id (0x7f030001) + // 0x6c: overlay_id (0x7f030001) 0x01, 0x00, 0x03, 0x7f, // INLINE TARGET ENTRIES - // 0x250: target_id + // 0x70: target_id 0x00, 0x00, 0x04, 0x7f, - // 0x254: Res_value::size (value ignored by idmap) + // 0x74: Res_value::size (value ignored by idmap) 0x08, 0x00, - // 0x256: Res_value::res0 (value ignored by idmap) + // 0x77: Res_value::res0 (value ignored by idmap) 0x00, - // 0x257: Res_value::dataType (TYPE_INT_HEX) + // 0x78: Res_value::dataType (TYPE_INT_HEX) 0x11, - // 0x258: Res_value::data + // 0x7c: Res_value::data 0x78, 0x56, 0x34, 0x12, // OVERLAY ENTRIES - // 0x25c: 0x7f020000 -> 0x7f020000 + // 0x80: 0x7f020000 -> 0x7f020000 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f, - // 0x264: 0x7f030000 -> 0x7f030000 + // 0x88: 0x7f030000 -> 0x7f030000 0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f, - // 0x26c: 0x7f030001 -> 0x7f030002 + // 0x90: 0x7f030001 -> 0x7f030002 0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f, - // 0x274: string pool + // 0x94: string pool // string length, 0x04, 0x00, 0x00, 0x00, - // 0x278 string contents "test" (padded to word alignment) + // 0x98 string contents "test" 0x74, 0x65, 0x73, 0x74}; -const unsigned int idmap_raw_data_len = 0x27c; +const unsigned int idmap_raw_data_len = 0x9c; +const unsigned int idmap_raw_data_offset = 0x44; +const unsigned int idmap_raw_data_target_crc = 0x1234; +const unsigned int idmap_raw_data_overlay_crc = 0x5678; +const unsigned int idmap_raw_data_policies = 0x11; +inline const std::string idmap_raw_data_target_path = "targetX.apk"; +inline const std::string idmap_raw_data_overlay_path = "overlayX.apk"; std::string GetTestDataPath(); diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index cb56a5172a455..011a0de8031f8 100755 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -385,7 +385,7 @@ std::unique_ptr ApkAssets::LoadOverlay(const std::string& idmap return {}; } - auto overlay_path = loaded_idmap->OverlayApkPath(); + auto overlay_path = std::string(loaded_idmap->OverlayApkPath()); auto assets = ZipAssetsProvider::Create(overlay_path); return (assets) ? LoadImpl(std::move(assets), overlay_path, flags | PROPERTY_OVERLAY, nullptr /* override_asset */, std::move(idmap_asset), diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index bec80a7d605eb..3f0600040139c 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -157,7 +157,8 @@ void AssetManager2::BuildDynamicRefTable() { // The target package must precede the overlay package in the apk assets paths in order // to take effect. const auto& loaded_idmap = apk_assets->GetLoadedIdmap(); - auto target_package_iter = apk_assets_package_ids.find(loaded_idmap->TargetApkPath()); + auto target_package_iter = apk_assets_package_ids.find( + std::string(loaded_idmap->TargetApkPath())); if (target_package_iter == apk_assets_package_ids.end()) { LOG(INFO) << "failed to find target package for overlay " << loaded_idmap->OverlayApkPath(); diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp index a613095141432..68844be6d14a5 100644 --- a/libs/androidfw/Idmap.cpp +++ b/libs/androidfw/Idmap.cpp @@ -36,13 +36,51 @@ using ::android::base::StringPrintf; namespace android { -uint32_t round_to_4_bytes(uint32_t size) { - return size + (4U - (size % 4U)) % 4U; -} +// See frameworks/base/cmds/idmap2/include/idmap2/Idmap.h for full idmap file format specification. +struct Idmap_header { + // Always 0x504D4449 ('IDMP') + uint32_t magic; + uint32_t version; -size_t Idmap_header::Size() const { - return sizeof(Idmap_header) + sizeof(uint8_t) * round_to_4_bytes(dtohl(debug_info_size)); -} + uint32_t target_crc32; + uint32_t overlay_crc32; + + uint32_t fulfilled_policies; + uint32_t enforce_overlayable; + + // overlay_path, target_path, and other string values encoded in the idmap header and read and + // stored in separate structures. This allows the idmap header data to be casted to this struct + // without having to read/store each header entry separately. +}; + +struct Idmap_data_header { + uint8_t target_package_id; + uint8_t overlay_package_id; + + // Padding to ensure 4 byte alignment for target_entry_count + uint16_t p0; + + uint32_t target_entry_count; + uint32_t target_inline_entry_count; + uint32_t overlay_entry_count; + + uint32_t string_pool_index_offset; +}; + +struct Idmap_target_entry { + uint32_t target_id; + uint32_t overlay_id; +}; + +struct Idmap_target_entry_inline { + uint32_t target_id; + Res_value value; +}; + +struct Idmap_overlay_entry { + uint32_t overlay_id; + uint32_t target_id; +}; OverlayStringPool::OverlayStringPool(const LoadedIdmap* loaded_idmap) : data_header_(loaded_idmap->data_header_), @@ -155,140 +193,132 @@ IdmapResMap::Result IdmapResMap::Lookup(uint32_t target_res_id) const { return {}; } -static bool is_word_aligned(const void* data) { - return (reinterpret_cast(data) & 0x03U) == 0U; +namespace { +template +const T* ReadType(const uint8_t** in_out_data_ptr, size_t* in_out_size, const std::string& label, + size_t count = 1) { + if (!util::IsFourByteAligned(*in_out_data_ptr)) { + LOG(ERROR) << "Idmap " << label << " is not word aligned."; + return {}; + } + if ((*in_out_size / sizeof(T)) < count) { + LOG(ERROR) << "Idmap too small for the number of " << label << " entries (" + << count << ")."; + return nullptr; + } + auto data_ptr = *in_out_data_ptr; + const size_t read_size = sizeof(T) * count; + *in_out_data_ptr += read_size; + *in_out_size -= read_size; + return reinterpret_cast(data_ptr); } -static bool IsValidIdmapHeader(const StringPiece& data) { - if (!is_word_aligned(data.data())) { - LOG(ERROR) << "Idmap header is not word aligned."; - return false; +std::optional ReadString(const uint8_t** in_out_data_ptr, size_t* in_out_size, + const std::string& label) { + const auto* len = ReadType(in_out_data_ptr, in_out_size, label + " length"); + if (len == nullptr) { + return {}; } - - if (data.size() < sizeof(Idmap_header)) { - LOG(ERROR) << "Idmap header is too small."; - return false; + const auto* data = ReadType(in_out_data_ptr, in_out_size, label, *len); + if (data == nullptr) { + return {}; } - - auto header = reinterpret_cast(data.data()); - if (dtohl(header->magic) != kIdmapMagic) { - LOG(ERROR) << StringPrintf("Invalid Idmap file: bad magic value (was 0x%08x, expected 0x%08x)", - dtohl(header->magic), kIdmapMagic); - return false; + // Strings are padded to the next 4 byte boundary. + const uint32_t padding_size = (4U - ((size_t)*in_out_data_ptr & 0x3U)) % 4U; + for (uint32_t i = 0; i < padding_size; i++) { + if (**in_out_data_ptr != 0) { + LOG(ERROR) << " Idmap padding of " << label << " is non-zero."; + return {}; + } + *in_out_data_ptr += sizeof(uint8_t); + *in_out_size -= sizeof(uint8_t); } - - if (dtohl(header->version) != kIdmapCurrentVersion) { - // We are strict about versions because files with this format are auto-generated and don't need - // backwards compatibility. - LOG(ERROR) << StringPrintf("Version mismatch in Idmap (was 0x%08x, expected 0x%08x)", - dtohl(header->version), kIdmapCurrentVersion); - return false; - } - - return true; + return std::string_view(data, *len); +} } LoadedIdmap::LoadedIdmap(std::string&& idmap_path, - const time_t last_mod_time, const Idmap_header* header, const Idmap_data_header* data_header, const Idmap_target_entry* target_entries, const Idmap_target_entry_inline* target_inline_entries, const Idmap_overlay_entry* overlay_entries, - ResStringPool* string_pool) + std::unique_ptr&& string_pool, + std::string_view overlay_apk_path, + std::string_view target_apk_path) : header_(header), data_header_(data_header), target_entries_(target_entries), target_inline_entries_(target_inline_entries), overlay_entries_(overlay_entries), - string_pool_(string_pool), + string_pool_(std::move(string_pool)), idmap_path_(std::move(idmap_path)), - idmap_last_mod_time_(last_mod_time) { - - size_t length = strnlen(reinterpret_cast(header_->overlay_path), - arraysize(header_->overlay_path)); - overlay_apk_path_.assign(reinterpret_cast(header_->overlay_path), length); - - length = strnlen(reinterpret_cast(header_->target_path), - arraysize(header_->target_path)); - target_apk_path_.assign(reinterpret_cast(header_->target_path), length); -} + overlay_apk_path_(overlay_apk_path), + target_apk_path_(target_apk_path), + idmap_last_mod_time_(getFileModDate(idmap_path_.data())) {} std::unique_ptr LoadedIdmap::Load(const StringPiece& idmap_path, const StringPiece& idmap_data) { ATRACE_CALL(); - if (!IsValidIdmapHeader(idmap_data)) { + size_t data_size = idmap_data.size(); + auto data_ptr = reinterpret_cast(idmap_data.data()); + + // Parse the idmap header + auto header = ReadType(&data_ptr, &data_size, "header"); + if (header == nullptr) { + return {}; + } + if (dtohl(header->magic) != kIdmapMagic) { + LOG(ERROR) << StringPrintf("Invalid Idmap file: bad magic value (was 0x%08x, expected 0x%08x)", + dtohl(header->magic), kIdmapMagic); + return {}; + } + if (dtohl(header->version) != kIdmapCurrentVersion) { + // We are strict about versions because files with this format are generated at runtime and + // don't need backwards compatibility. + LOG(ERROR) << StringPrintf("Version mismatch in Idmap (was 0x%08x, expected 0x%08x)", + dtohl(header->version), kIdmapCurrentVersion); + return {}; + } + std::optional overlay_path = ReadString(&data_ptr, &data_size, "overlay path"); + if (!overlay_path) { + return {}; + } + std::optional target_path = ReadString(&data_ptr, &data_size, "target path"); + if (!target_path) { + return {}; + } + if (!ReadString(&data_ptr, &data_size, "debug info")) { return {}; } - auto header = reinterpret_cast(idmap_data.data()); - const uint8_t* data_ptr = reinterpret_cast(idmap_data.data()) + header->Size(); - size_t data_size = idmap_data.size() - header->Size(); - - // Currently idmap2 can only generate one data block. - auto data_header = reinterpret_cast(data_ptr); - data_ptr += sizeof(*data_header); - data_size -= sizeof(*data_header); - - // Make sure there is enough space for the target entries declared in the header - const auto target_entries = reinterpret_cast(data_ptr); - if (data_size / sizeof(Idmap_target_entry) < - static_cast(dtohl(data_header->target_entry_count))) { - LOG(ERROR) << StringPrintf("Idmap too small for the number of target entries (%d)", - (int)dtohl(data_header->target_entry_count)); + // Parse the idmap data blocks. Currently idmap2 can only generate one data block. + auto data_header = ReadType(&data_ptr, &data_size, "data header"); + if (data_header == nullptr) { return {}; } - - // Advance the data pointer past the target entries. - const size_t target_entry_size_bytes = - (dtohl(data_header->target_entry_count) * sizeof(Idmap_target_entry)); - data_ptr += target_entry_size_bytes; - data_size -= target_entry_size_bytes; - - // Make sure there is enough space for the target entries declared in the header. - const auto target_inline_entries = reinterpret_cast(data_ptr); - if (data_size / sizeof(Idmap_target_entry_inline) < - static_cast(dtohl(data_header->target_inline_entry_count))) { - LOG(ERROR) << StringPrintf("Idmap too small for the number of target inline entries (%d)", - (int)dtohl(data_header->target_inline_entry_count)); + auto target_entries = ReadType(&data_ptr, &data_size, "target", + dtohl(data_header->target_entry_count)); + if (target_entries == nullptr) { return {}; } - - // Advance the data pointer past the target entries. - const size_t target_inline_entry_size_bytes = - (dtohl(data_header->target_inline_entry_count) * sizeof(Idmap_target_entry_inline)); - data_ptr += target_inline_entry_size_bytes; - data_size -= target_inline_entry_size_bytes; - - // Make sure there is enough space for the overlay entries declared in the header. - const auto overlay_entries = reinterpret_cast(data_ptr); - if (data_size / sizeof(Idmap_overlay_entry) < - static_cast(dtohl(data_header->overlay_entry_count))) { - LOG(ERROR) << StringPrintf("Idmap too small for the number of overlay entries (%d)", - (int)dtohl(data_header->overlay_entry_count)); + auto target_inline_entries = ReadType( + &data_ptr, &data_size, "target inline", dtohl(data_header->target_inline_entry_count)); + if (target_inline_entries == nullptr) { return {}; } - - // Advance the data pointer past the overlay entries. - const size_t overlay_entry_size_bytes = - (dtohl(data_header->overlay_entry_count) * sizeof(Idmap_overlay_entry)); - data_ptr += overlay_entry_size_bytes; - data_size -= overlay_entry_size_bytes; - - // Read the idmap string pool that holds the value of inline string entries. - uint32_t string_pool_size = dtohl(*reinterpret_cast(data_ptr)); - data_ptr += sizeof(uint32_t); - data_size -= sizeof(uint32_t); - - if (data_size < string_pool_size) { - LOG(ERROR) << StringPrintf("Idmap too small for string pool (length %d)", - (int)string_pool_size); + auto overlay_entries = ReadType(&data_ptr, &data_size, "target inline", + dtohl(data_header->overlay_entry_count)); + if (overlay_entries == nullptr) { + return {}; + } + std::optional string_pool = ReadString(&data_ptr, &data_size, "string pool"); + if (!string_pool) { return {}; } - auto idmap_string_pool = util::make_unique(); - if (string_pool_size > 0) { - status_t err = idmap_string_pool->setTo(data_ptr, string_pool_size); + if (!string_pool->empty()) { + const status_t err = idmap_string_pool->setTo(string_pool->data(), string_pool->size()); if (err != NO_ERROR) { LOG(ERROR) << "idmap string pool corrupt."; return {}; @@ -296,12 +326,10 @@ std::unique_ptr LoadedIdmap::Load(const StringPiece& idmap_pa } // Can't use make_unique because LoadedIdmap constructor is private. - auto loaded_idmap = std::unique_ptr( - new LoadedIdmap(idmap_path.to_string(), getFileModDate(idmap_path.data()), header, - data_header, target_entries, target_inline_entries, overlay_entries, - idmap_string_pool.release())); - - return std::move(loaded_idmap); + return std::unique_ptr( + new LoadedIdmap(idmap_path.to_string(), header, data_header, target_entries, + target_inline_entries, overlay_entries, std::move(idmap_string_pool), + *target_path, *overlay_path)); } bool LoadedIdmap::IsUpToDate() const { diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h index fdab03ba2de44..fd9a8d13e0c68 100644 --- a/libs/androidfw/include/androidfw/Idmap.h +++ b/libs/androidfw/include/androidfw/Idmap.h @@ -31,6 +31,11 @@ namespace android { class LoadedIdmap; class IdmapResMap; +struct Idmap_header; +struct Idmap_data_header; +struct Idmap_target_entry; +struct Idmap_target_entry_inline; +struct Idmap_overlay_entry; // A string pool for overlay apk assets. The string pool holds the strings of the overlay resources // table and additionally allows for loading strings from the idmap string pool. The idmap string @@ -148,29 +153,29 @@ class LoadedIdmap { const StringPiece& idmap_data); // Returns the path to the IDMAP. - inline const std::string& IdmapPath() const { + std::string_view IdmapPath() const { return idmap_path_; } // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated. - inline const std::string& OverlayApkPath() const { + std::string_view OverlayApkPath() const { return overlay_apk_path_; } // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated. - inline const std::string& TargetApkPath() const { + std::string_view TargetApkPath() const { return target_apk_path_; } // Returns a mapping from target resource ids to overlay values. - inline const IdmapResMap GetTargetResourcesMap( + const IdmapResMap GetTargetResourcesMap( uint8_t target_assigned_package_id, const OverlayDynamicRefTable* overlay_ref_table) const { return IdmapResMap(data_header_, target_entries_, target_inline_entries_, target_assigned_package_id, overlay_ref_table); } // Returns a dynamic reference table for a loaded overlay package. - inline const OverlayDynamicRefTable GetOverlayDynamicRefTable( + const OverlayDynamicRefTable GetOverlayDynamicRefTable( uint8_t target_assigned_package_id) const { return OverlayDynamicRefTable(data_header_, overlay_entries_, target_assigned_package_id); } @@ -190,22 +195,23 @@ class LoadedIdmap { const Idmap_overlay_entry* overlay_entries_; const std::unique_ptr string_pool_; - const std::string idmap_path_; - std::string overlay_apk_path_; - std::string target_apk_path_; - const time_t idmap_last_mod_time_; + std::string idmap_path_; + std::string_view overlay_apk_path_; + std::string_view target_apk_path_; + time_t idmap_last_mod_time_; private: DISALLOW_COPY_AND_ASSIGN(LoadedIdmap); explicit LoadedIdmap(std::string&& idmap_path, - time_t last_mod_time, const Idmap_header* header, const Idmap_data_header* data_header, const Idmap_target_entry* target_entries, const Idmap_target_entry_inline* target_inline_entries, const Idmap_overlay_entry* overlay_entries, - ResStringPool* string_pool); + std::unique_ptr&& string_pool, + std::string_view overlay_apk_path, + std::string_view target_apk_path); friend OverlayStringPool; }; diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index fb5f864731891..d1622a03a318c 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -44,7 +44,7 @@ namespace android { constexpr const static uint32_t kIdmapMagic = 0x504D4449u; -constexpr const static uint32_t kIdmapCurrentVersion = 0x00000005u; +constexpr const static uint32_t kIdmapCurrentVersion = 0x00000006u; /** * In C++11, char16_t is defined as *at least* 16 bits. We do a lot of @@ -1700,56 +1700,6 @@ inline ResTable_overlayable_policy_header::PolicyFlags& operator |=( return first; } -struct Idmap_header { - // Always 0x504D4449 ('IDMP') - uint32_t magic; - - uint32_t version; - - uint32_t target_crc32; - uint32_t overlay_crc32; - - uint32_t fulfilled_policies; - uint32_t enforce_overlayable; - - uint8_t target_path[256]; - uint8_t overlay_path[256]; - - uint32_t debug_info_size; - uint8_t debug_info[0]; - - size_t Size() const; -}; - -struct Idmap_data_header { - uint8_t target_package_id; - uint8_t overlay_package_id; - - // Padding to ensure 4 byte alignment for target_entry_count - uint16_t p0; - - uint32_t target_entry_count; - uint32_t target_inline_entry_count; - uint32_t overlay_entry_count; - - uint32_t string_pool_index_offset; -}; - -struct Idmap_target_entry { - uint32_t target_id; - uint32_t overlay_id; -}; - -struct Idmap_target_entry_inline { - uint32_t target_id; - Res_value value; -}; - -struct Idmap_overlay_entry { - uint32_t overlay_id; - uint32_t target_id; -}; - class AssetManager2; /** diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h index aceeeccccb611..c59b5b6c51a2d 100644 --- a/libs/androidfw/include/androidfw/Util.h +++ b/libs/androidfw/include/androidfw/Util.h @@ -128,10 +128,14 @@ std::string Utf16ToUtf8(const StringPiece16& utf16); std::vector SplitAndLowercase(const android::StringPiece& str, char sep); template -bool IsFourByteAligned(const incfs::map_ptr& data) { +inline bool IsFourByteAligned(const incfs::map_ptr& data) { return ((size_t)data.unsafe_ptr() & 0x3U) == 0; } +inline bool IsFourByteAligned(const void* data) { + return ((size_t)data & 0x3U) == 0; +} + } // namespace util } // namespace android diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap index 3ab244eb084abba68dc2c83ea4000270608bb31c..6f0104a52f68fa6ad6777a3f763c43a46f514808 100644 GIT binary patch delta 62 zcmX@Y@rOmy)5SM{je&u|H>8k$w( literal 1092 zcmd^;Jx;?w5QWF_UlNoki6bfs3MvXrBz}7eQbbBYi4-mIVpcddayB7UE)chXOK=J* zS~^a_0eE9T z-v0foSaZ4df3xoOKbvJl4HRm?1-wseGBSg#%z@URZlQIkiRT8?f;OQZS=dT7Ofi53 z*gL??Hc+d>@Jvi)-`UMQ_i`V@-cUQfkZhBEc1Nqnus2_DI^l$JB-D1~KzyFg_Za+STgZ=9A ifIRPa_hDuAsIq!oSv{$&o|5Bek%m%}Z7)T%kVM}E8j)21