feat(apple-fs): implement AppleDouble + resource-fork support#3556
Merged
Conversation
Expand the apple-fs crate with three new pieces of standalone surface that close the audit follow-ups in docs/audits/apple-fs-roundtrip.md: - apple_double: a self-contained AppleDouble v2 (RFC 1740) container parser and encoder. Pure-data, no FFI. Validates magic, version, descriptor table, and per-entry offset/length bounds. Encoder writes entries in ascending id order so identical logical content yields identical bytes. - resource_fork: safe accessors for com.apple.ResourceFork and com.apple.FinderInfo. On macOS they delegate to the third-party xattr crate (the same safe wrapper used by crates/metadata); on every other target the readers return Ok(None) and writers return Ok(()) so cross-platform callers do not abort on absent forks. - AppleDouble companion-name helpers: is_apple_double_name and apple_double_companion translate between foo and ._foo lexically, cross-platform. The crate keeps its #![deny(unsafe_code)] declaration. macOS xattr syscalls (getxattr(2), setxattr(2), removexattr(2)) are reached through xattr 1.6, which contains the only unsafe code involved. This honours the workspace unsafe-code policy that forbids #[allow(unsafe_code)] in apple-fs and routes platform FFI through pre-vetted wrapper crates. Tests: - Cross-platform unit tests for the parser/encoder, name detection, and stub behaviour. - A macOS-gated integration test in tests/apple_double_round_trip.rs that writes the synthesised payloads back as native xattrs and reads them through the safe accessors. Closes audit follow-up F-3. The resource-fork pipeline that runs during real transfers continues to flow through metadata::xattr -> protocol::xattr::wire as before; this PR adds standalone primitives for inspection tools, audit harnesses, and any future opt-in AppleDouble merge feature (audit follow-up F-2). Integration of the new accessors into the transfer pipeline is intentionally out of scope and tracked separately. References: - RFC 1740 section 5 (AppleDouble v2 container format). - Apple TN1188 (AppleSingle/AppleDouble Formats). - Upstream rsync 3.4.1 xattrs.c (rsync_xal_get / rsync_xal_set): the canonical com.apple.* names cross the wire through the same generic xattr path with no Mac-specific code.
PR #3556 added `xattr` and `tempfile` to crates/apple-fs/Cargo.toml but did not update Cargo.lock. Both dependency entries already existed in the lockfile via other crates (xattr 1.6.1 used by metadata; tempfile 3.27.0 widely used), so this only adds the apple-fs -> {xattr,tempfile} edges to the dependency graph. Fixes the `--locked` failure in `fmt + clippy` and `MSRV 1.88` jobs.
oferchen
added a commit
that referenced
this pull request
May 5, 2026
* feat(apple-fs): implement AppleDouble + resource-fork support Expand the apple-fs crate with three new pieces of standalone surface that close the audit follow-ups in docs/audits/apple-fs-roundtrip.md: - apple_double: a self-contained AppleDouble v2 (RFC 1740) container parser and encoder. Pure-data, no FFI. Validates magic, version, descriptor table, and per-entry offset/length bounds. Encoder writes entries in ascending id order so identical logical content yields identical bytes. - resource_fork: safe accessors for com.apple.ResourceFork and com.apple.FinderInfo. On macOS they delegate to the third-party xattr crate (the same safe wrapper used by crates/metadata); on every other target the readers return Ok(None) and writers return Ok(()) so cross-platform callers do not abort on absent forks. - AppleDouble companion-name helpers: is_apple_double_name and apple_double_companion translate between foo and ._foo lexically, cross-platform. The crate keeps its #![deny(unsafe_code)] declaration. macOS xattr syscalls (getxattr(2), setxattr(2), removexattr(2)) are reached through xattr 1.6, which contains the only unsafe code involved. This honours the workspace unsafe-code policy that forbids #[allow(unsafe_code)] in apple-fs and routes platform FFI through pre-vetted wrapper crates. Tests: - Cross-platform unit tests for the parser/encoder, name detection, and stub behaviour. - A macOS-gated integration test in tests/apple_double_round_trip.rs that writes the synthesised payloads back as native xattrs and reads them through the safe accessors. Closes audit follow-up F-3. The resource-fork pipeline that runs during real transfers continues to flow through metadata::xattr -> protocol::xattr::wire as before; this PR adds standalone primitives for inspection tools, audit harnesses, and any future opt-in AppleDouble merge feature (audit follow-up F-2). Integration of the new accessors into the transfer pipeline is intentionally out of scope and tracked separately. References: - RFC 1740 section 5 (AppleDouble v2 container format). - Apple TN1188 (AppleSingle/AppleDouble Formats). - Upstream rsync 3.4.1 xattrs.c (rsync_xal_get / rsync_xal_set): the canonical com.apple.* names cross the wire through the same generic xattr path with no Mac-specific code. * chore(deps): regenerate Cargo.lock for apple-fs xattr/tempfile deps PR #3556 added `xattr` and `tempfile` to crates/apple-fs/Cargo.toml but did not update Cargo.lock. Both dependency entries already existed in the lockfile via other crates (xattr 1.6.1 used by metadata; tempfile 3.27.0 widely used), so this only adds the apple-fs -> {xattr,tempfile} edges to the dependency graph. Fixes the `--locked` failure in `fmt + clippy` and `MSRV 1.88` jobs.
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
Expand the
apple-fscrate with three new pieces of standalone surfacethat close the audit follow-ups in
docs/audits/apple-fs-roundtrip.md:apple_doublemodule: a self-contained AppleDouble v2 (RFC 1740)container parser and encoder. Pure-data, no FFI. Validates magic,
version, descriptor table, and per-entry offset/length bounds. The
encoder writes entries in ascending id order so identical logical
content yields identical bytes.
resource_forkmodule: safe accessors forcom.apple.ResourceForkand
com.apple.FinderInfo. On macOS they delegate to the third-partyxattrcrate (the same safe wrapper used bycrates/metadata); onevery other target the readers return
Ok(None)and writers returnOk(()).is_apple_double_nameandapple_double_companiontranslate betweenfooand._foolexically, cross-platform.
Public API surface added
Design choice: xattr-backed accessors, not sidecar synthesis
Upstream rsync 3.4.1 has no dedicated resource-fork pathway. macOS
exposes the resource fork and the 32-byte Finder info as ordinary
extended attributes named
com.apple.ResourceForkandcom.apple.FinderInfo; upstream reads and writes them via standardgetxattr(2)/setxattr(2)(xattrs.c->rsync_xal_get/rsync_xal_set). This PR mirrors that approach for the in-processaccessors and keeps the AppleDouble container format as a standalone
helper for tools, audits, and any future opt-in merge feature.
Rationale: the existing transfer pipeline already round-trips
com.apple.*xattrs symmetrically viametadata::xattrandprotocol::xattr::wire(seedocs/audits/apple-fs-roundtrip.md,"Round-trip path" section). Adding a parallel sidecar path inside
apple-fswould either duplicate that work or change wire behaviour,neither of which is upstream-compatible. The accessors here are
therefore orthogonal to the live pipeline and intended for tooling.
Unsafe-code encapsulation
The crate keeps
#![deny(unsafe_code)]. macOS xattr syscalls reachthe kernel through
xattr1.6, which contains the onlyunsafeinvolved. No
#[allow(unsafe_code)]was added toapple-fs, in linewith the workspace unsafe-code policy that routes platform FFI through
pre-vetted wrapper crates or the
fast_iocrate.Test plan
(round-trip, magic / version / descriptor / payload-bound
validation, per-entry replacement, ordering).
is_apple_double_nameandapple_double_companion(round-trip pairing, root andbare-prefix edge cases).
(readers return
Ok(None), writers / removers are no-ops).(
tests/apple_double_round_trip.rs::macos_resource_fork_pipeline_matches_apple_double_payload)that writes payloads through
write_resource_fork/write_finder_info, reads them back, and verifies theAppleDouble container encodes / decodes the same bytes.
Finder info via the safe accessors, plus rejection of malformed
Finder-info length.
cargo fmt --allclean.Linux musl) - relies on CI; not run locally per workspace policy.
Follow-ups (not in this PR)
--apple-double-mergeanalogue once or if upstream picks up therelevant patch. The standalone container helpers added here are the
building block such a feature would need.
README.md:223line thatstill mentions "clonefile, FSEvents" for
apple-fs(out of scopefor this functional PR).