diff options
author | smatz <smatz@openttd.org> | 2009-07-13 11:09:02 +0000 |
---|---|---|
committer | smatz <smatz@openttd.org> | 2009-07-13 11:09:02 +0000 |
commit | aa7bcb1259aef0c71523b9ccc945840edcf9c6b1 (patch) | |
tree | 5723d51f450d7021d1207fc55d4bb404c23d3e8d | |
parent | a67f861d5505106ec8b919222da762ab7d185af6 (diff) | |
download | openttd-aa7bcb1259aef0c71523b9ccc945840edcf9c6b1.tar.xz |
(svn r16808) -Fix (r16338): don't crash when loading savegame with invalid references
-rw-r--r-- | src/saveload/saveload.cpp | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 46c6104e6..54f2c451f 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -1135,6 +1135,8 @@ static void SlLoadChunks() } } +static const char *_sl_ptrs_error; ///< error message if there was an error during fixing pointers, NULL otherwise + /** Fix all pointers (convert index -> pointer) */ static void SlFixPointers() { @@ -1142,6 +1144,7 @@ static void SlFixPointers() const ChunkHandler * const *chsc; _sl.action = SLA_PTRS; + _sl_ptrs_error = NULL; DEBUG(sl, 1, "Fixing pointers"); @@ -1157,6 +1160,9 @@ static void SlFixPointers() } } + /* We need to fix all possible pointers even if there were invalid ones. This way pool cleaning will work fine. */ + if (_sl_ptrs_error != NULL) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, _sl_ptrs_error); + DEBUG(sl, 1, "All pointers fixed"); assert(_sl.action == SLA_PTRS); @@ -1520,41 +1526,55 @@ static void *IntToReference(size_t index, SLRefType rt) switch (rt) { case REF_ORDERLIST: if (OrderList::IsValidID(index)) return OrderList::Get(index); - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid OrderList"); + _sl_ptrs_error = "Referencing invalid OrderList"; + break; case REF_ORDER: if (Order::IsValidID(index)) return Order::Get(index); /* in old versions, invalid order was used to mark end of order list */ if (CheckSavegameVersionOldStyle(5, 2)) return NULL; - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Order"); + _sl_ptrs_error = "Referencing invalid Order"; + break; case REF_VEHICLE_OLD: case REF_VEHICLE: if (Vehicle::IsValidID(index)) return Vehicle::Get(index); - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Vehicle"); + _sl_ptrs_error = "Referencing invalid Vehicle"; + break; case REF_STATION: if (Station::IsValidID(index)) return Station::Get(index); - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Station"); + _sl_ptrs_error = "Referencing invalid Station"; + break; case REF_TOWN: if (Town::IsValidID(index)) return Town::Get(index); - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Town"); + _sl_ptrs_error = "Referencing invalid Town"; + break; case REF_ROADSTOPS: if (RoadStop::IsValidID(index)) return RoadStop::Get(index); - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid RoadStop"); + _sl_ptrs_error = "Referencing invalid RoadStop"; + break; case REF_ENGINE_RENEWS: if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index); - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid EngineRenew"); + _sl_ptrs_error = "Referencing invalid EngineRenew"; + break; case REF_CARGO_PACKET: if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index); - SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid CargoPacket"); + _sl_ptrs_error = "Referencing invalid CargoPacket"; + break; default: NOT_REACHED(); } + + /* Print a debug message about each invalid reference */ + DEBUG(sl, 1, "%s (index = " PRINTF_SIZE ")", _sl_ptrs_error, index); + + /* Return NULL for broken savegames */ + return NULL; } /** The format for a reader/writer type of a savegame */ |