diff options
author | Alyssa Milburn | 2011-08-11 13:12:20 +0200 |
---|---|---|
committer | Alyssa Milburn | 2011-08-11 13:15:18 +0200 |
commit | 76a18b247b4ee64725f1ae5cae93d5e82a248f53 (patch) | |
tree | 773b953357f0b945c9dbf43d46dad08f791d0fad | |
parent | 0f6e231356305043bc7f66ae1cbe2c3a0607c68a (diff) | |
download | scummvm-rg350-76a18b247b4ee64725f1ae5cae93d5e82a248f53.tar.gz scummvm-rg350-76a18b247b4ee64725f1ae5cae93d5e82a248f53.tar.bz2 scummvm-rg350-76a18b247b4ee64725f1ae5cae93d5e82a248f53.zip |
COMPOSER: Stop kBitmapSpp32 writing off the end of the buffer.
This fixes corruption when there's only one pixel left to
decompress, but two pixels available in the compressed data.
Also, improve error checking in the bitmap decompression code.
-rw-r--r-- | engines/composer/graphics.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp index 5c9fc6e1f7..0768a86e7a 100644 --- a/engines/composer/graphics.cpp +++ b/engines/composer/graphics.cpp @@ -598,10 +598,16 @@ enum { }; void ComposerEngine::decompressBitmap(uint16 type, Common::SeekableReadStream *stream, byte *buffer, uint32 size, uint width, uint height) { + uint outSize = width * height; + switch (type) { case kBitmapUncompressed: - assert(stream->size() - (uint)stream->pos() == size); - assert(size == width * height); + if (stream->size() - (uint)stream->pos() != size) + error("kBitmapUncompressed stream had %d bytes left, supposed to be %d", + stream->size() - (uint)stream->pos(), size); + if (size != outSize) + error("kBitmapUncompressed size %d doesn't match required size %d", + size, outSize); stream->read(buffer, size); break; case kBitmapSpp32: @@ -615,12 +621,22 @@ void ComposerEngine::decompressBitmap(uint16 type, Common::SeekableReadStream *s // run of a single color uint count = (uint)stream->readByte() + 3; size--; + if (outSize < count) + error("kBitmapSpp32 only needed %d bytes, but got run of %d", + outSize, count); + outSize -= count; memset(buffer, lookup[lowBits], count); buffer += count; } else { // two pixels + if (!outSize) + error("kBitmapSpp32 had too many pixels"); *buffer++ = lookup[highBits]; - *buffer++ = lookup[lowBits]; + outSize--; + if (outSize) { + *buffer++ = lookup[lowBits]; + outSize--; + } } } break; |