diff options
author | 2018-09-12 08:54:07 -0700 | |
---|---|---|
committer | 2018-09-12 08:54:07 -0700 | |
commit | e0eba7a3bb951906476d16731a214f65b50f27f1 (patch) | |
tree | b2b522f081230f8e685baea7f32fe18721b24a92 | |
parent | 342df6ddd178d55aa94e01ff94e5be00457f3440 (diff) |
AAPT2: Increase maximum proto size
Deserializing a proto form a string throws an error when 64MB have been
read from the stream. This change removes the maximum size but shows a
warning when a proto is larger than 64MB.
Bug: 114020398
Test: manual test with resources.pb greater than 64MB
Change-Id: Iee397b6709d79a9338133a6136fe6e8f70a4964c
-rw-r--r-- | tools/aapt2/LoadedApk.cpp | 16 | ||||
-rw-r--r-- | tools/aapt2/cmd/Convert.cpp | 4 | ||||
-rw-r--r-- | tools/aapt2/io/Util.h | 18 |
3 files changed, 28 insertions, 10 deletions
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp index a73d56c8f951..c610b667c5b9 100644 --- a/tools/aapt2/LoadedApk.cpp +++ b/tools/aapt2/LoadedApk.cpp @@ -69,8 +69,8 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection( return {}; } - io::ZeroCopyInputAdaptor adaptor(in.get()); - if (!pb_table.ParseFromZeroCopyStream(&adaptor)) { + io::ProtoInputStreamReader proto_reader(in.get()); + if (!proto_reader.ReadMessage(&pb_table)) { diag->Error(DiagMessage(source) << "failed to read " << kProtoResourceTablePath); return {}; } @@ -97,8 +97,8 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection( } pb::XmlNode pb_node; - io::ZeroCopyInputAdaptor manifest_adaptor(manifest_in.get()); - if (!pb_node.ParseFromZeroCopyStream(&manifest_adaptor)) { + io::ProtoInputStreamReader proto_reader(manifest_in.get()); + if (!proto_reader.ReadMessage(&pb_node)) { diag->Error(DiagMessage(source) << "failed to read proto " << kAndroidManifestPath); return {}; } @@ -270,9 +270,9 @@ std::unique_ptr<xml::XmlResource> LoadedApk::LoadXml(const std::string& file_pat return nullptr; } - io::ZeroCopyInputAdaptor adaptor(in.get()); pb::XmlNode pb_node; - if (!pb_node.ParseFromZeroCopyStream(&adaptor)) { + io::ProtoInputStreamReader proto_reader(in.get()); + if (!proto_reader.ReadMessage(&pb_node)) { diag->Error(DiagMessage() << "failed to parse file as proto XML"); return nullptr; } @@ -317,8 +317,8 @@ ApkFormat LoadedApk::DetermineApkFormat(io::IFileCollection* apk) { std::unique_ptr<io::InputStream> manifest_in = manifest_file->OpenInputStream(); if (manifest_in != nullptr) { pb::XmlNode pb_node; - io::ZeroCopyInputAdaptor manifest_adaptor(manifest_in.get()); - if (pb_node.ParseFromZeroCopyStream(&manifest_adaptor)) { + io::ProtoInputStreamReader proto_reader(manifest_in.get()); + if (!proto_reader.ReadMessage(&pb_node)) { return ApkFormat::kProto; } } diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp index 86b1f4c54deb..954f1ed3fb72 100644 --- a/tools/aapt2/cmd/Convert.cpp +++ b/tools/aapt2/cmd/Convert.cpp @@ -170,8 +170,8 @@ class BinaryApkSerializer : public IApkSerializer { } pb::XmlNode pb_node; - io::ZeroCopyInputAdaptor adaptor(in.get()); - if (!pb_node.ParseFromZeroCopyStream(&adaptor)) { + io::ProtoInputStreamReader proto_reader(in.get()); + if (!proto_reader.ReadMessage(&pb_node)) { context_->GetDiagnostics()->Error(DiagMessage(source_) << "failed to parse proto XML " << *file->path); return false; diff --git a/tools/aapt2/io/Util.h b/tools/aapt2/io/Util.h index b07fb5399313..5f978a8e2c35 100644 --- a/tools/aapt2/io/Util.h +++ b/tools/aapt2/io/Util.h @@ -20,6 +20,7 @@ #include <string> #include "google/protobuf/message_lite.h" +#include "google/protobuf/io/coded_stream.h" #include "format/Archive.h" #include "io/File.h" @@ -122,6 +123,23 @@ class ZeroCopyInputAdaptor : public ::google::protobuf::io::ZeroCopyInputStream io::InputStream* in_; }; +class ProtoInputStreamReader { + public: + explicit ProtoInputStreamReader(io::InputStream* in) : in_(in) { } + + /** Deserializes a MessageLite proto from the current position in the input stream.*/ + template <typename T> bool ReadMessage(T *message_lite) { + ZeroCopyInputAdaptor adapter(in_); + google::protobuf::io::CodedInputStream coded_stream(&adapter); + coded_stream.SetTotalBytesLimit(std::numeric_limits<int32_t>::max(), + coded_stream.BytesUntilTotalBytesLimit()); + return message_lite->ParseFromCodedStream(&coded_stream); + } + + private: + io::InputStream* in_; +}; + } // namespace io } // namespace aapt |