From 00cbedb25f891ef508e71c49ffa0f9973361ba60 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 22:45:38 +0000 Subject: Added possibility to get the read resource's size from readBundleFile. Made loadMsg handle input data that has empty strings residing just beyond the input buffer (Thanks Valgrind :-)). svn-id: r33810 --- engines/cine/msg.cpp | 45 ++++++++++++++++++++++++++++----------------- engines/cine/part.cpp | 7 ++++++- engines/cine/part.h | 2 +- 3 files changed, 35 insertions(+), 19 deletions(-) (limited to 'engines') diff --git a/engines/cine/msg.cpp b/engines/cine/msg.cpp index 55eb627309..c826db3bf3 100644 --- a/engines/cine/msg.cpp +++ b/engines/cine/msg.cpp @@ -34,29 +34,40 @@ namespace Cine { Common::StringList messageTable; void loadMsg(char *pMsgName) { - int i, count, len; - byte *ptr, *dataPtr; - const char *messagePtr; + uint32 sourceSize; checkDataDisk(-1); - messageTable.clear(); - - ptr = dataPtr = readBundleFile(findFileInBundle(pMsgName)); + byte *dataPtr = readBundleFile(findFileInBundle(pMsgName), &sourceSize); setMouseCursor(MOUSE_CURSOR_DISK); - count = READ_BE_UINT16(ptr); - ptr += 2; - - messagePtr = (const char*)(ptr + 2 * count); - - for (i = 0; i < count; i++) { - len = READ_BE_UINT16(ptr); - ptr += 2; - - messageTable.push_back(messagePtr); - messagePtr += len; + uint count = READ_BE_UINT16(dataPtr); + uint messageLenPos = 2; + uint messageDataPos = messageLenPos + 2 * count; + + // Read in the messages + for (uint i = 0; i < count; i++) { + // Read message's length + uint messageLen = READ_BE_UINT16(dataPtr + messageLenPos); + messageLenPos += 2; + + // Store the read message. + // This code works around input data that has empty strings residing outside the input + // buffer (e.g. message indexes 58-254 in BATEAU.MSG in PROCS08 in Operation Stealth). + if (messageDataPos < sourceSize) { + messageTable.push_back((const char *)(dataPtr + messageDataPos)); + } else { + if (messageLen > 0) { // Only warn about overflowing non-empty strings + warning("loadMsg(%s): message (%d. / %d) is overflowing the input buffer. Replacing it with an empty string", pMsgName, i + 1, count); + } else { + debugC(5, kCineDebugPart, "loadMsg(%s): empty message (%d. / %d) resides outside input buffer", pMsgName, i + 1, count); + } + // Message resides outside the input buffer so we replace it with an empty string + messageTable.push_back(""); + } + // Jump to the next message + messageDataPos += messageLen; } free(dataPtr); diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp index df530b77f2..657471be4e 100644 --- a/engines/cine/part.cpp +++ b/engines/cine/part.cpp @@ -217,7 +217,7 @@ void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize) { g_cine->_partFileHandle.read(dataPtr, MIN(partBuffer[idx].packedSize, maxSize)); } -byte *readBundleFile(int16 foundFileIdx) { +byte *readBundleFile(int16 foundFileIdx, uint32 *size) { assert(foundFileIdx >= 0 && foundFileIdx < (int32)partBuffer.size()); bool error = false; byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1); @@ -236,6 +236,11 @@ byte *readBundleFile(int16 foundFileIdx) { warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName); } + // Set the size variable if a pointer to it has been given + if (size != NULL) { + *size = partBuffer[foundFileIdx].unpackedSize; + } + return dataPtr; } diff --git a/engines/cine/part.h b/engines/cine/part.h index dc9d1db537..755f843b4a 100644 --- a/engines/cine/part.h +++ b/engines/cine/part.h @@ -46,7 +46,7 @@ int16 findFileInBundle(const char *fileName); void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize); -byte *readBundleFile(int16 foundFileIdx); +byte *readBundleFile(int16 foundFileIdx, uint32 *size = NULL); byte *readBundleSoundFile(const char *entryName, uint32 *size = 0); byte *readFile(const char *filename, bool crypted = false); -- cgit v1.2.3