diff options
author | fmalita <fmalita@chromium.org> | 2015-09-04 11:36:39 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-04 11:36:39 -0700 |
commit | c3470340b6658dea7baa3ac90d3b716c0afd7051 (patch) | |
tree | 3b164197eade94b9bac1d2cc9df98a0dd98f156e /src/core | |
parent | 19e9b35750e7c3752ea2e6d8a938de4a1dc874f0 (diff) |
Handle zero-length encoded images gracefully during deserialization
Image encoding may fail during serialization, resulting in zero-length
encoded data in the SKP.
Instead of invalidating the stream (and preventing deserialization of
the whole picture) we can instantiate placeholder images.
BUG=skia:4285
R=reed@google.com,robertphillips@google.com
Review URL: https://codereview.chromium.org/1308273011
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkPictureData.cpp | 23 | ||||
-rw-r--r-- | src/core/SkWriteBuffer.cpp | 2 |
2 files changed, 23 insertions, 2 deletions
diff --git a/src/core/SkPictureData.cpp b/src/core/SkPictureData.cpp index 5089e5d8d6..9d497f676a 100644 --- a/src/core/SkPictureData.cpp +++ b/src/core/SkPictureData.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ #include <new> +#include "SkImageGenerator.h" #include "SkPictureData.h" #include "SkPictureRecord.h" #include "SkReadBuffer.h" @@ -433,6 +434,20 @@ bool SkPictureData::parseStreamTag(SkStream* stream, return true; // success } +namespace { + +// This generator intentionally should always fail on all attempts to get its pixels, +// simulating a bad or empty codec stream. +class EmptyImageGenerator final : public SkImageGenerator { +public: + EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { } + +private: + typedef SkImageGenerator INHERITED; +}; + +} // anonymous namespace + static const SkImage* create_image_from_buffer(SkReadBuffer& buffer) { int width = buffer.read32(); int height = buffer.read32(); @@ -442,9 +457,15 @@ static const SkImage* create_image_from_buffer(SkReadBuffer& buffer) { } SkAutoTUnref<SkData> encoded(buffer.readByteArrayAsData()); + if (encoded->size() == 0) { + // The image could not be encoded at serialization time - return an empty placeholder. + return SkImage::NewFromGenerator( + new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height))); + } + int originX = buffer.read32(); int originY = buffer.read32(); - if (0 == encoded->size() || originX < 0 || originY < 0) { + if (originX < 0 || originY < 0) { buffer.validate(false); return nullptr; } diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp index ac3d678dbc..1dfe0b3972 100644 --- a/src/core/SkWriteBuffer.cpp +++ b/src/core/SkWriteBuffer.cpp @@ -223,7 +223,7 @@ void SkWriteBuffer::writeImage(const SkImage* image) { this->writeInt(image->height()); SkAutoTUnref<SkData> encoded(image->encode(this->getPixelSerializer())); - if (encoded) { + if (encoded && encoded->size() > 0) { write_encoded_bitmap(this, encoded, SkIPoint::Make(0, 0)); return; } |