fix zip symlink extraction, clean up cfg-gated test imports#199
Merged
Conversation
jaemk
added a commit
that referenced
this pull request
Jul 19, 2026
…t escaping targets - a zip entry whose unix mode is `S_IFLNK` was extracted as a regular file containing the target path text, corrupting directory trees that rely on symlinks (e.g. a macOS .app's `Frameworks/*/Versions/Current`) and breaking the publisher's code signature. On unix such entries are now restored with `std::os::unix::fs::symlink`; on windows they still extract as regular files (creating symlinks requires privileges; documented). - symlink targets are validated: an absolute target or one whose lexical resolution escapes the extraction root is rejected, consistent with the existing `enclosed_name` zip-slip defense. As a backstop against symlinked-parent traversal (a link aliasing an ancestor, then entries descending through it), every file/symlink entry's physical parent must canonicalize to exactly `canonical_root/<lexical parent>` before anything is created. - `extract_file` rejects a symlink entry instead of writing the target text as the requested file. - gate the test-only `ReleaseAsset` import in update.rs behind `checksums` and the `Duration` import in s3.rs behind `s3-auth` so single-backend `clippy -D warnings` runs are clean.
jaemk
force-pushed
the
260719.zip-symlinks-clippy
branch
from
July 20, 2026 00:37
bf672b6 to
464f0ec
Compare
jaemk
added a commit
that referenced
this pull request
Jul 20, 2026
jaemk
added a commit
that referenced
this pull request
Jul 20, 2026
* docs: add bundle-install design spec for directory-bundle (.app) installs Design doc for #145 phase A (maintainer sign-off before implementation): `bundle_root_in_archive`/`bundle_install_path` builder API, whole-tree stash-and-rollback swap with `MoveAll` semantics, same-filesystem staging, preflight interaction, non-goals (.deb/.msi recipe-only, no signing/notarizing, no escalation), test strategy, and the open API questions. Also records that zip symlink entries are currently extracted as regular files (a standalone bug for .app framework symlinks; see BNDL-4-2). * docs: note the zip-symlink fix landed in #199
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.
S_IFLNKunix mode) as real symlinks inExtract::extract_intoon unix. Previously the entry's target path text was written as a regular file, corrupting directory trees that rely on symlinks (e.g. a macOS.app'sFrameworks/*/Versions/Current) and breaking the publisher's code signature. On windows symlink entries still extract as regular files (creating symlinks requires privileges; documented). Tar extraction was already correct.enclosed_namezip-slip defense. As a backstop against symlinked-parent traversal (a link aliasing an ancestor, then later entries descending through it), every file/symlink entry's physical parent must canonicalize to exactlycanonical_root/<lexical parent>before anything is created.Extract::extract_fileinstead of writing the target text as the requested file.ReleaseAssetimport in update.rs behindchecksumsand theDurationimport in s3.rs behinds3-auth, so single-backendclippy -D warningsruns (--features s3,--features github, bare) are clean.Tests: 14 zip-extraction tests (unix-gated) covering symlink restore, chains, implicit parents, absolute/escaping/deep-traversal rejection, symlinked destination dirs, dir-through-symlink containment, and regressions for mode preservation and zip-slip. Spec updated in
specs/ref-update-pipeline.md.