Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: src/core/SkPicturePlayback.cpp

Issue 24826002: Allow creating a picture from skp to fail. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix debugger. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkPicturePlayback.cpp
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 08097a988ee06f466809b495faf74ebec4aa34fa..13128aac74c0ba96871edb0e39b92530f537213b 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) {
+ 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,26 @@ 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,
- SkPicture::InstallPixelRefProc proc) {
- this->init();
+SkPicturePlayback* SkPicturePlayback::CreateFromStream(SkStream* stream,
+ const SkPictInfo& info,
+ SkPicture::InstallPixelRefProc proc) {
+ SkAutoTDelete<SkPicturePlayback> playback(SkNEW(SkPicturePlayback));
+
+ if (!playback->parseStream(stream, info, proc)) {
+ return NULL;
+ }
+ return playback.detach();
+}
+bool SkPicturePlayback::parseStream(SkStream* stream, const SkPictInfo& info,
+ SkPicture::InstallPixelRefProc proc) {
for (;;) {
uint32_t tag = stream->readU32();
if (PICT_EOF_TAG == tag) {
@@ -599,8 +631,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 false; // we're invalid
+ }
}
+ return true;
}
///////////////////////////////////////////////////////////////////////////////
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698