[Scummvm-cvs-logs] SF.net SVN: scummvm: [32292] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Mon May 26 17:29:13 CEST 2008


Revision: 32292
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32292&view=rev
Author:   drmccoy
Date:     2008-05-26 08:29:12 -0700 (Mon, 26 May 2008)

Log Message:
-----------
Changed anim/static PieceDesc loading, to allow for more sanity checks.
This should take care of all invalid reads in renderStatic(), updateStatic() and updateAnim()

Modified Paths:
--------------
    scummvm/trunk/engines/gob/scenery.cpp
    scummvm/trunk/engines/gob/scenery.h

Modified: scummvm/trunk/engines/gob/scenery.cpp
===================================================================
--- scummvm/trunk/engines/gob/scenery.cpp	2008-05-26 14:10:34 UTC (rev 32291)
+++ scummvm/trunk/engines/gob/scenery.cpp	2008-05-26 15:29:12 UTC (rev 32292)
@@ -100,7 +100,6 @@
 	byte *extData = 0;
 	byte *dataPtr;
 	Static *ptr;
-	int16 pictDescId;
 	int16 width;
 	int16 height;
 	int16 sprResId;
@@ -143,8 +142,6 @@
 	dataPtr += 2;
 
 	ptr->layers = new StaticLayer[ptr->layersCount];
-	ptr->pieces = new PieceDesc*[picsCount];
-	ptr->piecesFromExt = new bool[picsCount];
 
 	for (int i = 0; i < ptr->layersCount; i++) {
 		int16 offset = READ_LE_UINT16(dataPtr + i * 2);
@@ -166,18 +163,13 @@
 		backsPtr++;
 	}
 
+	ptr->pieces = new PieceDesc*[picsCount];
+	ptr->piecesCount = new uint32[picsCount];
+
 	for (int i = 0; i < picsCount; i++) {
-		pictDescId = _vm->_inter->load16();
+		int16 pictDescId = _vm->_inter->load16();
 
-		if (pictDescId >= 30000) {
-			ptr->pieces[i] =
-				(PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0);
-			ptr->piecesFromExt[i] = true;
-		} else {
-			ptr->pieces[i] =
-				(PieceDesc *) _vm->_game->loadTotResource(pictDescId);
-			ptr->piecesFromExt[i] = false;
-		}
+		loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]);
 
 		width = _vm->_inter->load16();
 		height = _vm->_inter->load16();
