[Scummvm-cvs-logs] SF.net SVN: scummvm:[55258] scummvm/trunk/graphics/video

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Sun Jan 16 17:27:22 CET 2011


Revision: 55258
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55258&view=rev
Author:   drmccoy
Date:     2011-01-16 16:27:22 +0000 (Sun, 16 Jan 2011)

Log Message:
-----------
VIDEO: Add range checks to deLZ77()

Modified Paths:
--------------
    scummvm/trunk/graphics/video/coktel_decoder.cpp
    scummvm/trunk/graphics/video/coktel_decoder.h

Modified: scummvm/trunk/graphics/video/coktel_decoder.cpp
===================================================================
--- scummvm/trunk/graphics/video/coktel_decoder.cpp	2011-01-16 16:26:52 UTC (rev 55257)
+++ scummvm/trunk/graphics/video/coktel_decoder.cpp	2011-01-16 16:27:22 UTC (rev 55258)
@@ -268,64 +268,83 @@
 	return (_features & kFeaturesPalette) && _paletteDirty;
 }
 
-void CoktelDecoder::deLZ77(byte *dest, byte *src) {
-	int i;
-	byte buf[4370];
-	uint16 chunkLength;
-	uint32 frameLength;
+uint32 CoktelDecoder::deLZ77(byte *dest, const byte *src, uint32 srcSize, uint32 destSize) {
+	uint32 frameLength = READ_LE_UINT32(src);
+	if (frameLength > destSize) {
+		warning("CoktelDecoder::deLZ77(): Uncompressed size bigger than buffer size (%d > %d)", frameLength, destSize);
+		return 0;
+	}
+
+	assert(srcSize >= 4);
+
+	uint32 realSize = frameLength;
+
+	src     += 4;
+	srcSize -= 4;
+
 	uint16 bufPos1;
-	uint16 bufPos2;
-	uint16 tmp;
-	uint8 chunkBitField;
-	uint8 chunkCount;
 	bool mode;
+	if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) {
+		assert(srcSize >= 4);
 
-	frameLength = READ_LE_UINT32(src);
-	src += 4;
+		src     += 4;
+		srcSize -= 4;
 
-	if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) {
-		src += 4;
 		bufPos1 = 273;
-		mode = 1; // 123Ch (cmp al, 12h)
+		mode    = 1; // 123Ch (cmp al, 12h)
 	} else {
 		bufPos1 = 4078;
-		mode = 0; // 275h (jnz +2)
+		mode    = 0; // 275h (jnz +2)
 	}
 
+	byte buf[4370];
 	memset(buf, 32, bufPos1);
-	chunkCount = 1;
-	chunkBitField = 0;
 
+	uint8 chunkCount    = 1;
+	uint8 chunkBitField = 0;
+
 	while (frameLength > 0) {
 		chunkCount--;
+
 		if (chunkCount == 0) {
-			tmp = *src++;
-			chunkCount = 8;
-			chunkBitField = tmp;
+			chunkCount    = 8;
+			chunkBitField = *src++;
 		}
+
 		if (chunkBitField % 2) {
+			assert(srcSize >= 1);
+
 			chunkBitField >>= 1;
 			buf[bufPos1] = *src;
 			*dest++ = *src++;
 			bufPos1 = (bufPos1 + 1) % 4096;
 			frameLength--;
+			srcSize--;
 			continue;
 		}
 		chunkBitField >>= 1;
 
-		tmp = READ_LE_UINT16(src);
-		src += 2;
-		chunkLength = ((tmp & 0xF00) >> 8) + 3;
+		assert(srcSize >= 2);
 
+		uint16 tmp = READ_LE_UINT16(src);
+		uint16 chunkLength = ((tmp & 0xF00) >> 8) + 3;
+
+		src     += 2;
+		srcSize -= 2;
+
 		if ((mode && ((chunkLength & 0xFF) == 0x12)) ||
-				(!mode && (chunkLength == 0)))
+				(!mode && (chunkLength == 0))) {
+			assert(srcSize >= 1);
+
 			chunkLength = *src++ + 0x12;
+			srcSize--;
+		}
 
-		bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00);
+		uint16 bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00);
 		if (((tmp + chunkLength) >= 4096) ||
 				((chunkLength + bufPos1) >= 4096)) {
 
-			for (i = 0; i < chunkLength; i++, dest++) {
+			for (int i = 0; i < chunkLength; i++, dest++) {
 				*dest = buf[bufPos2];
 				buf[bufPos1] = buf[bufPos2];
 				bufPos1 = (bufPos1 + 1) % 4096;
@@ -338,13 +357,13 @@
 			memcpy(dest, buf + bufPos2, chunkLength);
 			memmove(buf + bufPos1, buf + bufPos2, chunkLength);
 
-			dest += chunkLength;
+			dest    += chunkLength;
 			bufPos1 += chunkLength;
 			bufPos2 += chunkLength;
 
 		} else {
 
-			for (i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) {
+			for (int i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) {
 				*dest = buf[bufPos2];
 				buf[bufPos1] = buf[bufPos2];
 			}
@@ -353,6 +372,8 @@
 		frameLength -= chunkLength;
 
 	}
+
+	return realSize;
 }
 
 void CoktelDecoder::deRLE(byte *&destPtr, const byte *&srcPtr, int16 destLen, int16 srcLen) {
@@ -1316,7 +1337,8 @@
 		// Result is empty => nothing to do
 		return false;
 
-	byte *dataPtr = _videoBuffer[0];
+	byte  *dataPtr  = _videoBuffer[0];
+	uint32 dataSize = _videoBufferLen[0] - 1;
 
 	uint8 type = *dataPtr++;
 
@@ -1330,7 +1352,8 @@
 		for (int i = 0; i < count; i++)
 			_palette[index * 3 + i] = dataPtr[i] << 2;
 
-		dataPtr += 48;
+		dataPtr  += 48;
+		dataSize -= 49;
 		type ^= 0x10;
 
 		_paletteDirty = true;
@@ -1343,13 +1366,15 @@
 
 		if ((type == 2) && (rect.width() == _surface.w) && (_x == 0)) {
 			// Directly uncompress onto the video surface
-			deLZ77((byte *)_surface.pixels + (_y * _surface.pitch), dataPtr);
+			deLZ77((byte *)_surface.pixels + (_y * _surface.pitch), dataPtr, dataSize,
+					_surface.w * _surface.h * _surface.bytesPerPixel);
 			return true;
 		}
 
-		deLZ77(_videoBuffer[1], dataPtr);
+		_videoBufferLen[1] = deLZ77(_videoBuffer[1], dataPtr, dataSize, _videoBufferSize);
 
-		dataPtr = _videoBuffer[1];
+		dataPtr  = _videoBuffer[1];
+		dataSize = _videoBufferLen[1];
 	}
 
 	// Evaluate the block type
@@ -2133,7 +2158,8 @@
 		return false;
 	}
 
-	byte *dataPtr = _videoBuffer[0];
+	byte  *dataPtr  = _videoBuffer[0];
+	uint32 dataSize = _videoBufferLen[0] - 1;
 
 	uint8 type = *dataPtr++;
 
@@ -2144,13 +2170,15 @@
 
 		if ((type == 2) && (rect.width() == _surface.w) && (_x == 0)) {
 			// Directly uncompress onto the video surface
-			deLZ77((byte *)_surface.pixels + (_y * _surface.pitch), dataPtr);
+			deLZ77((byte *)_surface.pixels + (_y * _surface.pitch), dataPtr, dataSize,
+					_surface.w * _surface.h * _surface.bytesPerPixel);
 			return true;
 		}
 
-		deLZ77(_videoBuffer[1], dataPtr);
+		_videoBufferLen[1] = deLZ77(_videoBuffer[1], dataPtr, dataSize, _videoBufferSize);
 
-		dataPtr = _videoBuffer[1];
+		dataPtr  = _videoBuffer[1];
+		dataSize = _videoBufferLen[1];
 	}
 
 	// Evaluate the block type

Modified: scummvm/trunk/graphics/video/coktel_decoder.h
===================================================================
--- scummvm/trunk/graphics/video/coktel_decoder.h	2011-01-16 16:26:52 UTC (rev 55257)
+++ scummvm/trunk/graphics/video/coktel_decoder.h	2011-01-16 16:27:22 UTC (rev 55258)
@@ -191,7 +191,7 @@
 	void freeSurface();
 
 	// Decompression
-	void deLZ77(byte *dest, byte *src);
+	uint32 deLZ77(byte *dest, const byte *src, uint32 srcSize, uint32 destSize);
 	void deRLE(byte *&destPtr, const byte *&srcPtr, int16 destLen, int16 srcLen);
 
 	// Block rendering


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list