1
0
Fork 0

(svn r15144) -Codechange: make sure we don't run out of bounds while determining old savegame name

Note this can't happen in current code
release/0.7
smatz 2009-01-18 22:44:53 +00:00
parent a46245f21f
commit 3bceaf41b4
4 changed files with 23 additions and 16 deletions

View File

@ -41,7 +41,7 @@ extern void FiosGetDrives();
extern bool FiosGetDiskFreeSpace(const char *path, uint64 *tot); extern bool FiosGetDiskFreeSpace(const char *path, uint64 *tot);
/* get the name of an oldstyle savegame */ /* get the name of an oldstyle savegame */
extern void GetOldSaveGameName(char *title, const char *path, const char *file); extern void GetOldSaveGameName(const char *path, const char *file, char *title, const char *last);
/** /**
* Compare two FiosItem's. Used with qsort when sorting the file list. * Compare two FiosItem's. Used with qsort when sorting the file list.
@ -194,7 +194,7 @@ bool FileExists(const char *filename)
#endif #endif
} }
typedef FiosType fios_getlist_callback_proc(SaveLoadDialogMode mode, const char *filename, const char *ext, char *title); typedef FiosType fios_getlist_callback_proc(SaveLoadDialogMode mode, const char *filename, const char *ext, char *title, const char *last);
/** Create a list of the files in a directory, according to some arbitrary rule. /** Create a list of the files in a directory, according to some arbitrary rule.
* @param mode The mode we are in. Some modes don't allow 'parent'. * @param mode The mode we are in. Some modes don't allow 'parent'.
@ -265,7 +265,7 @@ static FiosItem *FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_
if ((t = strrchr(d_name, '.')) == NULL) continue; if ((t = strrchr(d_name, '.')) == NULL) continue;
fios_title[0] = '\0'; // reset the title; fios_title[0] = '\0'; // reset the title;
FiosType type = callback_proc(mode, d_name, t, fios_title); FiosType type = callback_proc(mode, d_name, t, fios_title, lastof(fios_title));
if (type != FIOS_TYPE_INVALID) { if (type != FIOS_TYPE_INVALID) {
fios = _fios_items.Append(); fios = _fios_items.Append();
fios->mtime = sb.st_mtime; fios->mtime = sb.st_mtime;
@ -298,11 +298,12 @@ static FiosItem *FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_
* @param file Name of the file to check. * @param file Name of the file to check.
* @param ext A pointer to the extension identifier inside file * @param ext A pointer to the extension identifier inside file
* @param title Buffer if a callback wants to lookup the title of the file; NULL to skip the lookup * @param title Buffer if a callback wants to lookup the title of the file; NULL to skip the lookup
* @param last Last available byte in buffer (to prevent buffer overflows); not used when title == NULL
* @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a savegame * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a savegame
* @see FiosGetFileList * @see FiosGetFileList
* @see FiosGetSavegameList * @see FiosGetSavegameList
*/ */
FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title) FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last)
{ {
/* Show savegame files /* Show savegame files
* .SAV OpenTTD saved game * .SAV OpenTTD saved game
@ -314,7 +315,7 @@ FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file,
if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) { if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) {
if (strcasecmp(ext, ".ss1") == 0 || strcasecmp(ext, ".sv1") == 0 || if (strcasecmp(ext, ".ss1") == 0 || strcasecmp(ext, ".sv1") == 0 ||
strcasecmp(ext, ".sv2") == 0) { strcasecmp(ext, ".sv2") == 0) {
if (title != NULL) GetOldSaveGameName(title, _fios_path, file); if (title != NULL) GetOldSaveGameName(_fios_path, file, title, last);
return FIOS_TYPE_OLDFILE; return FIOS_TYPE_OLDFILE;
} }
} }
@ -348,11 +349,12 @@ void FiosGetSavegameList(SaveLoadDialogMode mode)
* @param file Name of the file to check. * @param file Name of the file to check.
* @param ext A pointer to the extension identifier inside file * @param ext A pointer to the extension identifier inside file
* @param title Buffer if a callback wants to lookup the title of the file * @param title Buffer if a callback wants to lookup the title of the file
* @param last Last available byte in buffer (to prevent buffer overflows)
* @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a scenario * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a scenario
* @see FiosGetFileList * @see FiosGetFileList
* @see FiosGetScenarioList * @see FiosGetScenarioList
*/ */
static FiosType FiosGetScenarioListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title) static FiosType FiosGetScenarioListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last)
{ {
/* Show scenario files /* Show scenario files
* .SCN OpenTTD style scenario file * .SCN OpenTTD style scenario file
@ -362,7 +364,7 @@ static FiosType FiosGetScenarioListCallback(SaveLoadDialogMode mode, const char
if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO || mode == SLD_NEW_GAME) { if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO || mode == SLD_NEW_GAME) {
if (strcasecmp(ext, ".sv0") == 0 || strcasecmp(ext, ".ss0") == 0 ) { if (strcasecmp(ext, ".sv0") == 0 || strcasecmp(ext, ".ss0") == 0 ) {
GetOldSaveGameName(title, _fios_path, file); GetOldSaveGameName(_fios_path, file, title, last);
return FIOS_TYPE_OLD_SCENARIO; return FIOS_TYPE_OLD_SCENARIO;
} }
} }
@ -391,7 +393,7 @@ void FiosGetScenarioList(SaveLoadDialogMode mode)
FiosGetFileList(mode, &FiosGetScenarioListCallback); FiosGetFileList(mode, &FiosGetScenarioListCallback);
} }
static FiosType FiosGetHeightmapListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title) static FiosType FiosGetHeightmapListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last)
{ {
/* Show heightmap files /* Show heightmap files
* .PNG PNG Based heightmap files * .PNG PNG Based heightmap files

View File

@ -106,7 +106,7 @@ bool FiosDelete(const char *name);
/* Make a filename from a name */ /* Make a filename from a name */
void FiosMakeSavegameName(char *buf, const char *name, size_t size); void FiosMakeSavegameName(char *buf, const char *name, size_t size);
/* Determines type of savegame (or tells it is not a savegame) */ /* Determines type of savegame (or tells it is not a savegame) */
FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title); FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last);
int CDECL compare_FiosItems(const void *a, const void *b); int CDECL compare_FiosItems(const void *a, const void *b);

View File

@ -514,7 +514,7 @@ int ttd_main(int argc, char *argv[])
/* if the file doesn't exist or it is not a valid savegame, let the saveload code show an error */ /* if the file doesn't exist or it is not a valid savegame, let the saveload code show an error */
const char *t = strrchr(_file_to_saveload.name, '.'); const char *t = strrchr(_file_to_saveload.name, '.');
if (t != NULL) { if (t != NULL) {
FiosType ft = FiosGetSavegameListCallback(SLD_LOAD_GAME, _file_to_saveload.name, t, NULL); FiosType ft = FiosGetSavegameListCallback(SLD_LOAD_GAME, _file_to_saveload.name, t, NULL, NULL);
if (ft != FIOS_TYPE_INVALID) SetFiosType(ft); if (ft != FIOS_TYPE_INVALID) SetFiosType(ft);
} }

View File

@ -25,6 +25,7 @@
#include "../variables.h" #include "../variables.h"
#include "../strings_func.h" #include "../strings_func.h"
#include "../effectvehicle_base.h" #include "../effectvehicle_base.h"
#include "../string_func.h"
#include "table/strings.h" #include "table/strings.h"
@ -1571,19 +1572,23 @@ bool LoadOldSaveGame(const char *file)
return true; return true;
} }
void GetOldSaveGameName(char *title, const char *path, const char *file) void GetOldSaveGameName(const char *path, const char *file, char *title, const char *last)
{ {
char filename[MAX_PATH]; char filename[MAX_PATH];
FILE *f; char temp[HEADER_SIZE - 1];
snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file); snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file);
f = fopen(filename, "rb"); FILE *f = fopen(filename, "rb");
title[0] = '\0'; temp[0] = '\0';
title[48] = '\0'; temp[HEADER_SIZE - 2] = '\0';
if (f == NULL) return; if (f == NULL) return;
if (fread(title, 1, 48, f) != 48) snprintf(title, 48, "Corrupt file"); if (fread(temp, 1, HEADER_SIZE - 2, f) != HEADER_SIZE - 2) {
seprintf(title, last, "Corrupt file");
} else {
seprintf(title, last, temp);
}
fclose(f); fclose(f);
} }