1
0
mirror of https://github.com/luanti-org/luanti.git synced 2026-01-14 05:15: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:
SmallJoker
2026-01-03 11:13:14 +01:00
committed by GitHub
parent 6079d762ce
commit 3d10d4e859
13 changed files with 207 additions and 179 deletions

View File

@@ -465,20 +465,12 @@ void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt)
std::string datastring(pkt->getString(0), pkt->getSize());
std::istringstream is(datastring, std::ios_base::binary);
try {
while (is.good()) {
u16 id = readU16(is);
if (!is.good())
break;
while (canRead(is)) {
u16 id = readU16(is);
std::string message = deSerializeString16(is);
std::string message = deSerializeString16(is);
// Pass on to the environment
m_env.processActiveObjectMessage(id, message);
}
} catch (SerializationError &e) {
errorstream << "Client::handleCommand_ActiveObjectMessages: "
<< "caught SerializationError: " << e.what() << std::endl;
// Pass on to the environment
m_env.processActiveObjectMessage(id, message);
}
}
@@ -989,7 +981,7 @@ void Client::handleCommand_SpawnParticleBatch(NetworkPacket *pkt)
decompressZstd(compressed, particle_batch_data);
}
while (particle_batch_data.peek() != EOF) {
while (canRead(particle_batch_data)) {
auto p = std::make_unique<ParticleParameters>();
{
std::istringstream particle_data(deSerializeString32(particle_batch_data), std::ios::binary);
@@ -1049,25 +1041,24 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
p.glow = readU8(is);
p.object_collision = readU8(is);
// This is kinda awful
do {
u16 tmp_param0 = readU16(is);
if (is.eof())
if (!canRead(is))
break;
p.node.param0 = tmp_param0;
// >= 5.3.0-dev
p.node.param0 = readU16(is);;
p.node.param2 = readU8(is);
p.node_tile = readU8(is);
if (m_proto_ver < 42) {
// v >= 5.6.0
f32 tmp_sbias = readF32(is);
if (is.eof())
if (!canRead(is))
break;
// initial bias must be stored separately in the stream to preserve
// backwards compatibility with older clients, which do not support
// a bias field in their range "format"
p.pos.start.bias = tmp_sbias;
p.pos.start.bias = readF32(is);
p.vel.start.bias = readF32(is);
p.acc.start.bias = readF32(is);
p.exptime.start.bias = readF32(is);
@@ -1112,6 +1103,10 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
newtex.deSerialize(is, m_proto_ver);
p.texpool.push_back(newtex);
}
//if (!canRead(is))
// break;
// Add new code here
} while(0);
if (missing_end_values) {