Skip to content

core: SanitizedMode newtype and non_exhaustive on growth-prone enums - #554

Merged
bug-ops merged 1 commit into
mainfrom
feat/549-core-mode-newtype-nonexhaustive
Aug 18, 2026
Merged

core: SanitizedMode newtype and non_exhaustive on growth-prone enums#554
bug-ops merged 1 commit into
mainfrom
feat/549-core-mode-newtype-nonexhaustive

Conversation

@bug-ops

@bug-ops bug-ops commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Introduce a SanitizedMode newtype wrapping sanitized permission modes, sealed so it can only be constructed by sanitize_permissions. Threaded through ValidatedEntry, create_file_with_mode, and extract_file_with_permit, replacing an Option<u32> whose "must be sanitized" invariant was previously enforced only by a doc comment.
  • Mark ArchiveError, QuotaResource, formats::detect::ArchiveType, formats::compression::CompressionCodec, inspection::report::IssueCategory, and types::entry_type::EntryType as #[non_exhaustive] so adding a variant to any of them is no longer a semver break for downstream exhaustive matches, consistent with the existing ValidatedEntryType precedent. creation::walker::EntryType was intentionally left unmarked — it is pub(crate)-only and never nameable outside this crate.
  • Added wildcard arms to exhaustive matches on the now-non-exhaustive enums in exarch-cli, exarch-python, and exarch-node.
  • Added a trybuild fixture proving SanitizedMode cannot be forged from outside sanitize_permissions, mirroring the existing QuotaPermit fixture.

Test plan

  • cargo +nightly fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo nextest run --workspace --all-features --exclude exarch-python --exclude exarch-node (1229/1229 pass)
  • cargo test --doc --workspace --all-features --exclude exarch-python --exclude exarch-node and cargo test --doc -p exarch-core without --all-features (119/119 pass both ways)
  • RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features --workspace
  • cargo audit / cargo deny check --all-features clean, no new unsafe
  • Live-extracted forged-header TAR and ZIP archives to confirm setuid/setgid/world-writable stripping is unchanged (4755->0755, 2755->0755, 6755->0755, 7777->1775, 1755->1755, 0777->0775 across both formats)

Closes #549
Closes #551

@github-actions github-actions Bot added core Changes to exarch-core docs Documentation python Python bindings node Node.js bindings tests Test changes labels Aug 18, 2026
@bug-ops
bug-ops enabled auto-merge (squash) August 18, 2026 18:30
…_exhaustive

Wrap sanitized permission modes in a SanitizedMode newtype so a caller
can no longer pass an unsanitized u32 into create_file_with_mode or
extract_file_with_permit; the invariant was previously enforced only
by a doc-comment contract. SanitizedMode can only be constructed by
sanitize_permissions, matching the SafePath/QuotaPermit sealed-type
pattern already used in this crate.

Mark ArchiveError, QuotaResource, ArchiveType, CompressionCodec,
IssueCategory, and types::entry_type::EntryType as #[non_exhaustive]
so adding a variant to any of them is no longer a semver break for
downstream exhaustive matches, consistent with ValidatedEntryType.

Closes #549
Closes #551
@bug-ops
bug-ops force-pushed the feat/549-core-mode-newtype-nonexhaustive branch from 20299e7 to 53fc488 Compare August 18, 2026 18:34
@bug-ops
bug-ops merged commit 878e093 into main Aug 18, 2026
26 checks passed
@bug-ops
bug-ops deleted the feat/549-core-mode-newtype-nonexhaustive branch August 18, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Changes to exarch-core docs Documentation node Node.js bindings python Python bindings tests Test changes

Projects

None yet

1 participant