Skip to content

Conversation

@SmallJoker
Copy link
Member

This commit replaces all uses of PacketError with 'getRemainingBytes' to more reliably catch issues related to improper read/write implementations. Furthermore, conditions like 'getRemainingBytes() >= 4' could hide potential issues, or even cause misbehaviour if used multiple times. Hence, 'do {} while(0);' + 'break' is now used to avoid such edge-cases.

PacketError handling is moved consistently to

  • Server::Receive
  • Client::ReceiveAll (only to append details, rethrown.)

This is a follow-up on #16796.

To do

This PR is Ready for Review.

How to test

  1. Join a few servers with different versions (such as 5.2.0, 5.9.0)
  2. Play sounds, look at particles
  3. Ensure there's no error showing up.

@SmallJoker SmallJoker added the Maintenance Tasks to keep the codebase and related parts in order, including architectural improvements label Jan 2, 2026
*pkt >> id >> type;
m_env.addActiveObject(id, type, pkt->readLongString());
}
} catch (PacketError &e) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should never occur. This change will cause the client to disconnect and show a technical error message (get_packet_dbg_info). If this change of behaviour is undesired, I can undo that on request.

bool ephemeral = false;

*pkt >> server_id >> spec.name >> spec.gain >> (u8 &)type >> pos >> object_id >> spec.loop;
*pkt >> spec.fade >> spec.pitch;
Copy link
Member Author

@SmallJoker SmallJoker Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to reviewers: Added in 5.0.0-dev, which is guaranteed to be available.

try {
*pkt >> world_pos;
*pkt >> size;
*pkt >> world_pos >> size;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to reviewers: Added in 0.4.16 or so, which is guaranteed to be available.

errorstream << "Server::ProcessData(): SendFailedException: "
<< "what=" << e.what()
<< std::endl;
} catch (PacketError &e) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to reviewers: Moved to Server::Receive, where almost all other exceptions are handled.

@SmallJoker SmallJoker added the Waiting (on dependency) Waiting on another PR or external circumstances (not for rebases/changes requested) label Jan 2, 2026
>> height >> thickness >> speed;

if (pkt->getRemainingBytes() >= 4) {
if (pkt->getRemainingBytes()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer >= 0 to make the intent clearer

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Someone might think that >= 0 should be changed to >= 4 to be sure there's enough bytes to read. That's however incorrect. It should always be checked against 0 to catch incorrectly formatted packets.

How about != 0 instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or: introduce a method and make it pkt->hasRemainingBytes(), given how frequent this pattern will be?

similar to how containers have empty().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with != 0

src/server.cpp Outdated
<< e.what() << std::endl;
} catch (const SerializationError &e) {
} catch (SerializationError &e) {
e.appendBacktrace(get_packet_dbg_info(pkt, true));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking there's no guarantee that the SerializationError actually directly related to an offset in the packet (e.g. with wrapped SAO cmds)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily, but this is better than ... well.. no information at all.

This commit replaces all uses of PacketError with 'getRemainingBytes' to
more reliably catch issues related to improper read/write implementations.
Furthermore, conditions like 'getRemainingBytes() >= 4' could hide potential
issues, or even cause misbehaviour if used multiple times. Hence,
'do {} while(0);' + 'break' is now used to avoid such edge-cases.

PacketError handling is moved consistently to
- Server::Receive
- Client::ReceiveAll (only to append details, rethrown.)
@SmallJoker SmallJoker force-pushed the pr_16800_PacketError_cleanup branch from 9a6c02d to 1dbf4f1 Compare January 3, 2026 10:40
@SmallJoker SmallJoker removed the Waiting (on dependency) Waiting on another PR or external circumstances (not for rebases/changes requested) label Jan 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Maintenance Tasks to keep the codebase and related parts in order, including architectural improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants