What happens
Adding a file to a zip through MacPacker stores its contents and POSIX permissions, but not its extended attributes or resource fork. SevenZipWriter builds each entry from archivePath, diskPath/data, modificationDate and posixPermissions — there is nothing carrying the rest.
So a file with Finder tags, a Finder comment, or a resource fork goes into the archive stripped, and comes back out of any extractor without them. Nothing warns about it.
Why it matters now
#189 made extraction careful about exactly this metadata: an AppleDouble sidecar is folded into the file it describes, quarantine is never the archive's to change, and attributes the sidecar does not speak for survive. The read path treats extended attributes as part of the file. The write path does not, so a round-trip through MacPacker still loses them:
file with xattrs -> add to archive -> extract -> file without xattrs
Every other Mac archiver behaves the same way except ditto, so this is not unusual — but it is worth deciding rather than inheriting. Measured while building the corpus in MacPacker-TestArchives archivers/: of Finder's "Compress", ditto in both arrangements, Info-ZIP, Keka and 7-Zip, only ditto preserves metadata at all.
What a fix looks like
macOS's convention is a sibling ._name entry in AppleDouble format, which is what ditto --sequesterRsrc writes into __MACOSX/ and what ditto alone writes inline. copyfile(3) with COPYFILE_PACK produces those bytes from a file in one call — the same call the extraction path already uses in reverse with COPYFILE_UNPACK — so no encoder is needed.
Open questions worth settling before building it:
- Inline or
__MACOSX/? Inline is what the extraction path handles most directly; __MACOSX/ is what Finder produces and keeps the sidecars out of a bundle.
- Always, or only when a file actually has attributes worth storing? Emitting a sidecar per file would roughly double the entry count of most archives.
- Should it be optional? Keka exposes "Exclude Mac resource forks" as a checkbox, though in testing it dropped attributes either way.
Not a regression
This behaviour predates #189 and that PR does not change it. Filed because the read path now takes this metadata seriously and the write path is the remaining half.
What happens
Adding a file to a zip through MacPacker stores its contents and POSIX permissions, but not its extended attributes or resource fork.
SevenZipWriterbuilds each entry fromarchivePath,diskPath/data,modificationDateandposixPermissions— there is nothing carrying the rest.So a file with Finder tags, a Finder comment, or a resource fork goes into the archive stripped, and comes back out of any extractor without them. Nothing warns about it.
Why it matters now
#189 made extraction careful about exactly this metadata: an AppleDouble sidecar is folded into the file it describes, quarantine is never the archive's to change, and attributes the sidecar does not speak for survive. The read path treats extended attributes as part of the file. The write path does not, so a round-trip through MacPacker still loses them:
Every other Mac archiver behaves the same way except
ditto, so this is not unusual — but it is worth deciding rather than inheriting. Measured while building the corpus in MacPacker-TestArchivesarchivers/: of Finder's "Compress",dittoin both arrangements, Info-ZIP, Keka and 7-Zip, onlydittopreserves metadata at all.What a fix looks like
macOS's convention is a sibling
._nameentry in AppleDouble format, which is whatditto --sequesterRsrcwrites into__MACOSX/and whatdittoalone writes inline.copyfile(3)withCOPYFILE_PACKproduces those bytes from a file in one call — the same call the extraction path already uses in reverse withCOPYFILE_UNPACK— so no encoder is needed.Open questions worth settling before building it:
__MACOSX/? Inline is what the extraction path handles most directly;__MACOSX/is what Finder produces and keeps the sidecars out of a bundle.Not a regression
This behaviour predates #189 and that PR does not change it. Filed because the read path now takes this metadata seriously and the write path is the remaining half.