From c3470340b6658dea7baa3ac90d3b716c0afd7051 Mon Sep 17 00:00:00 2001 From: fmalita Date: Fri, 4 Sep 2015 11:36:39 -0700 Subject: 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 --- src/core/SkPictureData.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/core/SkPictureData.cpp') 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 +#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 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; } -- cgit v1.2.3