CNA-BUG-258: LocalNetworkGamer::ReceiveData(byte buffer, offset) dequeues and silently truncates a packet larger than the buffer, where XNA throws ArgumentException without dequeuing
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
The byte-array overload pops the next packet, copies min(packet size, buffer size) bytes and returns the packet's data as if it had fit; XNA peeks first and throws ArgumentException (PacketArrayTooSmall) without consuming the packet.
- Identifier
CNA-BUG-258- Category
- Bug
- Subsystem
- Networking & gamer services
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- CNA::LocalNetworkGamer::ReceiveData(std::vector<byte>& data, int offset, NetworkGamer*& sender) and the overload without an offset (Microsoft::Xna::Framework::Net::LocalNetworkGamer)
Expected behaviour
XNA 4.0's ReceiveData(byte[] data, int offset, out NetworkGamer sender) (read from the decompiled genuine Microsoft.Xna.Framework.Net assembly) peeks at the next packet and, when offset + packet.Size > data.Length, throws ArgumentException(PacketArrayTooSmall) before it dequeues, so a caller that supplied too small a buffer keeps the packet and learns the size it needs. Only then does it dequeue and copy.
Actual behaviour at TARGET
LocalNetworkGamer::ReceiveData moves the front packet out of packetQueue_ and pops it first, then computes len = min(packet size, data.size()). A packet larger than the buffer is therefore consumed and truncated to the buffer size, and the call returns without an error; the exception path only fires when offset is negative or offset + len exceeds the buffer. A comment in the function records that the ordering “match[es] FNA's Dequeue()-before-Array.Copy”: it is a deliberate port of FNA, whereas CNA's rule is that XNA wins where the two disagree.
Source locations
modules/net/src/Xna/LocalNetworkGamer.cpp— ReceiveData(std::vector<byte>&, int, NetworkGamer*&): pop, then min(size), then copy
Evidence
Read at 009d40f5 against the decompiled XNA 4.0 assembly (xna4-decomp); nothing was built or executed. Reported as a possible unpublished defect by the R08 networking reviewer and re-verified by the orchestrator. Distinct from CNA-BUG-171 (the PacketReader overload does not resize its reader) and CNA-BUG-174 (that overload returns 0 instead of the packet size).
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
The gamer tests cover receiving into an adequately sized buffer and the empty queue; none supplies a buffer smaller than the next packet.
Regression test
Queue a packet, call ReceiveData with a buffer one byte too small and expect an ArgumentException and the packet still queued; then a call with an adequate buffer must return it whole.
Blast radius
Code that receives packets into fixed-size byte buffers: an oversized packet is silently cut and lost instead of raising the exception XNA programs may rely on to size their buffers. Callers whose buffers always fit are unaffected.
Workaround
Size the buffer from a known maximum packet size, or receive through the PacketReader overload.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- XNA compatibility
- Internals
- Networking internals
- Deep dives
- Network sessions: packets
- Known issues
- Bug index