From 80a7408e4d17e0e388f2d45fb90c5524a5dd7c89 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Mon, 26 Jan 2015 15:52:02 +0100 Subject: [PATCH] Fix a crash (assert) when client set serial version < 24 in INIT When SER_FMT_VER_LOWEST is set to zero, then the test is stupid in INIT because all client works. In mapblock we check if client's serialization version is < 24, but if client sent serialization version < 24 (15 for example) the server set it and tried to send nodes, then BOOM To resolve the problem: * Create a different CLIENT_MIN_VERSION to handle this problem * Remove the exception * Use an assert in case of bad developer code --- src/mapblock.cpp | 6 +----- src/mapblock.h | 1 + src/serialization.h | 4 ++++ src/server.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 4cc0abc8..ecd9a016 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -526,11 +526,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) throw SerializationError("ERROR: Not writing dummy block."); } - // Can't do this anymore; we have 16-bit dynamically allocated node IDs - // in memory; conversion just won't work in this direction. - if(version < 24) - throw SerializationError("MapBlock::serialize: serialization to " - "version < 24 not possible"); + assert(version >= SER_FMT_CLIENT_VER_LOWEST); // First byte u8 flags = 0; diff --git a/src/mapblock.h b/src/mapblock.h index 5cf2bc80..e7d7798b 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -494,6 +494,7 @@ public: // These don't write or read version by itself // Set disk to true for on-disk format, false for over-the-network format + // Precondition: version >= SER_FMT_CLIENT_VER_LOWEST void serialize(std::ostream &os, u8 version, bool disk); // If disk == true: In addition to doing other things, will add // unknown blocks from id-name mapping to wndef diff --git a/src/serialization.h b/src/serialization.h index caa1a66d..ab6fe0f7 100644 --- a/src/serialization.h +++ b/src/serialization.h @@ -71,6 +71,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #define SER_FMT_VER_HIGHEST_WRITE 25 // Lowest supported serialization version #define SER_FMT_VER_LOWEST 0 +// Lowest client supported serialization version +// Can't do < 24 anymore; we have 16-bit dynamically allocated node IDs +// in memory; conversion just won't work in this direction. +#define SER_FMT_CLIENT_VER_LOWEST 24 inline bool ser_ver_supported(s32 v) { return v >= SER_FMT_VER_LOWEST && v <= SER_FMT_VER_HIGHEST_READ; diff --git a/src/server.cpp b/src/server.cpp index 2b5fe9b0..31b5041e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1366,7 +1366,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // Use the highest version supported by both int deployed = std::min(client_max, our_max); // If it's lower than the lowest supported, give up. - if(deployed < SER_FMT_VER_LOWEST) + if(deployed < SER_FMT_CLIENT_VER_LOWEST) deployed = SER_FMT_VER_INVALID; if(deployed == SER_FMT_VER_INVALID)