diff options
| author | 2018-07-16 20:57:43 +0000 | |
|---|---|---|
| committer | 2018-07-16 20:57:43 +0000 | |
| commit | cf0b12711057a2a23dc08f1ac6acfe67892b945d (patch) | |
| tree | f06788c3b9801c4a89e99c1182a00c4ca2e96e7e /libs/androidfw | |
| parent | c450d1401e68cc2492153e4aae6878c5003ce5db (diff) | |
| parent | 28e663cbed28fb6c8c8dec0849e0277daf67651b (diff) | |
Merge "Loosen resource file verification" into pi-dev
Diffstat (limited to 'libs/androidfw')
| -rw-r--r-- | libs/androidfw/ChunkIterator.cpp | 21 | ||||
| -rw-r--r-- | libs/androidfw/LoadedArsc.cpp | 12 | ||||
| -rw-r--r-- | libs/androidfw/include/androidfw/Chunk.h | 9 |
3 files changed, 38 insertions, 4 deletions
diff --git a/libs/androidfw/ChunkIterator.cpp b/libs/androidfw/ChunkIterator.cpp index d8adbe5ac85d..8fc321968055 100644 --- a/libs/androidfw/ChunkIterator.cpp +++ b/libs/androidfw/ChunkIterator.cpp @@ -32,11 +32,30 @@ Chunk ChunkIterator::Next() { if (len_ != 0) { // Prepare the next chunk. - VerifyNextChunk(); + if (VerifyNextChunkNonFatal()) { + VerifyNextChunk(); + } } return Chunk(this_chunk); } +// TODO(b/111401637) remove this and have full resource file verification +// Returns false if there was an error. +bool ChunkIterator::VerifyNextChunkNonFatal() { + if (len_ < sizeof(ResChunk_header)) { + last_error_ = "not enough space for header"; + last_error_was_fatal_ = false; + return false; + } + const size_t size = dtohl(next_chunk_->size); + if (size > len_) { + last_error_ = "chunk size is bigger than given data"; + last_error_was_fatal_ = false; + return false; + } + return true; +} + // Returns false if there was an error. bool ChunkIterator::VerifyNextChunk() { const uintptr_t header_start = reinterpret_cast<uintptr_t>(next_chunk_); diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index 04d506a2d71c..c2740c9fbaa4 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -560,7 +560,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); - return {}; + if (iter.HadFatalError()) { + return {}; + } } // Flatten and construct the TypeSpecs. @@ -641,7 +643,9 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); - return false; + if (iter.HadFatalError()) { + return false; + } } return true; } @@ -673,7 +677,9 @@ std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); - return {}; + if (iter.HadFatalError()) { + return {}; + } } // Need to force a move for mingw32. diff --git a/libs/androidfw/include/androidfw/Chunk.h b/libs/androidfw/include/androidfw/Chunk.h index 89b588e2b2e9..99a52dc9244e 100644 --- a/libs/androidfw/include/androidfw/Chunk.h +++ b/libs/androidfw/include/androidfw/Chunk.h @@ -94,18 +94,27 @@ class ChunkIterator { Chunk Next(); inline bool HasNext() const { return !HadError() && len_ != 0; }; + // Returns whether there was an error and processing should stop inline bool HadError() const { return last_error_ != nullptr; } inline std::string GetLastError() const { return last_error_; } + // Returns whether there was an error and processing should stop. For legacy purposes, + // some errors are considered "non fatal". Fatal errors stop processing new chunks and + // throw away any chunks already processed. Non fatal errors also stop processing new + // chunks, but, will retain and use any valid chunks already processed. + inline bool HadFatalError() const { return HadError() && last_error_was_fatal_; } private: DISALLOW_COPY_AND_ASSIGN(ChunkIterator); // Returns false if there was an error. bool VerifyNextChunk(); + // Returns false if there was an error. For legacy purposes. + bool VerifyNextChunkNonFatal(); const ResChunk_header* next_chunk_; size_t len_; const char* last_error_; + bool last_error_was_fatal_ = true; }; } // namespace android |