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 /engines | |
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
Diffstat (limited to 'engines')
-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); |