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
This commit is contained in:
parent
9931fb6a44
commit
c2dc86df08
3 changed files with 42 additions and 22 deletions
|
@ -114,6 +114,9 @@ int CineEngine::modifyGameSpeed(int speedChange) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CineEngine::initialize() {
|
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
|
// Resize object table to its correct size and reset all its elements
|
||||||
objectTable.resize(NUM_MAX_OBJECT);
|
objectTable.resize(NUM_MAX_OBJECT);
|
||||||
resetObjectTable();
|
resetObjectTable();
|
||||||
|
|
|
@ -607,35 +607,37 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
|
||||||
pattern += ".?";
|
pattern += ".?";
|
||||||
Common::StringList filenames = saveFileMan->listSavefiles(pattern);
|
Common::StringList filenames = saveFileMan->listSavefiles(pattern);
|
||||||
sort(filenames.begin(), filenames.end());
|
sort(filenames.begin(), filenames.end());
|
||||||
Common::StringList::const_iterator file = filenames.begin();
|
Common::StringList::const_iterator file;
|
||||||
|
|
||||||
Common::String filename = target;
|
Common::String filename = target;
|
||||||
filename += ".dir";
|
filename += ".dir";
|
||||||
Common::InSaveFile *in = saveFileMan->openForLoading(filename);
|
Common::InSaveFile *in = saveFileMan->openForLoading(filename);
|
||||||
if (in) {
|
if (in) {
|
||||||
int8 ch;
|
typedef char CommandeType[20];
|
||||||
char saveDesc[20];
|
CommandeType saveNames[10];
|
||||||
do {
|
|
||||||
|
// 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
|
// Obtain the last digit of the filename, since they correspond to the save slot
|
||||||
int slotNum = atoi(file->c_str() + file->size() - 1);
|
int slotNum = atoi(file->c_str() + file->size() - 1);
|
||||||
|
|
||||||
uint pos = 0;
|
// Copy the savegame description making sure it ends with a trailing zero
|
||||||
do {
|
strncpy(saveDesc, saveNames[slotNum], 20);
|
||||||
ch = in->readByte();
|
saveDesc[sizeof(CommandeType) - 1] = 0;
|
||||||
if (pos < (sizeof(saveDesc) - 1)) {
|
|
||||||
if (ch < 32 || in->eos()) {
|
saveList.push_back(SaveStateDescriptor(slotNum, saveDesc));
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete in;
|
delete in;
|
||||||
|
@ -650,6 +652,11 @@ void CineMetaEngine::removeSaveState(const char *target, int slot) const {
|
||||||
typedef char CommandeType[20];
|
typedef char CommandeType[20];
|
||||||
CommandeType saveNames[10];
|
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;
|
Common::InSaveFile *in;
|
||||||
char tmp[80];
|
char tmp[80];
|
||||||
|
|
||||||
|
@ -707,8 +714,9 @@ Common::Error CineEngine::saveGameState(int slot, const char *desc) {
|
||||||
// Load savegame descriptions from index file
|
// Load savegame descriptions from index file
|
||||||
loadSaveDirectory();
|
loadSaveDirectory();
|
||||||
|
|
||||||
// Set description for selected slot
|
// Set description for selected slot making sure it ends with a trailing zero
|
||||||
strncpy(currentSaveName[slot], desc, 20);
|
strncpy(currentSaveName[slot], desc, 20);
|
||||||
|
currentSaveName[slot][sizeof(CommandeType) - 1] = 0;
|
||||||
|
|
||||||
// Update savegame descriptions
|
// Update savegame descriptions
|
||||||
char indexFile[80];
|
char indexFile[80];
|
||||||
|
|
|
@ -468,9 +468,18 @@ bool CineEngine::loadSaveDirectory(void) {
|
||||||
return false;
|
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);
|
fHandle->read(currentSaveName, 10 * 20);
|
||||||
delete fHandle;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue