diff options
author | Kari Salminen | 2009-08-03 17:52:07 +0000 |
---|---|---|
committer | Kari Salminen | 2009-08-03 17:52:07 +0000 |
commit | c2dc86df08c5d0dc034789d265cc1a7aa7966fc0 (patch) | |
tree | 48f6c736b39e354a86c72ba7dfc291c17ba3721a | |
parent | 9931fb6a443571f104109f0c8a4116d892648a09 (diff) | |
download | scummvm-rg350-c2dc86df08c5d0dc034789d265cc1a7aa7966fc0.tar.gz scummvm-rg350-c2dc86df08c5d0dc034789d265cc1a7aa7966fc0.tar.bz2 scummvm-rg350-c2dc86df08c5d0dc034789d265cc1a7aa7966fc0.zip |
Fix for #2824798 (FW: crash when clicking "load" in the GUI):
- Fixed CineMetaEngine::listSaves(const char *target) which was broken.
- Also added explicit initialization of savegame descriptions to
empty strings for safety reasons (e.g. arrays on stack aren't
initialized to zero).
- Added explicit trailing zero setting to savegame descriptions
(Previously using GMM you could write a description of length >= 20
that had no trailing zero when written to description file (e.g. fw.dir)).
svn-id: r43027
-rw-r--r-- | engines/cine/cine.cpp | 3 | ||||
-rw-r--r-- | engines/cine/detection.cpp | 52 | ||||
-rw-r--r-- | engines/cine/saveload.cpp | 9 |
3 files changed, 42 insertions, 22 deletions
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index aa73b3adec..8756a2fc3c 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -114,6 +114,9 @@ int CineEngine::modifyGameSpeed(int speedChange) { } void CineEngine::initialize() { + // Initialize all savegames' descriptions to empty strings + memset(currentSaveName, 0, sizeof(currentSaveName)); + // Resize object table to its correct size and reset all its elements objectTable.resize(NUM_MAX_OBJECT); resetObjectTable(); diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp index 4786005647..3bc26ab417 100644 --- a/engines/cine/detection.cpp +++ b/engines/cine/detection.cpp @@ -607,35 +607,37 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const { pattern += ".?"; Common::StringList filenames = saveFileMan->listSavefiles(pattern); sort(filenames.begin(), filenames.end()); - Common::StringList::const_iterator file = filenames.begin(); + Common::StringList::const_iterator file; Common::String filename = target; filename += ".dir"; Common::InSaveFile *in = saveFileMan->openForLoading(filename); if (in) { - int8 ch; - char saveDesc[20]; - do { + typedef char CommandeType[20]; + CommandeType saveNames[10]; + + // Initialize all savegames' descriptions to empty strings + // so that if the savegames' descriptions can only be partially read from file + // then the missing ones are correctly set to empty strings. + memset(saveNames, 0, sizeof(saveNames)); + + in->read(saveNames, 10 * 20); + CommandeType saveDesc; + + for (file = filenames.begin(); file != filenames.end(); ++file) { + // Jump over savegame files that don't end with a digit (e.g. "fw.3" is ok, "fw.a" is not). + if (!isdigit(file->lastChar())) + continue; + // Obtain the last digit of the filename, since they correspond to the save slot int slotNum = atoi(file->c_str() + file->size() - 1); - uint pos = 0; - do { - ch = in->readByte(); - if (pos < (sizeof(saveDesc) - 1)) { - if (ch < 32 || in->eos()) { - saveDesc[pos++] = '\0'; - } - else if (ch >= 32) { - saveDesc[pos++] = ch; - } - } - } while (ch >= 32 && !in->eos()); - if (saveDesc[0] != 0) { - saveList.push_back(SaveStateDescriptor(slotNum, saveDesc)); - file++; - } - } while (!in->eos()); + // Copy the savegame description making sure it ends with a trailing zero + strncpy(saveDesc, saveNames[slotNum], 20); + saveDesc[sizeof(CommandeType) - 1] = 0; + + saveList.push_back(SaveStateDescriptor(slotNum, saveDesc)); + } } delete in; @@ -650,6 +652,11 @@ void CineMetaEngine::removeSaveState(const char *target, int slot) const { typedef char CommandeType[20]; CommandeType saveNames[10]; + // Initialize all savegames' descriptions to empty strings + // so that if the savegames' descriptions can only be partially read from file + // then the missing ones are correctly set to empty strings. + memset(saveNames, 0, sizeof(saveNames)); + Common::InSaveFile *in; char tmp[80]; @@ -707,8 +714,9 @@ Common::Error CineEngine::saveGameState(int slot, const char *desc) { // Load savegame descriptions from index file loadSaveDirectory(); - // Set description for selected slot + // Set description for selected slot making sure it ends with a trailing zero strncpy(currentSaveName[slot], desc, 20); + currentSaveName[slot][sizeof(CommandeType) - 1] = 0; // Update savegame descriptions char indexFile[80]; diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp index be1e19b229..158d209289 100644 --- a/engines/cine/saveload.cpp +++ b/engines/cine/saveload.cpp @@ -468,9 +468,18 @@ bool CineEngine::loadSaveDirectory(void) { return false; } + // Initialize all savegames' descriptions to empty strings + // so that if the savegames' descriptions can only be partially read from file + // then the missing ones are correctly set to empty strings. + memset(currentSaveName, 0, sizeof(currentSaveName)); + fHandle->read(currentSaveName, 10 * 20); delete fHandle; + // Make sure all savegames' descriptions end with a trailing zero. + for (int i = 0; i < ARRAYSIZE(currentSaveName); i++) + currentSaveName[i][sizeof(CommandeType) - 1] = 0; + return true; } |