mirror of
https://github.com/luanti-org/luanti.git
synced 2026-01-13 12:45:29 +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:
@@ -221,25 +221,6 @@ void ObjectProperties::serialize(std::ostream &os) const
|
||||
// Never remove anything, because we don't want new versions of this!
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Type-safe wrapper for bools as u8
|
||||
inline bool readBool(std::istream &is)
|
||||
{
|
||||
return readU8(is) != 0;
|
||||
}
|
||||
|
||||
// Wrapper for primitive reading functions that don't throw (awful)
|
||||
template <typename T, T (reader)(std::istream& is)>
|
||||
bool tryRead(T& val, std::istream& is)
|
||||
{
|
||||
T tmp = reader(is);
|
||||
if (is.eof())
|
||||
return false;
|
||||
val = tmp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectProperties::deSerialize(std::istream &is)
|
||||
{
|
||||
int version = readU8(is);
|
||||
@@ -295,40 +276,50 @@ void ObjectProperties::deSerialize(std::istream &is)
|
||||
zoom_fov = readF32(is);
|
||||
use_texture_alpha = readU8(is);
|
||||
|
||||
try {
|
||||
damage_texture_modifier = deSerializeString16(is);
|
||||
} catch (SerializationError &e) {
|
||||
if (!canRead(is))
|
||||
return;
|
||||
}
|
||||
// >= 5.3.0-dev
|
||||
|
||||
if (!tryRead<bool, readBool>(shaded, is))
|
||||
return;
|
||||
|
||||
if (!tryRead<bool, readBool>(show_on_minimap, is))
|
||||
damage_texture_modifier = deSerializeString16(is);
|
||||
shaded = readU8(is);
|
||||
|
||||
if (!canRead(is))
|
||||
return;
|
||||
// >= 5.4.0-dev
|
||||
|
||||
show_on_minimap = readU8(is);
|
||||
auto bgcolor = readARGB8(is);
|
||||
if (bgcolor != NULL_BGCOLOR)
|
||||
nametag_bgcolor = bgcolor;
|
||||
else
|
||||
nametag_bgcolor = std::nullopt;
|
||||
|
||||
if (!tryRead<bool, readBool>(rotate_selectionbox, is))
|
||||
if (!canRead(is))
|
||||
return;
|
||||
// >= 5.7.0-dev
|
||||
|
||||
if (!tryRead<content_t, readU16>(node.param0, is))
|
||||
rotate_selectionbox = readU8(is);
|
||||
|
||||
if (!canRead(is))
|
||||
return;
|
||||
// >= 5.12.0-dev
|
||||
|
||||
node.param0 = readU16(is);
|
||||
node.param1 = readU8(is);
|
||||
node.param2 = readU8(is);
|
||||
|
||||
u32 fontsize;
|
||||
if (!tryRead<u32, readU32>(fontsize, is))
|
||||
if (!canRead(is))
|
||||
return;
|
||||
// >= 5.14.0-dev
|
||||
|
||||
const u32 fontsize = readU32(is);
|
||||
if (fontsize != U32_MAX)
|
||||
nametag_fontsize = fontsize;
|
||||
else
|
||||
nametag_fontsize = std::nullopt;
|
||||
nametag_scale_z = readU8(is);
|
||||
|
||||
// Add new properties down here and remember to use either tryRead<> or a try-catch.
|
||||
//if (!canRead(is))
|
||||
// return;
|
||||
// Add new code here
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user