@@ -224,8 +216,7 @@
 		return;
 
 	for (int i = 0; i < _staticPictCount[index]; i++) {
-		if (_statics[index].piecesFromExt[i])
-			delete[] _statics[index].pieces[i];
+		delete[] _statics[index].pieces[i];
 
 		spr = _staticPictToSprite[index * 7 + i];
 		_spriteRefs[spr]--;
@@ -239,7 +230,7 @@
 		delete[] _statics[index].layers[i].planes;
 	delete[] _statics[index].layers;
 	delete[] _statics[index].pieces;
-	delete[] _statics[index].piecesFromExt;
+	delete[] _statics[index].piecesCount;
 
 	_statics[index].layersCount = 0;
 	_staticPictCount[index] = -1;
@@ -253,8 +244,8 @@
 	int16 order;
 	int16 plane;
 
-	int16 pieceIndex;
-	int16 pictIndex;
+	uint16 pieceIndex;
+	uint16 pictIndex;
 
 	int16 left;
 	int16 right;
@@ -286,15 +277,21 @@
 			pieceIndex = planePtr->pieceIndex;
 			pictIndex = planePtr->pictIndex - 1;
 
-			if ((pictIndex >= _staticPictCount[scenery]) || (!ptr->pieces))
+			if (pictIndex >= _staticPictCount[scenery])
 				continue;
 
+			if (!ptr->pieces || !ptr->pieces[pictIndex])
+				continue;
+
+			if (pieceIndex >= ptr->piecesCount[pictIndex])
+				continue;
+
 			_vm->_draw->_destSpriteX = planePtr->destX;
 			_vm->_draw->_destSpriteY = planePtr->destY;
-			left = FROM_LE_16(ptr->pieces[pictIndex][pieceIndex].left);
-			right = FROM_LE_16(ptr->pieces[pictIndex][pieceIndex].right);
-			top = FROM_LE_16(ptr->pieces[pictIndex][pieceIndex].top);
-			bottom = FROM_LE_16(ptr->pieces[pictIndex][pieceIndex].bottom);
+			left = ptr->pieces[pictIndex][pieceIndex].left;
+			right = ptr->pieces[pictIndex][pieceIndex].right;
+			top = ptr->pieces[pictIndex][pieceIndex].top;
+			bottom = ptr->pieces[pictIndex][pieceIndex].bottom;
 
 			_vm->_draw->_sourceSurface =
 			    _staticPictToSprite[scenery * 7 + pictIndex];
@@ -316,8 +313,8 @@
 	int16 planeCount;
 	int16 order;
 	int16 plane;
-	int16 pieceIndex;
-	int16 pictIndex;
+	uint16 pieceIndex;
+	uint16 pictIndex;
 
 	int16 left;
 	int16 right;
@@ -341,16 +338,22 @@
 			pieceIndex = planePtr->pieceIndex;
 			pictIndex = planePtr->pictIndex - 1;
 
-			if ((pictIndex >= _staticPictCount[index]) || (!pictPtr[pictIndex]))
+			if (pictIndex >= _staticPictCount[index])
 				continue;
 
+			if (!pictPtr || !pictPtr[pictIndex])
+				continue;
+
+			if (pieceIndex >= _statics[index].piecesCount[pictIndex])
+				continue;
+
 			_vm->_draw->_destSpriteX = planePtr->destX;
 			_vm->_draw->_destSpriteY = planePtr->destY;
 
-			left = FROM_LE_16(pictPtr[pictIndex][pieceIndex].left);
-			right = FROM_LE_16(pictPtr[pictIndex][pieceIndex].right);
-			top = FROM_LE_16(pictPtr[pictIndex][pieceIndex].top);
-			bottom = FROM_LE_16(pictPtr[pictIndex][pieceIndex].bottom);
+			left = pictPtr[pictIndex][pieceIndex].left;
+			right = pictPtr[pictIndex][pieceIndex].right;
+			top = pictPtr[pictIndex][pieceIndex].top;
+			bottom = pictPtr[pictIndex][pieceIndex].bottom;
 
 			if (_vm->_draw->_destSpriteX > _toRedrawRight)
 				continue;
@@ -421,7 +424,6 @@
 	byte *extData;
 	byte *dataPtr;
 	Animation *ptr;
-	int16 pictDescId;
 	int16 width;
 	int16 height;
 	int16 sprResId;
@@ -460,9 +462,6 @@
 	dataPtr += 2;
 
 	ptr->layers = new AnimLayer[ptr->layersCount];
-	ptr->pieces = new PieceDesc*[picsCount];
-	ptr->piecesFromExt = new bool[picsCount];
-	ptr->sizes = new uint16[picsCount];
 
 	for (i = 0; i < ptr->layersCount; i++) {
 		int16 offset = READ_LE_UINT16(dataPtr + i * 2);
@@ -498,24 +497,14 @@
 		}
 	}
 
+	ptr->pieces = new PieceDesc*[picsCount];
+	ptr->piecesCount = new uint32[picsCount];
+
 	for (i = 0; i < picsCount; i++) {
-		pictDescId = _vm->_inter->load16();
-		if (pictDescId >= 30000) {
-			uint32 size;
+		int16 pictDescId = _vm->_inter->load16();
 
-			ptr->pieces[i] =
-				(PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0, &size);
-			ptr->piecesFromExt[i] = true;
-			ptr->sizes[i] = size / 8;
-		} else {
-			int16 size;
+		loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]);
 
-			ptr->pieces[i] =
-				(PieceDesc *) _vm->_game->loadTotResource(pictDescId, &size);
-			ptr->piecesFromExt[i] = false;
-			ptr->sizes[i] = size / 8;
-		}
-
 		width = _vm->_inter->load16();
 		height = _vm->_inter->load16();
 		sprResId = _vm->_inter->load16();
@@ -560,8 +549,7 @@
 		return;
 
 	for (int i = 0; i < _animPictCount[index]; i++) {
-		if (_animations[index].piecesFromExt[i])
-			delete[] _animations[index].pieces[i];
+		delete[] _animations[index].pieces[i];
 
 		spr = _animPictToSprite[index * 7 + i];
 		_spriteRefs[spr]--;
@@ -575,8 +563,7 @@
 		delete[] _animations[index].layers[i].frames;
 	delete[] _animations[index].layers;
 	delete[] _animations[index].pieces;
-	delete[] _animations[index].piecesFromExt;
-	delete[] _animations[index].sizes;
+	delete[] _animations[index].piecesCount;
 
 	_animPictCount[index] = 0;
 }
