Skip to content

fix(cli/mem): bound mem patch input at 4 MiB and error instead of truncating - #6475

Open
sanjay3290 wants to merge 2 commits into
block:mainfrom
sanjay3290:fix/mem-patch-input-limit
Open

fix(cli/mem): bound mem patch input at 4 MiB and error instead of truncating#6475
sanjay3290 wants to merge 2 commits into
block:mainfrom
sanjay3290:fix/mem-patch-input-limit

Conversation

@sanjay3290

Copy link
Copy Markdown

Fixes #6262.

mem patch read its diff with read_to_string on stdin and fs::read_to_string on
--patch-file, with no bound. A patch larger than the NIP-44 value cap was accepted,
silently cut down, and then reported back as a hunk-syntax error — so the user saw a
parse failure for a patch that was in fact well-formed, and had no signal that anything
had been dropped.

This bounds patch input at 4 MiB and errors instead of truncating.

  • read_patch_input(reader, limit) reads limit + 1 bytes via Read::take and returns
    a CliError::Usage naming the limit if the input exceeds it. Reading one byte past the
    limit is what distinguishes "exactly at the limit" from "over it" without buffering the
    whole oversized input.
  • read_patch_source(patch_path, limit) holds both input branches, so stdin and
    --patch-file are bounded by construction and cmd_patch has a single call site.
    The existing empty-stdin rejection is preserved; an empty --patch-file still
    propagates to the caller as before.
  • The error message points at the recovery path: split the change into sequential
    patches, chaining --base-hash through each result.

No change to the existing result-size check after the patch is applied.

Six tests: exact limit accepted, over limit rejected with the limit in the message, a
diff larger than the NIP-44 cap but under 4 MiB still accepted, no truncation at any size,
and two --patch-file call-site tests through a tempfile.

Verified locally at cafb88e6c on a clean tree:

  • ./scripts/run-tests.sh unit — exit 0
  • cargo clippy --workspace --all-targets -- -D warnings — exit 0
  • cargo fmt --all -- --check — exit 0

Deletion probes, both compiling and both failing:

  • reverting the --patch-file branch to fs::read_to_string fails
    read_patch_source_file_over_limit_err
  • loosening the bound to buf.len() > limit + 1 fails read_patch_input_never_truncates,
    read_patch_input_over_limit_err_contains_limit and read_patch_source_file_over_limit_err

Signed-off-by: Sanjay Ramadugu <sramadugu1@gmail.com>
Signed-off-by: Sanjay Ramadugu <sramadugu1@gmail.com>
@sanjay3290
sanjay3290 requested a review from a team as a code owner August 21, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

buzz mem patch: stdin/patch input silently truncated at 65,535 bytes — surfaces as bogus 'hunk header does not match hunk'

1 participant