From f27ca88596973af30a57de66788ebf82bc9db70f Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 12 Sep 2015 13:33:35 +0100 Subject: [PATCH 1/3] Show error message instead of aborting when loading an invalid map size. --- src/map.cpp | 25 +++++++++++++++++++------ src/map_func.h | 1 + src/saveload/map_sl.cpp | 3 +++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index 392ab8ab6c..a8023c9226 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -32,17 +32,14 @@ uint _map_tile_mask; ///< _map_size - 1 (to mask the mapsize) Tile *_m = NULL; ///< Tiles of the map TileExtended *_me = NULL; ///< Extended Tiles of the map - /** - * (Re)allocates a map with the given dimension + * Validates whether a map with the given dimension is valid * @param size_x the width of the map along the NE/SW edge * @param size_y the 'height' of the map along the SE/NW edge + * @return true if valid, or false if not valid */ -void AllocateMap(uint size_x, uint size_y) +bool ValidateMapSize(uint size_x, uint size_y) { - DEBUG(map, 2, "Min/max map size %d/%d, max map tiles %d", MIN_MAP_SIZE, MAX_MAP_SIZE, MAX_MAP_TILES); - DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); - /* Make sure that the map size is within the limits and that * size of both axes is a power of 2. */ if (size_x * size_y > MAX_MAP_TILES || @@ -50,6 +47,22 @@ void AllocateMap(uint size_x, uint size_y) size_y < MIN_MAP_SIZE || (size_x & (size_x - 1)) != 0 || (size_y & (size_y - 1)) != 0) { + return false; + } + return true; +} + +/** + * (Re)allocates a map with the given dimension + * @param size_x the width of the map along the NE/SW edge + * @param size_y the 'height' of the map along the SE/NW edge + */ +void AllocateMap(uint size_x, uint size_y) +{ + DEBUG(map, 2, "Min/max map size %d/%d, max map tiles %d", MIN_MAP_SIZE, MAX_MAP_SIZE, MAX_MAP_TILES); + DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); + + if (!ValidateMapSize(size_x, size_y)) { error("Invalid map size"); } diff --git a/src/map_func.h b/src/map_func.h index 9198c2cd1f..b390f0eaef 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -43,6 +43,7 @@ extern Tile *_m; */ extern TileExtended *_me; +bool ValidateMapSize(uint size_x, uint size_y); void AllocateMap(uint size_x, uint size_y); /** diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 86a185ca42..ee157ec17c 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -37,6 +37,9 @@ static void Save_MAPS() static void Load_MAPS() { SlGlobList(_map_dimensions); + if (!ValidateMapSize(_map_dim_x, _map_dim_y)) { + SlErrorCorruptFmt("Invalid map size: %u x %u", _map_dim_x, _map_dim_y); + } AllocateMap(_map_dim_x, _map_dim_y); } From d6395b97a75331cb0a2635545456f323f73a2d94 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 12 Sep 2015 14:15:04 +0100 Subject: [PATCH 2/3] Enable extended feature versions for saving to be set at run time. --- src/saveload/extended_ver_sl.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index be40cad17b..6e13994e67 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -164,7 +164,6 @@ static void Save_SLXI() SlXvSetCurrentState(); static const SaveLoad _xlsi_sub_chunk_desc[] = { - SLE_VAR(SlxiSubChunkInfo, save_version, SLE_UINT16), SLE_STR(SlxiSubChunkInfo, name, SLE_STR, 0), SLE_END() }; @@ -178,9 +177,9 @@ static void Save_SLXI() chunk_counts.resize(XSLFI_SIZE); const SlxiSubChunkInfo *info = _sl_xv_sub_chunk_infos; for (; info->index != XSLFI_NULL; ++info) { - if (info->save_version > 0) { + if (_sl_xv_feature_versions[info->index] > 0) { item_count++; - length += 4; + length += 6; length += SlCalcObjLength(info, _xlsi_sub_chunk_desc); if (info->save_proc) { uint32 extra_data_length = info->save_proc(info, true); @@ -208,7 +207,8 @@ static void Save_SLXI() // write data info = _sl_xv_sub_chunk_infos; for (; info->index != XSLFI_NULL; ++info) { - if (info->save_version > 0) { + uint16 save_version = _sl_xv_feature_versions[info->index]; + if (save_version > 0) { SlxiSubChunkFlags flags = info->flags; assert(!(flags & (XSCF_EXTRA_DATA_PRESENT | XSCF_CHUNK_ID_LIST_PRESENT))); uint32 extra_data_length = extra_data_lengths[info->index]; @@ -216,6 +216,7 @@ static void Save_SLXI() if (extra_data_length > 0) flags |= XSCF_EXTRA_DATA_PRESENT; if (chunk_count > 0) flags |= XSCF_CHUNK_ID_LIST_PRESENT; SlWriteUint32(flags); + SlWriteUint16(save_version); SlObject(const_cast(info), _xlsi_sub_chunk_desc); if (extra_data_length > 0) { From 421b9034e2a4d159c98c40c58b345dac217deab0 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 12 Sep 2015 14:17:37 +0100 Subject: [PATCH 3/3] Add an extended version feature for map sizes > 8kx8k. This is to prevent earlier versions from trying to load the savegame and aborting. --- src/saveload/extended_ver_sl.cpp | 5 +++++ src/saveload/extended_ver_sl.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 6e13994e67..36fad17326 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -32,6 +32,7 @@ #include "../debug.h" #include "saveload.h" #include "extended_ver_sl.h" +#include "../map_func.h" #include @@ -45,6 +46,7 @@ std::vector _sl_xv_discardable_chunk_ids; ///< list of chunks static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { + { XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", NULL, NULL, NULL }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; @@ -108,6 +110,9 @@ void SlXvSetCurrentState() for (; info->index != XSLFI_NULL; ++info) { _sl_xv_feature_versions[info->index] = info->save_version; } + if (MapSizeX() > 8192 || MapSizeY() > 8192) { + _sl_xv_feature_versions[XSLFI_EXTRA_LARGE_MAP] = 1; + } } /** diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index 39a03478c2..6602a0da5d 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -21,6 +21,7 @@ */ enum SlXvFeatureIndex { XSLFI_NULL = 0, ///< Unused value, to indicate that no extended feature test is in use + XSLFI_EXTRA_LARGE_MAP, ///< Extra large map XSLFI_SIZE, ///< Total count of features, including null feature };