fix(binding-mqtt): bound will-message continuation read to the declared payload length - #2534
Conversation
…ed payload length onDecodeConnectWillPayload's continuation branch (used when the will message must be split across multiple frames because the session stream's window is too small to hold it in one write) wrapped the network buffer using the raw decode-window limit instead of bounding it to willPayloadDeferred, the actual number of will-payload bytes still outstanding. When the decode buffer holds more bytes than that (e.g. a pipelined control packet immediately behind the CONNECT, or any other field arriving in the same read), those extra bytes were forwarded downstream as if they were part of the will payload, producing a session-state record longer than its own declared deferred length -- which Kafka rejects as CORRUPT_MESSAGE -- and desynchronizing the network decoder's own progress tracking. Bound the continuation read the same way the first-chunk branch is already bounded: by available network bytes, the session window, and what's actually left of the declared will payload. Also fixes a latent out-of-bounds read in the first-chunk branch, where the wrong accessor was used as the copy length. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015YVNaqKvEXZVzmg3HoGVnt
|
The
This lines up with those two Generated by Claude Code |
|
Update: root-caused and fixed the Generated by Claude Code |
Fixes #2522
onDecodeConnectWillPayload's continuation branch (used when a will message must be split across multiple frames because the session stream's window is too small to hold it in one write) bounded the network buffer read using the raw decode-window limit instead ofwillPayloadDeferred, the actual number of will-payload bytes still outstanding. When the decode buffer held more bytes than that (e.g. a pipelined control packet immediately behind the CONNECT), those extra bytes were forwarded downstream as if they were part of the will payload — producing a session-state record longer than its own declared deferred length, which Kafka rejects asCORRUPT_MESSAGE, and desynchronizing the network decoder's own progress tracking. Also fixes a latent out-of-bounds read in the first-chunk branch using the wrong accessor as the copy length.Credit to community contributor @sfr-oc, who diagnosed and fixed this as part of the combined #2523. This PR cherry-picks that fix's commit standalone, since #2523 bundles seven independently-scoped defects across three bindings into one PR — each deserves its own focused review, and this one is ready on its own.
Test coverage
Includes the original commit's coverage, plus a naming-consistency rename applied here: the new scenario is
session.will.message.disconnect.while.deferred(originallysession.will.message.deferred.trailing.packet), matching this file's existing<event>.while.<state>naming template (e.g.session.will.message.abort.while.deferred) rather than introducing new vocabulary.client.rpt+server.rpt) in bothspecs/binding-mqtt.spec'sapplication/andnetwork/v5/treesspecs/binding-mqtt.spec'sapplication/SessionITandnetwork/v5/SessionIT)runtime/binding-mqtt'sserver/v5/SessionIT#shouldDisconnectWhileDeferred)Verification
ComparisonFailureon the exact-match of the deferred remainder, thenTestTimedOutException(matching the corrupted-boundary/decoder-desync description above) — then restored the fix and confirmed all three IT variants (runtime + both spec-level pairs) pass🤖 Generated with Claude Code
https://claude.ai/code/session_015YVNaqKvEXZVzmg3HoGVnt
Generated by Claude Code