diff options
-rw-r--r-- | tools/aapt2/ResourceValues.cpp | 77 | ||||
-rw-r--r-- | tools/aapt2/diff/Diff.cpp | 23 | ||||
-rw-r--r-- | tools/aapt2/dump/Dump.cpp | 83 | ||||
-rw-r--r-- | tools/aapt2/unflatten/BinaryResourceParser.cpp | 1 | ||||
-rw-r--r-- | tools/aapt2/util/Maybe.h | 23 |
5 files changed, 164 insertions, 43 deletions
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp index c10b134cb36e..4a865799372d 100644 --- a/tools/aapt2/ResourceValues.cpp +++ b/tools/aapt2/ResourceValues.cpp @@ -21,6 +21,7 @@ #include "io/File.h" #include "util/Util.h" +#include <algorithm> #include <androidfw/ResourceTypes.h> #include <limits> @@ -302,18 +303,42 @@ Attribute::Attribute(bool w, uint32_t t) : mWeak = w; } +template <typename T> +T* addPointer(T& val) { + return &val; +} + bool Attribute::equals(const Value* value) const { const Attribute* other = valueCast<Attribute>(value); if (!other) { return false; } - return this->typeMask == other->typeMask && this->minInt == other->minInt && - this->maxInt == other->maxInt && - std::equal(this->symbols.begin(), this->symbols.end(), - other->symbols.begin(), - [](const Symbol& a, const Symbol& b) -> bool { - return a.symbol.equals(&b.symbol) && a.value == b.value; + if (symbols.size() != other->symbols.size()) { + return false; + } + + if (typeMask != other->typeMask || minInt != other->minInt || maxInt != other->maxInt) { + return false; + } + + std::vector<const Symbol*> sortedA; + std::transform(symbols.begin(), symbols.end(), + std::back_inserter(sortedA), addPointer<const Symbol>); + std::sort(sortedA.begin(), sortedA.end(), [](const Symbol* a, const Symbol* b) -> bool { + return a->symbol.name < b->symbol.name; + }); + + std::vector<const Symbol*> sortedB; + std::transform(other->symbols.begin(), other->symbols.end(), + std::back_inserter(sortedB), addPointer<const Symbol>); + std::sort(sortedB.begin(), sortedB.end(), [](const Symbol* a, const Symbol* b) -> bool { + return a->symbol.name < b->symbol.name; + }); + + return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(), + [](const Symbol* a, const Symbol* b) -> bool { + return a->symbol.equals(&b->symbol) && a->value == b->value; }); } @@ -526,9 +551,28 @@ bool Style::equals(const Value* value) const { (parent && other->parent && !parent.value().equals(&other->parent.value()))) { return false; } - return std::equal(entries.begin(), entries.end(), other->entries.begin(), - [](const Entry& a, const Entry& b) -> bool { - return a.key.equals(&b.key) && a.value->equals(b.value.get()); + + if (entries.size() != other->entries.size()) { + return false; + } + + std::vector<const Entry*> sortedA; + std::transform(entries.begin(), entries.end(), + std::back_inserter(sortedA), addPointer<const Entry>); + std::sort(sortedA.begin(), sortedA.end(), [](const Entry* a, const Entry* b) -> bool { + return a->key.name < b->key.name; + }); + + std::vector<const Entry*> sortedB; + std::transform(other->entries.begin(), other->entries.end(), + std::back_inserter(sortedB), addPointer<const Entry>); + std::sort(sortedB.begin(), sortedB.end(), [](const Entry* a, const Entry* b) -> bool { + return a->key.name < b->key.name; + }); + + return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(), + [](const Entry* a, const Entry* b) -> bool { + return a->key.equals(&b->key) && a->value->equals(b->value.get()); }); } @@ -563,6 +607,8 @@ void Style::print(std::ostream* out) const { static ::std::ostream& operator<<(::std::ostream& out, const Style::Entry& value) { if (value.key.name) { out << value.key.name.value(); + } else if (value.key.id) { + out << value.key.id.value(); } else { out << "???"; } @@ -577,6 +623,10 @@ bool Array::equals(const Value* value) const { return false; } + if (items.size() != other->items.size()) { + return false; + } + return std::equal(items.begin(), items.end(), other->items.begin(), [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool { return a->equals(b.get()); @@ -605,6 +655,10 @@ bool Plural::equals(const Value* value) const { return false; } + if (values.size() != other->values.size()) { + return false; + } + return std::equal(values.begin(), values.end(), other->values.begin(), [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool { if (bool(a) != bool(b)) { @@ -659,6 +713,11 @@ bool Styleable::equals(const Value* value) const { if (!other) { return false; } + + if (entries.size() != other->entries.size()) { + return false; + } + return std::equal(entries.begin(), entries.end(), other->entries.begin(), [](const Reference& a, const Reference& b) -> bool { return a.equals(&b); diff --git a/tools/aapt2/diff/Diff.cpp b/tools/aapt2/diff/Diff.cpp index 67333a228cdf..1ff6ef6cd2b1 100644 --- a/tools/aapt2/diff/Diff.cpp +++ b/tools/aapt2/diff/Diff.cpp @@ -16,6 +16,7 @@ #include "Flags.h" #include "ResourceTable.h" +#include "ValueVisitor.h" #include "io/ZipArchive.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" @@ -385,6 +386,24 @@ static bool emitResourceTableDiff(IAaptContext* context, LoadedApk* apkA, Loaded return diff; } +class ZeroingReferenceVisitor : public ValueVisitor { +public: + using ValueVisitor::visit; + + void visit(Reference* ref) override { + if (ref->name && ref->id) { + if (ref->id.value().packageId() == 0x7f) { + ref->id = {}; + } + } + } +}; + +static void zeroOutAppReferences(ResourceTable* table) { + ZeroingReferenceVisitor visitor; + visitAllValuesInTable(table, &visitor); +} + int diff(const std::vector<StringPiece>& args) { DiffContext context; @@ -405,6 +424,10 @@ int diff(const std::vector<StringPiece>& args) { return 1; } + // Zero out Application IDs in references. + zeroOutAppReferences(apkA->getResourceTable()); + zeroOutAppReferences(apkB->getResourceTable()); + if (emitResourceTableDiff(&context, apkA.get(), apkB.get())) { // We emitted a diff, so return 1 (failure). return 1; diff --git a/tools/aapt2/dump/Dump.cpp b/tools/aapt2/dump/Dump.cpp index dba2d280fa30..8f0dd3af0788 100644 --- a/tools/aapt2/dump/Dump.cpp +++ b/tools/aapt2/dump/Dump.cpp @@ -20,6 +20,7 @@ #include "io/ZipArchive.h" #include "process/IResourceTableConsumer.h" #include "proto/ProtoSerialize.h" +#include "unflatten/BinaryResourceParser.h" #include "util/Files.h" #include "util/StringPiece.h" @@ -44,18 +45,9 @@ void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data, size_t l << "Source: " << file->source << "\n"; } -void dumpCompiledTable(const pb::ResourceTable& pbTable, const Source& source, - IAaptContext* context) { - std::unique_ptr<ResourceTable> table = deserializeTableFromPb(pbTable, source, - context->getDiagnostics()); - if (!table) { - return; - } - - Debug::printTable(table.get()); -} - void tryDumpFile(IAaptContext* context, const std::string& filePath) { + std::unique_ptr<ResourceTable> table; + std::string err; std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::create(filePath, &err); if (zip) { @@ -75,37 +67,62 @@ void tryDumpFile(IAaptContext* context, const std::string& filePath) { return; } - std::unique_ptr<ResourceTable> table = deserializeTableFromPb( + table = deserializeTableFromPb( pbTable, Source(filePath), context->getDiagnostics()); - if (table) { - DebugPrintTableOptions debugPrintTableOptions; - debugPrintTableOptions.showSources = true; - Debug::printTable(table.get(), debugPrintTableOptions); + if (!table) { + return; } } - return; - } - Maybe<android::FileMap> file = file::mmapPath(filePath, &err); - if (!file) { - context->getDiagnostics()->error(DiagMessage(filePath) << err); - return; + if (!table) { + file = zip->findFile("resources.arsc"); + if (file) { + std::unique_ptr<io::IData> data = file->openAsData(); + if (!data) { + context->getDiagnostics()->error(DiagMessage(filePath) + << "failed to open resources.arsc"); + return; + } + + table = util::make_unique<ResourceTable>(); + BinaryResourceParser parser(context, table.get(), Source(filePath), + data->data(), data->size()); + if (!parser.parse()) { + return; + } + } + } } - android::FileMap* fileMap = &file.value(); + if (!table) { + Maybe<android::FileMap> file = file::mmapPath(filePath, &err); + if (!file) { + context->getDiagnostics()->error(DiagMessage(filePath) << err); + return; + } - // Try as a compiled table. - pb::ResourceTable pbTable; - if (pbTable.ParseFromArray(fileMap->getDataPtr(), fileMap->getDataLength())) { - dumpCompiledTable(pbTable, Source(filePath), context); - return; + android::FileMap* fileMap = &file.value(); + + // Try as a compiled table. + pb::ResourceTable pbTable; + if (pbTable.ParseFromArray(fileMap->getDataPtr(), fileMap->getDataLength())) { + table = deserializeTableFromPb(pbTable, Source(filePath), context->getDiagnostics()); + } + + if (!table) { + // Try as a compiled file. + CompiledFileInputStream input(fileMap->getDataPtr(), fileMap->getDataLength()); + if (const pb::CompiledFile* pbFile = input.CompiledFile()) { + dumpCompiledFile(*pbFile, input.data(), input.size(), Source(filePath), context); + return; + } + } } - // Try as a compiled file. - CompiledFileInputStream input(fileMap->getDataPtr(), fileMap->getDataLength()); - if (const pb::CompiledFile* pbFile = input.CompiledFile()) { - dumpCompiledFile(*pbFile, input.data(), input.size(), Source(filePath), context); - return; + if (table) { + DebugPrintTableOptions debugPrintTableOptions; + debugPrintTableOptions.showSources = true; + Debug::printTable(table.get(), debugPrintTableOptions); } } diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp index 5cd1c8b47ede..d2eccbc4e90e 100644 --- a/tools/aapt2/unflatten/BinaryResourceParser.cpp +++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp @@ -61,7 +61,6 @@ public: auto cacheIter = mMapping->find(id); if (cacheIter != mMapping->end()) { reference->name = cacheIter->second; - reference->id = {}; } } }; diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h index 595db960d5e5..a31bc89fa98b 100644 --- a/tools/aapt2/util/Maybe.h +++ b/tools/aapt2/util/Maybe.h @@ -88,6 +88,8 @@ public: */ const T& value() const; + T valueOrDefault(const T& def) const; + private: template <typename U> friend class Maybe; @@ -263,6 +265,14 @@ const T& Maybe<T>::value() const { } template <typename T> +T Maybe<T>::valueOrDefault(const T& def) const { + if (mNothing) { + return def; + } + return reinterpret_cast<const T&>(mStorage); +} + +template <typename T> void Maybe<T>::destroy() { reinterpret_cast<T&>(mStorage).~T(); } @@ -306,6 +316,19 @@ typename std::enable_if< return !(a == b); } +template <typename T, typename U> +typename std::enable_if< + has_lt_op<T, U>::value, + bool +>::type operator<(const Maybe<T>& a, const Maybe<U>& b) { + if (a && b) { + return a.value() < b.value(); + } else if (!a && !b) { + return false; + } + return !a; +} + } // namespace aapt #endif // AAPT_MAYBE_H |