diff options
Diffstat (limited to 'libs')
| -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 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 5 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 1 |
5 files changed, 44 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 21f023dc0f05..68d216d286cf 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -594,7 +594,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. @@ -675,7 +677,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; } @@ -707,7 +711,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 diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 59048be768e9..020761110ef0 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -87,6 +87,11 @@ void RenderProxy::initialize(const sp<Surface>& surface) { [ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); }); } +void RenderProxy::allocateBuffers(const sp<Surface>& surface) { + mRenderThread.queue().post( + [ surf = surface ]() mutable { surf->allocateBuffers(); }); +} + void RenderProxy::updateSurface(const sp<Surface>& surface) { mRenderThread.queue().post( [ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); }); diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index ad534f0d96b5..0d29b4bcc317 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -70,6 +70,7 @@ public: ANDROID_API void setName(const char* name); ANDROID_API void initialize(const sp<Surface>& surface); + ANDROID_API void allocateBuffers(const sp<Surface>& surface); ANDROID_API void updateSurface(const sp<Surface>& surface); ANDROID_API bool pauseSurface(const sp<Surface>& surface); ANDROID_API void setStopped(bool stopped); |