Fix audit findings: append-log value cap, multipart abort, stream-limit detection - #29
Merged
Merged
Conversation
…it detection The append-log writer accepted values up to u32::MAX while replay called anything over 16 MiB corruption, so one large value made the fold unloadable. Both sides now share a 64 MiB cap (NATS's payload ceiling) and the writer refuses before writing. Failed multipart uploads are aborted so S3/GCS don't keep billed orphan parts. The Synadia stream-limit reply is recognized by err_code 10027 or case-insensitive text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152kQKDdP8XRhoeqisJYpWr
Merged
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.
Summary
u32::MAX; replay treatedvalue_len > 16 MiBas a CRC mismatch, so after one 17 MiB value everyapply/loadreturnedCorrupted(reproduced: the compaction triggered by the write itself fails). Writer and reader now shareMAX_VALUE_LEN = 64 MiB(NATS's payload ceiling); the writer refuses withInvalidFormatbefore writing anything. Regression test round-trips a value at the limit and checks a larger one leaves the fold loadable.put_multipartdroppedWriteMultipartwithoutabort(); S3/GCS keep those parts (billed, unlisted) until aborted. The upload now drains parts itself and aborts on any failure;finish()then only sends the completion, which object_store aborts on failure.err_code == 10027(JSMaximumStreamsLimitErr) or the text case-insensitively, instead of an exact substring. A false positive is harmless:StreamLimitre-checks the bucket.sync: truelike fjall and its own export;resume_window_okdocs nameresume_start_sequenceas the only source of the start sequence; import docs cover a failed open after the rename; ARCHITECTURE.md documents the value cap, the length-corruption limitation, and both new failure modes.Test plan
-D warnings, docs, full feature matrixlargest_value_round_trips_and_larger_is_refused_before_writingraw_create_stream_limit_by_code_or_reworded_text🤖 Generated with Claude Code
https://claude.ai/code/session_0152kQKDdP8XRhoeqisJYpWr