detect bad bitmaps during deserialization

BUG=skia:3117

Review URL: https://codereview.chromium.org/718103002
This commit is contained in:
reed 2014-11-12 09:25:25 -08:00 committed by Commit bot
parent 257bf0f6f7
commit ac6a2f964e
2 changed files with 15 additions and 3 deletions

View File

@ -392,6 +392,7 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
return false; return false;
} }
/* Should we use SkValidatingReadBuffer instead? */
SkReadBuffer buffer(storage.get(), size); SkReadBuffer buffer(storage.get(), size);
buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags)); buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
buffer.setVersion(fInfo.fVersion); buffer.setVersion(fInfo.fVersion);
@ -400,13 +401,16 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
fTFPlayback.setupBuffer(buffer); fTFPlayback.setupBuffer(buffer);
buffer.setBitmapDecoder(proc); buffer.setBitmapDecoder(proc);
while (!buffer.eof()) { while (!buffer.eof() && buffer.isValid()) {
tag = buffer.readUInt(); tag = buffer.readUInt();
size = buffer.readUInt(); size = buffer.readUInt();
if (!this->parseBufferTag(buffer, tag, size)) { if (!this->parseBufferTag(buffer, tag, size)) {
return false; return false;
} }
} }
if (!buffer.isValid()) {
return false;
}
SkDEBUGCODE(haveBuffer = true;) SkDEBUGCODE(haveBuffer = true;)
} break; } break;
} }
@ -421,8 +425,11 @@ bool SkPictureData::parseBufferTag(SkReadBuffer& buffer,
fBitmaps = SkTRefArray<SkBitmap>::Create(size); fBitmaps = SkTRefArray<SkBitmap>::Create(size);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
SkBitmap* bm = &fBitmaps->writableAt(i); SkBitmap* bm = &fBitmaps->writableAt(i);
buffer.readBitmap(bm); if (buffer.readBitmap(bm)) {
bm->setImmutable(); bm->setImmutable();
} else {
return false;
}
} }
} break; } break;
case SK_PICT_PAINT_BUFFER_TAG: { case SK_PICT_PAINT_BUFFER_TAG: {

View File

@ -260,6 +260,11 @@ bool SkReadBuffer::readBitmap(SkBitmap* bitmap) {
// not having a decoder. // not having a decoder.
SkErrorInternals::SetError(kParseError_SkError, SkErrorInternals::SetError(kParseError_SkError,
"Could not decode bitmap. Resulting bitmap will be red."); "Could not decode bitmap. Resulting bitmap will be red.");
// Even though we weren't able to decode the pixels, the readbuffer should still be
// intact, so we return true with an empty bitmap, so we don't for an abort of the
// larger deserialize.
bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
return true;
} else { } else {
// A size of zero means the SkBitmap was simply flattened. // A size of zero means the SkBitmap was simply flattened.
if (this->isVersionLT(kNoMoreBitmapFlatten_Version)) { if (this->isVersionLT(kNoMoreBitmapFlatten_Version)) {