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.
This commit is contained in:
Alyssa Milburn 2011-08-11 13:12:20 +02:00
parent 0f6e231356
commit 76a18b247b

View File

@ -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;