mirror of
https://github.com/luanti-org/luanti.git
synced 2026-01-14 13:25:21 +01:00
Serialize: Throw exception on incomplete reads (#16796)
Several mistakes were made past where the stream was expected to raise the EOF flag when reaching the end of stream. That is incorrect. The flag is only raised if the current read operation fails. This commit unifies all istream compatibility code to use 'canRead' for reliable EOF detection. An exception is now thrown when a value cannot be read completely (e.g. missing bytes). Version comments are added for easier backtracing.
This commit is contained in:
@@ -92,7 +92,7 @@ void AreaStore::deserialize(std::istream &is)
|
||||
areas.emplace_back(std::move(a));
|
||||
}
|
||||
|
||||
bool read_ids = is.good(); // EOF for old formats
|
||||
const bool read_ids = canRead(is); // since 5.1.0-dev
|
||||
|
||||
for (auto &area : areas) {
|
||||
if (read_ids)
|
||||
|
||||
@@ -377,11 +377,25 @@ inline void writeV3F32(u8 *data, v3f p)
|
||||
//// Iostream wrapper for data read/write
|
||||
////
|
||||
|
||||
inline bool canRead(std::istream &is)
|
||||
{
|
||||
return is.peek() != EOF;
|
||||
}
|
||||
|
||||
// Assuming -O3 on GCC 14.2.0, this function results in 55% less machine code
|
||||
// generated for the `is.eof()` branch in `MAKE_STREAM_READ_FXN`.
|
||||
static void serialize_throw_eof()
|
||||
{
|
||||
throw SerializationError("EOF");
|
||||
}
|
||||
|
||||
#define MAKE_STREAM_READ_FXN(T, N, S) \
|
||||
inline T read ## N(std::istream &is) \
|
||||
{ \
|
||||
char buf[S] = {0}; \
|
||||
is.read(buf, sizeof(buf)); \
|
||||
if (is.eof()) \
|
||||
serialize_throw_eof(); \
|
||||
return read ## N((u8 *)buf); \
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user