From a45e86d9241544a3153ef7e6e3da819156c0190e Mon Sep 17 00:00:00 2001 From: Glenn Fiedler Date: Tue, 8 Sep 2026 01:41:58 -0400 Subject: [PATCH 1/2] Give payload packets eight bytes of tail slack Johnny Grok: payload_data was a 1-byte flexible tail. BitReader loads an 8-byte window, so declare the array 8 bytes. sizeof already includes it; allocate sizeof+payload_bytes as before. --- netcode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netcode.c b/netcode.c index 9245ca5..65e091a 100755 --- a/netcode.c +++ b/netcode.c @@ -1487,7 +1487,7 @@ struct netcode_connection_payload_packet_t { uint8_t packet_type; uint32_t payload_bytes; - uint8_t payload_data[1]; + uint8_t payload_data[8]; }; struct netcode_connection_disconnect_packet_t From ca1030d18d79686a84f1e45e772a7c9e42d0cedf Mon Sep 17 00:00:00 2001 From: Glenn Fiedler Date: Tue, 8 Sep 2026 02:13:02 -0400 Subject: [PATCH 2/2] Pin the payload tail at eight bytes for the reader contract Johnny Grok: #188 follow-up. The array size is the slack serialize's BitReader needs. A compile-time check holds sizeof minus the payload offset at least eight, so a later trim cannot reintroduce the finding. --- netcode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/netcode.c b/netcode.c index 65e091a..0e5ebf7 100755 --- a/netcode.c +++ b/netcode.c @@ -1487,9 +1487,17 @@ struct netcode_connection_payload_packet_t { uint8_t packet_type; uint32_t payload_bytes; + /* serialize's BitReader loads an 8-byte window from the current byte, so a + read in the last payload byte reaches 7 past it. This array is the last + member; sizeof(*packet)+payload_bytes is allocated, leaving 8 bytes + behind the returned payload pointer. Do not shrink it. */ uint8_t payload_data[8]; }; +typedef char netcode_payload_packet_tail_holds_reader_slack[ + ( sizeof( struct netcode_connection_payload_packet_t ) + - offsetof( struct netcode_connection_payload_packet_t, payload_data ) >= 8 ) ? 1 : -1 ]; + struct netcode_connection_disconnect_packet_t { uint8_t packet_type;