Chromium Code Reviews| Index: src/core/SkPicturePlayback.cpp |
| diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp |
| index 08097a988ee06f466809b495faf74ebec4aa34fa..a97312701f1fe1506c2912f5cf4c2bab69c6cadb 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 |
| @@ -488,19 +488,23 @@ void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, |
| switch (tag) { |
| case PICT_READER_TAG: { |
| - void* storage = sk_malloc_throw(size); |
| - stream->read(storage, size); |
| + SkAutoMalloc storage(size); |
| + if (stream->read(storage.get(), size) != size) { |
|
scroggo
2013/09/26 21:06:29
Patch set 2 contains the interesting parts: return
|
| + return false; |
| + } |
| SkASSERT(NULL == fOpData); |
| - fOpData = SkData::NewFromMalloc(storage, size); |
| + fOpData = SkData::NewFromMalloc(storage.detach(), size); |
| } break; |
| case PICT_FACTORY_TAG: { |
| SkASSERT(!haveBuffer); |
| fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size)); |
| for (size_t i = 0; i < size; i++) { |
| SkString str; |
| - int len = stream->readPackedUInt(); |
| + const size_t len = stream->readPackedUInt(); |
| str.resize(len); |
| - stream->read(str.writable_str(), len); |
| + if (stream->read(str.writable_str(), len) != len) { |
| + return false; |
| + } |
| fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str()); |
| } |
| } break; |
| @@ -520,19 +524,31 @@ 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]) { |
| + 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: { |
| SkAutoMalloc storage(size); |
| - stream->read(storage.get(), size); |
| + if (stream->read(storage.get(), size) != size) { |
| + return false; |
| + } |
| SkOrderedReadBuffer buffer(storage.get(), size); |
| buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags)); |
| @@ -544,14 +560,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: { |
| @@ -585,13 +604,18 @@ void SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer, |
| buffer.readRegion(&fRegions->writableAt(i)); |
| } |
| } break; |
| + default: |
| + // The tag was invalid. |
| + return false; |
| } |
| + 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 +623,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; |
| } |
| /////////////////////////////////////////////////////////////////////////////// |