Skip to content

fix(cli): refuse a source whose name the trash cannot hold - #232

Merged
FeathBow merged 3 commits into
mainfrom
fix/refuse-a-name-too-long-for-the-trash
Oct 26, 2026
Merged

FeathBow merged 3 commits into
mainfrom
fix/refuse-a-name-too-long-for-the-trash

Conversation

@FeathBow

@FeathBow FeathBow commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

A reservation names a trash entry by its sequence, zero-padded to four digits, a dash, and the source's own name. A source whose name leaves no room for those five characters cannot be reserved: the reservation's first lookup of the name fails with ENAMETOOLONG. That was where it failed, after its tree had been assessed and the trash root, its claims directory and, across devices, the root's registration had been prepared. The preview admitted it, and an explicit --path batch, which is meant to reject before any mutation, let the items before it stage first. Review of #224 found the preview's half of this with a 251-byte name.

The staging feasibility probe, which the preview and production share, now asks the source parent whether the trash could hold the name a reservation would give the source. The trash is on the source's mount, so the parent's filesystem answers by its own measure, through the same no-follow lookup the reservation makes. On APFS that measure is not a byte count: 250 three-byte characters fit and 251 do not. A name that does not fit is blocked in the preview's staging_preflight as trash_name_too_long, category resource_limit, and production refuses it at preflight, before the trash is touched, whether alone or in a batch. A source on a backend degu does not certify is still reported for that first. The reservation now builds its names with the two functions the probe uses.

Production asks of the sequence the reservation will take. That is the trash's next sequence, past every entry and then past each claim already taken, as the reservation counts them, and in an explicit batch, one further for each item ahead of it in the same trash. An item ahead that fails leaves a later one a smaller sequence, never a larger, so a batch this check passes holds every name it reserves. The first commit asked production of the first sequence as well, and review found what that let through: over a trash at 9998, a batch staged a short name at 9999 and then failed a 250-byte one at its reservation, at 10000, with the batch half done. The second commit counts the sequence.

The preview reads no trash and still asks of the first sequence, so it, and the review that shares it, admit a name that fits behind four digits but not behind a next sequence past 9999; staging then refuses that name at preflight. docs/usage.md names the new status.

Validation

cargo fmt --all --check, cargo clippy --workspace --all-targets --locked -- -D warnings, RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --locked and cargo test --workspace --locked are clean, the suite at 1820 passed / 0 failed / 1 ignored.

  • trash_name_limit (CLI): a relocated pip cache named with 251 bytes is blocked as trash_name_too_long, and a full clean and a --path clean each fail it with that reason and leave no trash directory. Named with 250 bytes, it is assessed and staged as 0001- and its name.
  • apfs_measures_names (macOS): the probe passes a name of 250 three-byte characters and refuses one of 251.
  • planned_sequences: a trash not made yet starts at 1. Past entries at 5 and 9998 the next sequence is 9999 and the one after it 10000; with 9999 and 10001 claimed, they are 10000 and 10002.
  • batch_sequence_limit (CLI): review's case. Over a trash holding 9998, a --path batch of a short name ahead of a 250-byte one is refused before either is staged, the short one not_attempted. A clean of every finding then stages the short one at 9999 and refuses the 250-byte one at its own preflight for being too long for the trash, not at its reservation.

Nine mutations, each caught. Dropping the check fails the preview assertion; with the preview assertions removed it fails on the reason, and with the reason removed as well, on the trash directory the old path prepared. Probing with a five-digit sequence fails the 250-byte half. Counting bytes in place of asking the filesystem fails apfs_measures_names while trash_name_limit passes. Asking production of the first sequence again, as the first commit did, fails batch_sequence_limit, and so does counting no items ahead in a batch, or asking a lone item of the first sequence. Not passing claims fails planned_sequences, and starting every trash at the first sequence fails both.

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1c03ea90-fd47-4952-83ee-d85a38de70f4
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@FeathBow
FeathBow merged commit 0310e9c into main Oct 26, 2026
1 check passed
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.

1 participant