Index: src/core/SkReadBuffer.cpp |
diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp |
index 00e3e2c1ce1c5cdaa02fe86a7845ee2b125ac6c1..4a1d44f0bf5f6b5a022b66fd17d6c409a5fff9fe 100644 |
--- a/src/core/SkReadBuffer.cpp |
+++ b/src/core/SkReadBuffer.cpp |
@@ -8,6 +8,8 @@ |
#include "SkBitmap.h" |
#include "SkErrorInternals.h" |
+#include "SkImage.h" |
+#include "SkImageGenerator.h" |
#include "SkReadBuffer.h" |
#include "SkStream.h" |
#include "SkTypeface.h" |
@@ -274,6 +276,46 @@ bool SkReadBuffer::readBitmap(SkBitmap* bitmap) { |
return false; |
} |
+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 |
+ |
+SkImage* SkReadBuffer::readImage() { |
+ int width = this->read32(); |
+ int height = this->read32(); |
+ if (width <= 0 || height <= 0) { // SkImage never has a zero dimension |
+ this->validate(false); |
+ return nullptr; |
+ } |
+ |
+ SkAutoTUnref<SkData> encoded(this->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 = this->read32(); |
+ int originY = this->read32(); |
+ if (originX < 0 || originY < 0) { |
+ this->validate(false); |
+ return nullptr; |
+ } |
+ |
+ const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height); |
+ return SkImage::NewFromEncoded(encoded, &subset); |
+} |
+ |
SkTypeface* SkReadBuffer::readTypeface() { |
uint32_t index = fReader.readU32(); |