aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2015-09-04 11:36:39 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-04 11:36:39 -0700
commitc3470340b6658dea7baa3ac90d3b716c0afd7051 (patch)
tree3b164197eade94b9bac1d2cc9df98a0dd98f156e /src/core
parent19e9b35750e7c3752ea2e6d8a938de4a1dc874f0 (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.cpp23
-rw-r--r--src/core/SkWriteBuffer.cpp2
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;
}