From 6ff19664f9279023c96e5a65c3059e1ef4beac0f Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Thu, 30 Apr 2015 17:40:46 -0700 Subject: AAPT2: Record public status in a more robust way This allows us to store the source and comments of a resource's public declaration and avoids issues where there is no default configuration for a publicly declared resource (like with drawables of various densities) and AAPT2 mistakenly took this as an error. Change-Id: I07a2fe9f551daefcce842f205fb219d2fa453ebc --- tools/aapt2/BinaryResourceParser.cpp | 59 +++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) (limited to 'tools/aapt2/BinaryResourceParser.cpp') diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp index bad5aa510012..d16f63b5c337 100644 --- a/tools/aapt2/BinaryResourceParser.cpp +++ b/tools/aapt2/BinaryResourceParser.cpp @@ -396,6 +396,12 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) { } break; + case RES_TABLE_PUBLIC_TYPE: + if (!parsePublic(parser.getChunk())) { + return false; + } + break; + default: Logger::warn(mSource) << "unexpected chunk of type " @@ -429,6 +435,55 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) { return true; } +bool BinaryResourceParser::parsePublic(const ResChunk_header* chunk) { + const Public_header* header = convertTo(chunk); + + if (header->typeId == 0) { + Logger::error(mSource) + << "invalid type ID " << header->typeId << std::endl; + return false; + } + + const ResourceType* parsedType = parseResourceType(util::getString(mTypePool, + header->typeId - 1)); + if (!parsedType) { + Logger::error(mSource) + << "invalid type " << util::getString(mTypePool, header->typeId - 1) << std::endl; + return false; + } + + const uintptr_t chunkEnd = reinterpret_cast(chunk) + chunk->size; + const Public_entry* entry = reinterpret_cast( + getChunkData(header->header)); + for (uint32_t i = 0; i < header->count; i++) { + if (reinterpret_cast(entry) + sizeof(*entry) > chunkEnd) { + Logger::error(mSource) + << "Public_entry extends beyond chunk." + << std::endl; + return false; + } + + const ResourceId resId = { mTable->getPackageId(), header->typeId, entry->entryId }; + const ResourceName name = { + mTable->getPackage(), + *parsedType, + util::getString(mKeyPool, entry->key.index).toString() }; + + SourceLine source; + if (mSourcePool.getError() == NO_ERROR) { + source.path = util::utf16ToUtf8(util::getString(mSourcePool, entry->source.index)); + source.line = entry->sourceLine; + } + + if (!mTable->markPublic(name, resId, source)) { + return false; + } + + entry++; + } + return true; +} + bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) { if (mTypePool.getError() != NO_ERROR) { Logger::error(mSource) @@ -636,10 +691,6 @@ std::unique_ptr BinaryResourceParser::parseValue(const ResourceNameRef& na return util::make_unique(nullType); } - if (value->dataType == ExtendedTypes::TYPE_SENTINEL) { - return util::make_unique(); - } - if (value->dataType == ExtendedTypes::TYPE_RAW_STRING) { return util::make_unique( mTable->getValueStringPool().makeRef(util::getString(mValuePool, value->data), -- cgit v1.2.3-59-g8ed1b