Repository navigation
fix(#5361): FrameLimits — enforce wire bounds at encode AND decode (no-alloc rejects) - #5372
Merged
Merged
Conversation
…o-alloc rejects) Phase 1 of the production-HA plan (#5354), sub-issue #5361 (acceptance A3: frame fuzz/boundary tests reject malformed input without OOM). The gap: the frame codec accepted whatever sizes the header advertised. A malformed or hostile frame declaring dataLen=2^31-1 made the decoder allocate that much memory before failing on the truncated body (OOM instead of a clean reject); truncated buffers escaped as BufferUnderflowException instead of IllegalArgumentException. New FrameLimits (eventmesh-common/wire): - MAX_FRAME_BYTES 16 MiB, MAX_DATA_BYTES 8 MiB, MAX_ATTRIBUTES 64, MAX_ATTR_NAME_BYTES 256, MAX_ATTR_VALUE_BYTES 4 KiB - generous for streaming chunks / large CloudEvents payloads while bounding a single frame's memory footprint. Encode boundary: a producer cannot build an oversized frame (attribute count, data length, attr name/value length, total encoded size all fail fast with IllegalArgumentException). Decode boundary: advertised keyCount/dataLen are rejected BEFORE any allocation; every buffer read (attribute length prefixes, string bodies, the data bulk get) is guarded so a truncated frame fails as IllegalArgumentException - never BufferUnderflowException, never an over-allocation. decode is now total: any byte sequence either decodes or throws IllegalArgumentException. Tests (new FrameLimitsTest, 8 cases): - 4 encode-bound rejects + at-the-limit acceptance (boundary is >) - hostile dataLen=Integer.MAX_VALUE on a 64-byte buffer: clean IllegalArgumentException, no allocation - hostile keyCount; dataLen beyond provided buffer - deterministic 20,000-iteration byte-mutation fuzz: every mutant either decodes or throws IllegalArgumentException (found and fixed the two underflow escapes above during development) Local verification (Temurin 21.0.11): common tests + checkstyle (maxWarnings=0) green; downstream runtime + architecture-guard + storage-api tests green. Refs #5361 (sub-issue of #5354). Co-authored-by: qqeasonchen <qqeasonchen@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Closes #5361 — Phase 1 of the production-HA plan (#5354), acceptance A3: the frame codec enforces wire bounds at BOTH boundaries and rejects malformed input without OOM.
1. The gap this fixes
The codec accepted whatever sizes the header advertised. A hostile frame declaring
dataLen = 2^31-1made the decoder allocate that much memory before failing on the truncated body (OOM instead of a clean reject); truncated buffers escaped asBufferUnderflowException.2. New
FrameLimits(eventmesh-common/wire)MAX_FRAME_BYTESMAX_DATA_BYTESMAX_ATTRIBUTESMAX_ATTR_NAME_BYTESMAX_ATTR_VALUE_BYTES3. Boundary enforcement
keyCount/dataLenrejected before any allocation; every buffer read (attribute length prefixes, string bodies, data bulk-get) guarded.decodeis now total: any byte sequence either decodes or throwsIllegalArgumentException— never underflow, never over-allocation.4. Tests (new
FrameLimitsTest, 8 cases)>)dataLen=Integer.MAX_VALUEon a 64-byte buffer → cleanIllegalArgumentException, no allocationkeyCount;dataLenbeyond provided bufferIllegalArgumentException(the fuzz found and drove the fix for both underflow escapes during development)Verification (local, Temurin 21.0.11)
Relations
b3f9f75b4) and [P0] propagate FencingToken epoch through dispatch / ACK / offset / DLQ #5360 (017843ef1)docs/architecture-review/production-ha-plan.md(PR docs(#5354): production-HA acceptance plan — 10-issue topology (#5356-#5365) #5366)7ac0ab824)Co-authored-by: qqeasonchen qqeasonchen@gmail.com