Changeset - r10810:4d664f3e5f11
[Not reviewed]
master
0 2 0
smatz - 16 years ago 2009-01-18 23:26:38
smatz@openttd.org
(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
2 files changed with 37 insertions and 15 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -2028,6 +2028,7 @@ STR_GAME_SAVELOAD_ERROR_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
src/saveload/oldloader.cpp
Show inline comments
 
@@ -1452,9 +1452,6 @@ static bool LoadOldMain(LoadgameState *l
 
{
 
	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 *l
 
	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;
 

	
 
	fclose(ls.file);
 
	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);
 
}
0 comments (0 inline, 0 general)