From ea13c1a234077203977a6234863c0cb36c43e02f Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 13 Oct 2017 12:40:37 -0700 Subject: [PATCH] AAPT2: Flatten AndroidManifest.xml stringpool in UTF16 A few OEM devices have introduced a memory corruption bug that is only triggered when an application's AndroidManifest.xml uses UTF8 string pools. Workaround this by only encoding AndroidManifest.xml with UTF16 strings. Bug: 64434571 Test: manual Change-Id: I2ee50d1b2b5942d971ef2a544c878de63f67c652 --- tools/aapt2/cmd/Link.cpp | 8 +++++--- tools/aapt2/format/binary/XmlFlattener.cpp | 6 +++++- tools/aapt2/format/binary/XmlFlattener.h | 4 ++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index 88e0f699fd580..8cc2a6169ec6a 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -254,10 +254,11 @@ class FeatureSplitSymbolTableDelegate : public DefaultSymbolTableDelegate { }; static bool FlattenXml(IAaptContext* context, xml::XmlResource* xml_res, const StringPiece& path, - bool keep_raw_values, IArchiveWriter* writer) { + bool keep_raw_values, bool utf16, IArchiveWriter* writer) { BigBuffer buffer(1024); XmlFlattenerOptions options = {}; options.keep_raw_values = keep_raw_values; + options.use_utf16 = utf16; XmlFlattener flattener(&buffer, options); if (!flattener.Consume(context, xml_res)) { return false; @@ -607,7 +608,7 @@ bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archiv } } error |= !FlattenXml(context_, doc.get(), dst_path, options_.keep_raw_values, - archive_writer); + false /*utf16*/, archive_writer); } } else { error |= !io::CopyFileToArchive(context_, file_op.file_to_copy, file_op.dst_path, @@ -1477,7 +1478,8 @@ class LinkCommand { bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest, ResourceTable* table) { const bool keep_raw_values = context_->GetPackageType() == PackageType::kStaticLib; - bool result = FlattenXml(context_, manifest, "AndroidManifest.xml", keep_raw_values, writer); + bool result = FlattenXml(context_, manifest, "AndroidManifest.xml", keep_raw_values, + true /*utf16*/, writer); if (!result) { return false; } diff --git a/tools/aapt2/format/binary/XmlFlattener.cpp b/tools/aapt2/format/binary/XmlFlattener.cpp index f8f09ab0d2a5a..2456c3dfd5e9e 100644 --- a/tools/aapt2/format/binary/XmlFlattener.cpp +++ b/tools/aapt2/format/binary/XmlFlattener.cpp @@ -312,7 +312,11 @@ bool XmlFlattener::Flatten(IAaptContext* context, xml::Node* node) { xml_header_writer.StartChunk(RES_XML_TYPE); // Flatten the StringPool. - StringPool::FlattenUtf8(buffer_, visitor.pool); + if (options_.use_utf16) { + StringPool::FlattenUtf16(buffer_, visitor.pool); + } else { + StringPool::FlattenUtf8(buffer_, visitor.pool); + } { // Write the array of resource IDs, indexed by StringPool order. diff --git a/tools/aapt2/format/binary/XmlFlattener.h b/tools/aapt2/format/binary/XmlFlattener.h index 6a4883512907a..8db2281cd74ab 100644 --- a/tools/aapt2/format/binary/XmlFlattener.h +++ b/tools/aapt2/format/binary/XmlFlattener.h @@ -28,6 +28,10 @@ namespace aapt { struct XmlFlattenerOptions { // Keep attribute raw string values along with typed values. bool keep_raw_values = false; + + // Encode the strings in UTF-16. Only needed for AndroidManifest.xml to avoid a bug in + // certain non-AOSP platforms: https://issuetracker.google.com/64434571 + bool use_utf16 = false; }; class XmlFlattener : public IXmlResourceConsumer {