diff options
| author | Colin Snover | 2016-10-09 13:47:33 -0500 | 
|---|---|---|
| committer | Colin Snover | 2016-10-09 13:52:04 -0500 | 
| commit | d0ec919fb703b8016d55bab8316068350c27e84b (patch) | |
| tree | 67492381a1d4ebcdb6209a2f5840859dc5b8e25f | |
| parent | 6cc761e72850320e89d3136da4b4ec686fd784db (diff) | |
| download | scummvm-rg350-d0ec919fb703b8016d55bab8316068350c27e84b.tar.gz scummvm-rg350-d0ec919fb703b8016d55bab8316068350c27e84b.tar.bz2 scummvm-rg350-d0ec919fb703b8016d55bab8316068350c27e84b.zip | |
SCI: Fix crash when attempting to view invalid list, array, bitmap references
| -rw-r--r-- | engines/sci/console.cpp | 171 | ||||
| -rw-r--r-- | engines/sci/console.h | 9 | 
2 files changed, 121 insertions, 59 deletions
| diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 39fa95a956..8737c8b954 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -2175,7 +2175,7 @@ bool Console::segmentInfo(int nr) {  		for (uint i = 0; i < lt.size(); i++)  			if (lt.isValidEntry(i)) {  				debugPrintf("  [%04x]: ", i); -				printList(<[i]); +				printList(lt[i]);  			}  	}  	break; @@ -2779,16 +2779,8 @@ bool Console::cmdViewReference(int argc, const char **argv) {  		switch (type) {  		case 0:  			break; -		case SIG_TYPE_LIST: { -			List *list = _engine->_gamestate->_segMan->lookupList(reg); - -			debugPrintf("list\n"); - -			if (list) -				printList(list); -			else -				debugPrintf("Invalid list.\n"); -		} +		case SIG_TYPE_LIST: +			printList(reg);  			break;  		case SIG_TYPE_NODE:  			debugPrintf("list node\n"); @@ -2802,47 +2794,11 @@ bool Console::cmdViewReference(int argc, const char **argv) {  			switch (_engine->_gamestate->_segMan->getSegmentType(reg.getSegment())) {  #ifdef ENABLE_SCI32  				case SEG_TYPE_ARRAY: { -					const SciArray *array = _engine->_gamestate->_segMan->lookupArray(reg); -					const char *arrayType; -					switch (array->getType()) { -						case kArrayTypeID: -							arrayType = "reg_t"; -							break; -						case kArrayTypeByte: -							arrayType = "byte"; -							break; -						case kArrayTypeInt16: -							arrayType = "int16 (as reg_t)"; -							break; -						case kArrayTypeString: -							arrayType = "string"; -							break; -						default: -							arrayType = "invalid"; -							break; -					} -					debugPrintf("SCI32 %s array (%u entries):\n", arrayType, array->size()); -					switch (array->getType()) { -					case kArrayTypeInt16: -					case kArrayTypeID: { -						hexDumpReg((const reg_t *)array->getRawData(), array->size(), 4, 0, true); -						break; -					} -					case kArrayTypeByte: -					case kArrayTypeString: { -						Common::hexdump((const byte *)array->getRawData(), array->size(), 16, 0); -						break; -					} -					default: -						break; -					} - +					printArray(reg);  					break;  				}  				case SEG_TYPE_BITMAP: { -					debugPrintf("SCI32 bitmap:\n"); -					const SciBitmap *bitmap = _engine->_gamestate->_segMan->lookupBitmap(reg); -					Common::hexdump((const byte *) bitmap->getRawData(), bitmap->getRawSize(), 16, 0); +					printBitmap(reg);  					break;  				}  #endif @@ -4392,8 +4348,28 @@ void Console::printBasicVarInfo(reg_t variable) {  		debugPrintf(" IS INVALID!");  } -void Console::printList(List *list) { -	reg_t pos = list->first; +void Console::printList(reg_t reg) { +	SegmentObj *mobj = _engine->_gamestate->_segMan->getSegment(reg.getSegment(), SEG_TYPE_LISTS); + +	if (!mobj) { +		debugPrintf("list:\nCould not find list segment.\n"); +		return; +	} + +	ListTable *table = static_cast<ListTable *>(mobj); + +	if (!table->isValidEntry(reg.getOffset())) { +		debugPrintf("list:\nAddress does not contain a valid list.\n"); +		return; +	} + +	const List &list = table->at(reg.getOffset()); +	debugPrintf("list:\n"); +	printList(list); +} + +void Console::printList(const List &list) { +	reg_t pos = list.first;  	reg_t my_prev = NULL_REG;  	debugPrintf("\t<\n"); @@ -4403,8 +4379,7 @@ void Console::printList(List *list) {  		NodeTable *nt = (NodeTable *)_engine->_gamestate->_segMan->getSegment(pos.getSegment(), SEG_TYPE_NODES);  		if (!nt || !nt->isValidEntry(pos.getOffset())) { -			debugPrintf("   WARNING: %04x:%04x: Doesn't contain list node!\n", -			          PRINT_REG(pos)); +			debugPrintf("   WARNING: %04x:%04x: Doesn't contain list node!\n", PRINT_REG(pos));  			return;  		} @@ -4413,16 +4388,15 @@ void Console::printList(List *list) {  		debugPrintf("\t%04x:%04x  : %04x:%04x -> %04x:%04x\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value));  		if (my_prev != node->pred) -			debugPrintf("   WARNING: current node gives %04x:%04x as predecessor!\n", -			          PRINT_REG(node->pred)); +			debugPrintf("   WARNING: current node gives %04x:%04x as predecessor!\n", PRINT_REG(node->pred));  		my_prev = pos;  		pos = node->succ;  	} -	if (my_prev != list->last) +	if (my_prev != list.last)  		debugPrintf("   WARNING: Last node was expected to be %04x:%04x, was %04x:%04x!\n", -		          PRINT_REG(list->last), PRINT_REG(my_prev)); +				  PRINT_REG(list.last), PRINT_REG(my_prev));  	debugPrintf("\t>\n");  } @@ -4466,6 +4440,89 @@ int Console::printNode(reg_t addr) {  	return 0;  } +#ifdef ENABLE_SCI32 +void Console::printArray(reg_t reg) { +	SegmentObj *mobj = _engine->_gamestate->_segMan->getSegment(reg.getSegment(), SEG_TYPE_ARRAY); + +	if (!mobj) { +		debugPrintf("SCI32 array:\nCould not find array segment.\n"); +		return; +	} + +	ArrayTable *table = static_cast<ArrayTable *>(mobj); + +	if (!table->isValidEntry(reg.getOffset())) { +		debugPrintf("SCI32 array:\nAddress does not contain a valid array.\n"); +		return; +	} + +	const SciArray &array = table->at(reg.getOffset()); + +	const char *arrayType; +	switch (array.getType()) { +	case kArrayTypeID: +		arrayType = "reg_t"; +		break; +	case kArrayTypeByte: +		arrayType = "byte"; +		break; +	case kArrayTypeInt16: +		arrayType = "int16 (as reg_t)"; +		break; +	case kArrayTypeString: +		arrayType = "string"; +		break; +	default: +		arrayType = "invalid"; +		break; +	} +	debugPrintf("SCI32 %s array (%u entries):\n", arrayType, array.size()); +	switch (array.getType()) { +	case kArrayTypeInt16: +	case kArrayTypeID: { +		hexDumpReg((const reg_t *)array.getRawData(), array.size(), 4, 0, true); +		break; +	} +	case kArrayTypeByte: +	case kArrayTypeString: { +		Common::hexdump((const byte *)array.getRawData(), array.size(), 16, 0); +		break; +	} +	default: +		break; +	} +} + +void Console::printBitmap(reg_t reg) { +	SegmentObj *mobj = _engine->_gamestate->_segMan->getSegment(reg.getSegment(), SEG_TYPE_BITMAP); + +	if (!mobj) { +		debugPrintf("SCI32 bitmap:\nCould not find bitmap segment.\n"); +		return; +	} + +	BitmapTable *table = static_cast<BitmapTable *>(mobj); + +	if (!table->isValidEntry(reg.getOffset())) { +		debugPrintf("SCI32 bitmap:\nAddress does not contain a valid bitmap.\n"); +		return; +	} + +	const SciBitmap &bitmap = table->at(reg.getOffset()); + +	debugPrintf("SCI32 bitmap (%dx%d; res %dx%d; origin %dx%d; skip color %u; %s; %s):\n", +				bitmap.getWidth(), bitmap.getHeight(), +				bitmap.getXResolution(), bitmap.getYResolution(), +				bitmap.getOrigin().x, bitmap.getOrigin().y, +				bitmap.getSkipColor(), +				bitmap.getRemap() ? "remap" : "no remap", +				bitmap.getShouldGC() ? "GC" : "no GC"); + +	Common::hexdump((const byte *) bitmap.getRawData(), bitmap.getRawSize(), 16, 0); +} + +#endif +  int Console::printObject(reg_t pos) {  	EngineState *s = _engine->_gamestate;	// for the several defines in this function  	const Object *obj = s->_segMan->getObject(pos); diff --git a/engines/sci/console.h b/engines/sci/console.h index cf85def950..0b87a4408b 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -41,7 +41,11 @@ public:  	Console(SciEngine *engine);  	virtual ~Console(); -	int printObject(reg_t pos); +#ifdef ENABLE_SCI32 +	void printArray(reg_t reg); +	void printBitmap(reg_t reg); +#endif +	int printObject(reg_t reg);  private:  	virtual void preEnter(); @@ -169,7 +173,8 @@ private:  	void printBasicVarInfo(reg_t variable);  	bool segmentInfo(int nr); -	void printList(List *list); +	void printList(reg_t addr); +	void printList(const List &list);  	int printNode(reg_t addr);  	void hexDumpReg(const reg_t *data, int len, int regsPerLine = 4, int startOffset = 0, bool isArray = false);  	void printOffsets(int scriptNr, uint16 showType); | 
