aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorAlyssa Milburn2011-08-11 13:12:20 +0200
committerAlyssa Milburn2011-08-11 13:15:18 +0200
commit76a18b247b4ee64725f1ae5cae93d5e82a248f53 (patch)
tree773b953357f0b945c9dbf43d46dad08f791d0fad /engines
parent0f6e231356305043bc7f66ae1cbe2c3a0607c68a (diff)
downloadscummvm-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.
Diffstat (limited to 'engines')
-rw-r--r--engines/composer/graphics.cpp22
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;