[Scummvm-cvs-logs] SF.net SVN: scummvm: [20884] scummvm/trunk/engines/cine

cyx at users.sourceforge.net cyx at users.sourceforge.net
Sat Feb 25 10:27:01 CET 2006


Revision: 20884
Author:   cyx
Date:     2006-02-25 10:26:16 -0800 (Sat, 25 Feb 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm?rev=20884&view=rev

Log Message:
-----------
cleanup unpacking function and get rid of an old hack to prevent buffer overflows.

Modified Paths:
--------------
    scummvm/trunk/engines/cine/part.cpp
    scummvm/trunk/engines/cine/sfx_player.cpp
    scummvm/trunk/engines/cine/unpack.cpp
    scummvm/trunk/engines/cine/unpack.h
Modified: scummvm/trunk/engines/cine/part.cpp
===================================================================
--- scummvm/trunk/engines/cine/part.cpp	2006-02-25 18:24:55 UTC (rev 20883)
+++ scummvm/trunk/engines/cine/part.cpp	2006-02-25 18:26:16 UTC (rev 20884)
@@ -203,14 +203,10 @@
 
 	if (partBuffer[foundFileIdx].unpackedSize != partBuffer[foundFileIdx].packedSize) {
 		uint8 *unpackBuffer;
-		uint16 realSize;
 
-		unpackBuffer = (uint8 *)malloc(partBuffer[foundFileIdx].packedSize + 500);
+		unpackBuffer = (uint8 *)malloc(partBuffer[foundFileIdx].packedSize);
 		readFromPart(foundFileIdx, unpackBuffer);
-
-		realSize = READ_BE_UINT32(unpackBuffer + partBuffer[foundFileIdx].packedSize - 4);
-
-		decomp(unpackBuffer + partBuffer[foundFileIdx].packedSize - 4, dataPtr + realSize, realSize);
+		delphineUnpack(dataPtr, unpackBuffer, partBuffer[foundFileIdx].packedSize);
 		free(unpackBuffer);
 	} else {
 		readFromPart(foundFileIdx, dataPtr);

Modified: scummvm/trunk/engines/cine/sfx_player.cpp
===================================================================
--- scummvm/trunk/engines/cine/sfx_player.cpp	2006-02-25 18:24:55 UTC (rev 20883)
+++ scummvm/trunk/engines/cine/sfx_player.cpp	2006-02-25 18:26:16 UTC (rev 20884)
@@ -117,7 +117,7 @@
 					if (tempData) {
 						snd_baseSndFile->seek(be->offset, SEEK_SET);
 						snd_baseSndFile->read(tempData, be->size);
-						decomp(tempData + be->size - 4, entryData + be->unpackedSize, be->unpackedSize);
+						delphineUnpack(entryData, tempData, be->size);
 						free(tempData);
 					}
 				} else {

Modified: scummvm/trunk/engines/cine/unpack.cpp
===================================================================
--- scummvm/trunk/engines/cine/unpack.cpp	2006-02-25 18:24:55 UTC (rev 20883)
+++ scummvm/trunk/engines/cine/unpack.cpp	2006-02-25 18:26:16 UTC (rev 20884)
@@ -26,130 +26,86 @@
 
 namespace Cine {
 
-uint32 crc;			// variable at 5C5A
-uint32 bitbucket;			// dx:bx
+static int rcr(UnpackCtx *uc, int CF) {
+	int rCF = (uc->chk & 1);
+	uc->chk >>= 1;
+	if (CF) {
+		uc->chk |= 0x80000000;
+	}
+	return rCF;
+}
 
-uint16 swap16(uint16 r) {
-	return (r >> 8) | (r << 8);
+static int nextChunk(UnpackCtx *uc) {
+	int CF = rcr(uc, 0);
+	if (uc->chk == 0) {
+		uc->chk = READ_BE_UINT32(uc->src); uc->src -= 4;
+		uc->crc ^= uc->chk;
+		CF = rcr(uc, 1);
+	}
+	return CF;
 }
 
-#define loadd(p, d) {\
-    d = *(--p);\
-    d |= (*(--p)) << 8;\
-    d |= (*(--p)) << 16;\
-    d |= (*(--p)) << 24;\
+static uint16 getCode(UnpackCtx *uc, uint8 numChunks) {
+	uint16 c = 0;
+	while (numChunks--) {
+		c <<= 1;
+		if (nextChunk(uc)) {
+			c |= 1;
+		}			
+	}
+	return c;
 }
-#define store(p, b) *(--p) = b
-#define getbit(p, b) {			\
-	b = bitbucket & 1;			\
-	bitbucket >>= 1;			\
-	if (!bitbucket) {			\
-		loadd(p, bitbucket);	\
-		crc ^= bitbucket;		\
-		b = bitbucket & 1;		\
-		bitbucket >>= 1;		\
-		bitbucket |= 0x80000000;\
-	}							\
+
+static void unpackHelper1(UnpackCtx *uc, uint8 numChunks, uint8 addCount) {
+	uint16 count = getCode(uc, numChunks) + addCount + 1;
+	uc->datasize -= count;
+	while (count--) {
+		*uc->dst = (uint8)getCode(uc, 8);
+		--uc->dst;
+	}
 }
 
-#define loadbits(p, b) {	\
-	b = 0;					\
-	do {					\
-		getbit(p, bit);		\
-		b <<= 1;			\
-		b |= bit;			\
-		nbits--;			\
-	} while (nbits);		\
+static void unpackHelper2(UnpackCtx *uc, uint8 numChunks) {
+	uint16 i = getCode(uc, numChunks);
+	uint16 count = uc->size + 1;
+	uc->datasize -= count;
+	while (count--) {
+		*uc->dst = *(uc->dst + i);
+		--uc->dst;
+	}
 }
 
-int decomp(uint8 *in, uint8 *out, int size) {
-	uint8 bit;			// Carry flag
-	uint8 nbits;		// cl
-	uint8 byte = 0;		// ch
-	uint16 counter;		// bp
-	uint16 var = 0;		// variable at 5C58
-	uint16 ptr;
-	uint16 flags;
-
-	enum {
-		DO_COPY,
-		DO_UNPACK
-	} action;
-
-	loadd(in, crc);
-	loadd(in, bitbucket);
-	crc ^= bitbucket;
-
-	do {			// 5A4C
-		getbit(in, bit);
-		if (!bit) {	// 5A94
-			getbit(in, bit);
-			if (!bit) {	// 5AC8
-				nbits = 3;
-				byte = 0;
-				action = DO_COPY;
-			} else {	// 5ACA
-				var = 1;
-				nbits = 8;
-				action = DO_UNPACK;
+bool delphineUnpack(uint8 *dst, const uint8 *src, int len) {
+	UnpackCtx uc;
+	uc.src = src + len - 4;
+	uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4;
+	uc.dst = dst + uc.datasize - 1;
+	uc.size = 0;
+	uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4;
+	uc.chk = READ_BE_UINT32(uc.src); uc.src -= 4;
+	uc.crc ^= uc.chk;
+	do {
+		if (!nextChunk(&uc)) {
+			uc.size = 1;
+			if (!nextChunk(&uc)) {
+				unpackHelper1(&uc, 3, 0);
+			} else {
+				unpackHelper2(&uc, 8);
 			}
-		} else {	// 5B4F
-			nbits = 2;
-			loadbits(in, flags);
-			if (flags < 2) {
-				nbits = flags + 9;	// 5BC3
-				var = flags + 2;
-				action = DO_UNPACK;
-			} else if (flags == 3) {
-				nbits = 8;	// 5B4A
-				byte = 8;
-				action = DO_COPY;
+		} else {
+			uint16 c = getCode(&uc, 2);
+			if (c == 3) {
+				unpackHelper1(&uc, 8, 8);
+			} else if (c < 2) {
+				uc.size = c + 2;
+				unpackHelper2(&uc, c + 9);
 			} else {
-				nbits = 8;
-				loadbits(in, var);
-				nbits = 12;
-				action = DO_UNPACK;
+				uc.size = getCode(&uc, 8);
+				unpackHelper2(&uc, 12);
 			}
 		}
-
-		switch (action) {
-		case DO_COPY:
-			{
-				// 5AD1
-				loadbits(in, counter);	// 5AFD
-				counter += byte;
-				counter++;
-				size -= counter;
-				do {
-					nbits = 8;
-					loadbits(in, byte);	// 5B3F
-					store(out, byte);
-					counter--;
-				} while (counter);	// 5B45
-				break;
-			}
-
-		case DO_UNPACK:
-
-			// 5BD3
-			loadbits(in, ptr);	// 5BFF
-			counter = var + 1;
-			size -= counter;
-			do {
-				byte = *(out + ptr - 1);
-				store(out, byte);
-				counter--;
-			} while (counter);
-		}
-	} while (size > 0);
-
-	// 5C32
-	// ???
-	if (crc) {
-		return -1;
-	} else {
-		return 0;
-	}
+	} while (uc.datasize > 0);
+	return uc.crc == 0;
 }
 
 } // End of namespace Cine

Modified: scummvm/trunk/engines/cine/unpack.h
===================================================================
--- scummvm/trunk/engines/cine/unpack.h	2006-02-25 18:24:55 UTC (rev 20883)
+++ scummvm/trunk/engines/cine/unpack.h	2006-02-25 18:26:16 UTC (rev 20884)
@@ -30,8 +30,16 @@
 
 namespace Cine {
 
-int decomp(uint8 *in, uint8 *out, int size);
+struct UnpackCtx {
+	int size, datasize;
+	uint32 crc;
+	uint32 chk;
+	uint8 *dst;
+	const uint8 *src;	
+};
 
+bool delphineUnpack(uint8 *dst, const uint8 *src, int len);
+
 } // End of namespace Cine
 
 #endif







More information about the Scummvm-git-logs mailing list