aboutsummaryrefslogtreecommitdiff
path: root/engines/cine/detection.cpp
diff options
context:
space:
mode:
authorKari Salminen2009-08-03 17:52:07 +0000
committerKari Salminen2009-08-03 17:52:07 +0000
commitc2dc86df08c5d0dc034789d265cc1a7aa7966fc0 (patch)
tree48f6c736b39e354a86c72ba7dfc291c17ba3721a /engines/cine/detection.cpp
parent9931fb6a443571f104109f0c8a4116d892648a09 (diff)
downloadscummvm-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
Diffstat (limited to 'engines/cine/detection.cpp')
-rw-r--r--engines/cine/detection.cpp52
1 files changed, 30 insertions, 22 deletions
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];