@@ -827,21 +814,20 @@
 
 		pictIndex = (pictIndex & 15) - 1;
 
-		if ((pictIndex == 0xFFFF) || (_animPictCount[animation] <= pictIndex)) {
-			warning("Scenery::updateAnim: pictIndex out of range");
-			return;
-		}
+		if (pictIndex >= _animPictCount[animation])
+			continue;
 
-		if (_animations[animation].sizes[pictIndex] <= pieceIndex) {
-			warning("Scenery::updateAnim: pieceIndex out of range");
+		if (!pictPtr[pictIndex])
 			continue;
-		}
 
-		left = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].left);
-		right = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].right);
-		top = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].top);
-		bottom = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].bottom);
+		if (pieceIndex >= _animations[animation].piecesCount[pictIndex])
+			continue;
 
+		left = pictPtr[pictIndex][pieceIndex].left;
+		right = pictPtr[pictIndex][pieceIndex].right;
+		top = pictPtr[pictIndex][pieceIndex].top;
+		bottom = pictPtr[pictIndex][pieceIndex].bottom;
+
 		if (flags & 2) {
 			if (destX < _vm->_mult->_animLeft) {
 				left += _vm->_mult->_animLeft - destX;
@@ -961,4 +947,42 @@
 	return &_animations[index].layers[layer];
 }
 
+void Scenery::loadPieces(int16 pictDescId, PieceDesc *&pieceDesc, uint32 &piecesCount) {
+	byte *data;
+	uint32 size;
+	bool fromExt = false;
+
+	if (pictDescId >= 30000) {
+		fromExt = true;
+
+		uint32 eSize;
+
+		data = _vm->_game->loadExtData(pictDescId, 0, 0, &eSize);
+		size = eSize;
+	} else {
+		int16 tSize;
+
+		data = _vm->_game->loadTotResource(pictDescId, &tSize);
+		size = tSize;
+	}
+
+	if (!data)
+		error("Scenery::loadPieces(): Can't load pictDescId %d", pictDescId);
+
+	piecesCount = size / 8;
+	pieceDesc = new PieceDesc[piecesCount];
+
+	Common::MemoryReadStream pieceData(data, size);
+
+	for (uint32 i = 0; i < piecesCount; i++) {
+		pieceDesc[i].left = (int16) pieceData.readUint16LE();
+		pieceDesc[i].right = (int16) pieceData.readUint16LE();
+		pieceDesc[i].top = (int16) pieceData.readUint16LE();
+		pieceDesc[i].bottom = (int16) pieceData.readUint16LE();
+	}
+
+	if (fromExt)
+		delete[] data;
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/scenery.h
===================================================================
--- scummvm/trunk/engines/gob/scenery.h	2008-05-26 14:10:34 UTC (rev 32291)
+++ scummvm/trunk/engines/gob/scenery.h	2008-05-26 15:29:12 UTC (rev 32292)
@@ -34,10 +34,10 @@
 #include "common/pack-start.h"	// START STRUCT PACKING
 
 	struct PieceDesc {
-		int16 left;		//NOTE:
-		int16 right;		//These are stored in Little Endian format
-		int16 top;		//And should be converted by client code when accessed
-		int16 bottom;		//i.e. use FROM_LE_16()
+		int16 left;
+		int16 right;
+		int16 top;
+		int16 bottom;
 	} PACKED_STRUCT;
 
 	struct StaticPlane {
@@ -82,19 +82,16 @@
 		int16 layersCount;
 		StaticLayer *layers;
 		PieceDesc **pieces;
-		bool *piecesFromExt;
-		Static() : layersCount(0), layers(0), pieces(0),
-				   piecesFromExt(0) {}
+		uint32 *piecesCount;
+		Static() : layersCount(0), layers(0), pieces(0), piecesCount(0) {}
 	};
 
 	struct Animation {
 		int16 layersCount;
 		AnimLayer *layers;
 		PieceDesc **pieces;
-		bool *piecesFromExt;
-		uint16 *sizes;
-		Animation() : layersCount(0), layers(0), pieces(0),
-			              piecesFromExt(0) {}
+		uint32 *piecesCount;
+		Animation() : layersCount(0), layers(0), pieces(0), piecesCount(0) {}
 	};
 
 	int16 _curStatic;
@@ -151,6 +148,8 @@
 
 	GobEngine *_vm;
 
+	void loadPieces(int16 pictDescId, PieceDesc *&pieceDesc, uint32 &piecesCount);
+
 	void updateStatic(int16 orderFrom, byte index, byte layer);
 };
 


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