(svn r15145) -Fix: crash when one tried to load a TTO savegame

-Fix (r15144): it wasn't safe at all, but the code broken code isn't needed anymore
This commit is contained in:
smatz 2009-01-18 23:26:38 +00:00
parent 575a3a4563
commit 14834e67cb
2 changed files with 37 additions and 15 deletions

View File

@ -2028,6 +2028,7 @@ STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Broken savegame
STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Savegame is made with newer version
STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :File not readable
STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :File not writeable
STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :Data integrity check failed
STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}List of drives, directories and saved-game files
STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Currently selected name for saved-game
STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Delete the currently selected saved-game

View File

@ -1452,9 +1452,6 @@ static bool LoadOldMain(LoadgameState *ls)
{
int i;
/* The first 49 is the name of the game + checksum, skip it */
fseek(ls->file, HEADER_SIZE, SEEK_SET);
DEBUG(oldloader, 3, "Reading main chunk...");
/* Load the biggest chunk */
_old_map3 = MallocT<byte>(OLD_MAP_SIZE * 2);
@ -1540,6 +1537,28 @@ static bool LoadOldMain(LoadgameState *ls)
return true;
}
/**
* Verifies the title has a valid checksum
* @param title title and checksum
* @return true iff the title is valid
* @note the title (incl. checksum) has to be at least 49 (HEADER_SIZE) bytes long!
*/
static bool VerifyOldNameChecksum(char *title)
{
uint16 sum = 0;
for (uint i = 0; i < HEADER_SIZE - 2; i++) {
sum += title[i];
sum = ROL(sum, 1);
}
sum ^= 0xAAAA; // computed checksum
uint16 sum2 = title[HEADER_SIZE - 2]; // checksum in file
SB(sum2, 8, 8, title[HEADER_SIZE - 1]);
return sum == sum2;
}
bool LoadOldSaveGame(const char *file)
{
LoadgameState ls;
@ -1556,10 +1575,12 @@ bool LoadOldSaveGame(const char *file)
return false;
}
/* Load the main chunk */
if (!LoadOldMain(&ls)) return false;
char temp[HEADER_SIZE];
if (fread(temp, 1, HEADER_SIZE, ls.file) != HEADER_SIZE || !VerifyOldNameChecksum(temp) || !LoadOldMain(&ls)) {
SetSaveLoadError(STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED);
fclose(ls.file);
return false;
}
/* Some old TTD(Patch) savegames could have buoys at tile 0
* (without assigned station struct)
@ -1575,20 +1596,20 @@ bool LoadOldSaveGame(const char *file)
void GetOldSaveGameName(const char *path, const char *file, char *title, const char *last)
{
char filename[MAX_PATH];
char temp[HEADER_SIZE - 1];
char temp[HEADER_SIZE];
snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file);
FILE *f = fopen(filename, "rb");
temp[0] = '\0';
temp[HEADER_SIZE - 2] = '\0';
temp[0] = '\0'; // name is nul-terminated in savegame ...
if (f == NULL) return;
if (fread(temp, 1, HEADER_SIZE - 2, f) != HEADER_SIZE - 2) {
seprintf(title, last, "Corrupt file");
} else {
seprintf(title, last, temp);
}
bool broken = (fread(temp, 1, HEADER_SIZE, f) != HEADER_SIZE || !VerifyOldNameChecksum(temp));
temp[HEADER_SIZE - 2] = '\0'; // ... but it's better to be sure
if (broken) title = strecpy(title, "(broken) ", last);
title = strecpy(title, temp, last);
fclose(f);
}