Index: src/core/SkPicturePlayback.cpp |
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp |
index 08097a988ee06f466809b495faf74ebec4aa34fa..4a4a2d8a4337800abb1b13a4b31bc2558084982f 100644 |
--- a/src/core/SkPicturePlayback.cpp |
+++ b/src/core/SkPicturePlayback.cpp |
@@ -473,7 +473,7 @@ static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) { |
return rbMask; |
} |
-void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, uint32_t tag, |
+bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, uint32_t tag, |
size_t size, SkPicture::InstallPixelRefProc proc) { |
/* |
* By the time we encounter BUFFER_SIZE_TAG, we need to have already seen |
@@ -520,14 +520,24 @@ void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, |
case PICT_PICTURE_TAG: { |
fPictureCount = size; |
fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount); |
- for (int i = 0; i < fPictureCount; i++) { |
+ bool success = true; |
+ int i = 0; |
+ for ( ; i < fPictureCount; i++) { |
fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc); |
- // CreateFromStream can only fail if PICTURE_VERSION does not match |
- // (which should never happen from here, since a sub picture will |
- // have the same PICTURE_VERSION as its parent) or if stream->read |
- // returns 0. In the latter case, we have a bug when writing the |
- // picture to begin with, which will be alerted to here. |
- SkASSERT(fPictureRefs[i] != NULL); |
+ if (NULL == fPictureRefs[i]) { |
scroggo
2013/09/26 21:06:28
This bit is slightly different from a straight rev
|
+ success = false; |
+ break; |
+ } |
+ } |
+ if (!success) { |
+ // Delete all of the pictures that were already created (up to but excluding i): |
+ for (int j = 0; j < i; j++) { |
+ fPictureRefs[j]->unref(); |
+ } |
+ // Delete the array |
+ SkDELETE_ARRAY(fPictureRefs); |
+ fPictureCount = 0; |
+ return false; |
} |
} break; |
case PICT_BUFFER_SIZE_TAG: { |
@@ -544,14 +554,17 @@ void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, |
while (!buffer.eof()) { |
tag = buffer.readUInt(); |
size = buffer.readUInt(); |
- this->parseBufferTag(buffer, tag, size); |
+ if (!this->parseBufferTag(buffer, tag, size)) { |
+ return false; |
+ } |
} |
SkDEBUGCODE(haveBuffer = true;) |
} break; |
} |
+ return true; // success |
} |
-void SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer, |
+bool SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer, |
uint32_t tag, size_t size) { |
switch (tag) { |
case PICT_BITMAP_BUFFER_TAG: { |
@@ -586,12 +599,14 @@ void SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer, |
} |
} break; |
} |
+ return true; // success |
} |
-SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info, |
+SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info, bool* isValid, |
SkPicture::InstallPixelRefProc proc) { |
this->init(); |
+ *isValid = false; // wait until we're done parsing to mark as true |
for (;;) { |
uint32_t tag = stream->readU32(); |
if (PICT_EOF_TAG == tag) { |
@@ -599,8 +614,11 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info, |
} |
uint32_t size = stream->readU32(); |
- this->parseStreamTag(stream, info, tag, size, proc); |
+ if (!this->parseStreamTag(stream, info, tag, size, proc)) { |
+ return; // we're invalid |
+ } |
} |
+ *isValid = true; |
} |
/////////////////////////////////////////////////////////////////////////////// |