Loading libs/androidfw/ChunkIterator.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -32,11 +32,30 @@ Chunk ChunkIterator::Next() { if (len_ != 0) { // Prepare the next chunk. 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_); Loading libs/androidfw/LoadedArsc.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -560,8 +560,10 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); if (iter.HadFatalError()) { return {}; } } // Flatten and construct the TypeSpecs. for (auto& entry : type_builder_map) { Loading Loading @@ -641,8 +643,10 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); if (iter.HadFatalError()) { return false; } } return true; } Loading Loading @@ -673,8 +677,10 @@ std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); if (iter.HadFatalError()) { return {}; } } // Need to force a move for mingw32. return std::move(loaded_arsc); Loading libs/androidfw/include/androidfw/Chunk.h +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
libs/androidfw/ChunkIterator.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -32,11 +32,30 @@ Chunk ChunkIterator::Next() { if (len_ != 0) { // Prepare the next chunk. 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_); Loading
libs/androidfw/LoadedArsc.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -560,8 +560,10 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); if (iter.HadFatalError()) { return {}; } } // Flatten and construct the TypeSpecs. for (auto& entry : type_builder_map) { Loading Loading @@ -641,8 +643,10 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); if (iter.HadFatalError()) { return false; } } return true; } Loading Loading @@ -673,8 +677,10 @@ std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data, if (iter.HadError()) { LOG(ERROR) << iter.GetLastError(); if (iter.HadFatalError()) { return {}; } } // Need to force a move for mingw32. return std::move(loaded_arsc); Loading
libs/androidfw/include/androidfw/Chunk.h +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading