From 24df43633cb1f647f71867512ce4cbc9f9672561 Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 30 Jul 2010 22:57:46 +0000 Subject: [PATCH] (svn r20247) -Fix: when it is known the loading an old savegame is going to fail, bail out immediately (using an exception) instead of going on until e.g. the expected number of byte is read --- src/saveload/oldloader.cpp | 19 +++++++++++++------ src/saveload/oldloader.h | 1 - src/saveload/oldloader_sl.cpp | 18 ++++++++++++------ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/saveload/oldloader.cpp b/src/saveload/oldloader.cpp index b0688ed7a3..65e881869e 100644 --- a/src/saveload/oldloader.cpp +++ b/src/saveload/oldloader.cpp @@ -22,6 +22,8 @@ #include "saveload_internal.h" #include "oldloader.h" +#include + static const int TTO_HEADER_SIZE = 41; static const int TTD_HEADER_SIZE = 49; @@ -49,13 +51,14 @@ static byte ReadByteFromFile(LoadgameState *ls) /* To avoid slow reads, we read BUFFER_SIZE of bytes per time and just return a byte per time */ if (ls->buffer_cur >= ls->buffer_count) { + /* Read some new bytes from the file */ int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file); /* We tried to read, but there is nothing in the file anymore.. */ if (count == 0) { DEBUG(oldloader, 0, "Read past end of file, loading failed"); - ls->failed = true; + throw std::exception(); } ls->buffer_count = count; @@ -119,8 +122,6 @@ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks) if (chunk->type & OC_DEREFERENCE_POINTER) ptr = *(byte**)ptr; for (uint i = 0; i < chunk->amount; i++) { - if (ls->failed) return false; - /* Handle simple types */ if (GetOldChunkType(chunk->type) != 0) { switch (GetOldChunkType(chunk->type)) { @@ -135,7 +136,7 @@ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks) case OC_ASSERT: DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value); - if (ls->total_read != chunk->offset + _bump_assert_value) ls->failed = true; + if (ls->total_read != chunk->offset + _bump_assert_value) throw std::exception(); default: break; } } else { @@ -189,7 +190,6 @@ static void InitLoading(LoadgameState *ls) { ls->chunk_size = 0; ls->total_read = 0; - ls->failed = false; ls->decoding = false; ls->decode_char = 0; @@ -301,7 +301,14 @@ bool LoadOldSaveGame(const char *file) _savegame_type = type; - if (proc == NULL || !proc(&ls)) { + bool game_loaded; + try { + game_loaded = proc != NULL && proc(&ls); + } catch (...) { + game_loaded = false; + } + + if (!game_loaded) { SetSaveLoadError(STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED); fclose(ls.file); return false; diff --git a/src/saveload/oldloader.h b/src/saveload/oldloader.h index 6720a28a65..19ba09cc37 100644 --- a/src/saveload/oldloader.h +++ b/src/saveload/oldloader.h @@ -31,7 +31,6 @@ struct LoadgameState { byte buffer[BUFFER_SIZE]; uint total_read; - bool failed; }; /* OldChunk-Type */ diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index cabbcb0ac0..7e3c66ad1d 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -1479,7 +1479,7 @@ static bool LoadOldMapPart1(LoadgameState *ls, int num) } } - return !ls->failed; + return true; } static bool LoadOldMapPart2(LoadgameState *ls, int num) @@ -1493,7 +1493,7 @@ static bool LoadOldMapPart2(LoadgameState *ls, int num) _m[i].m5 = ReadByte(ls); } - return !ls->failed; + return true; } static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num) @@ -1548,7 +1548,7 @@ static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num) } } - return !ls->failed; + return true; } extern TileIndex _cur_tileloop_tile; @@ -1734,11 +1734,17 @@ bool LoadTTDMain(LoadgameState *ls) SmallStackSafeStackAlloc map3; _old_map3 = map3.data; _old_vehicle_names = NULL; - if (!LoadChunk(ls, NULL, main_chunk)) { - DEBUG(oldloader, 0, "Loading failed"); + try { + if (!LoadChunk(ls, NULL, main_chunk)) { + DEBUG(oldloader, 0, "Loading failed"); + free(_old_vehicle_names); + return false; + } + } catch (...) { free(_old_vehicle_names); - return false; + throw; } + DEBUG(oldloader, 3, "Done, converting game data..."); FixTTDMapArray();