Skip to content

fix: resolve absolute symlink targets correctly when packing#452

Merged
MarshallOfSound merged 1 commit into
mainfrom
fix/absolute-symlink-resolve-366
Jun 28, 2026
Merged

fix: resolve absolute symlink targets correctly when packing#452
MarshallOfSound merged 1 commit into
mainfrom
fix/absolute-symlink-resolve-366

Conversation

@claude

@claude claude Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Requested by Samuel Attard · Slack thread

Fixes #366

Before / After

Before: When a symlink's target was an absolute path, Filesystem.resolveLink used path.join(parentPath, symlink). path.join ignores the fact that symlink may itself be absolute and simply concatenates it onto parentPath, swallowing the leading separator. This had two bad consequences:

  • An absolute target pointing inside the package was packed as a broken relative link (e.g. subdir/package/inner/file.txt instead of inner/file.txt), so it dangled when the archive was extracted.
  • An absolute target pointing outside the package was silently mangled into an in-package-looking path, bypassing the existing "links out of the package" guard.

After: Absolute targets resolve to the path they actually point at. In-package absolute targets are stored as the correct in-package relative link, and out-of-package absolute targets resolve to a ../-prefixed path that the existing isAbsolute/.. guard rejects, exactly like a relative escape (e.g. ../../etc/passwd).

How

One-line change in src/filesystem.ts: path.join(parentPath, symlink)path.resolve(parentPath, symlink). path.resolve honors an absolute target as-is while treating a relative target identically to before, so absolute and relative targets now flow through a single, correct code path. Relative-target behavior is unchanged.

Tests

Added regression tests in test/filesystem-spec.ts (the existing insertLink symlink validation block):

  • An absolute symlink target pointing inside the package is stored as the correct in-package relative link.
  • An absolute symlink target pointing outside the package is rejected with the existing links out of the package error.

Both tests fail on main and pass with this change. The symlinks are constructed at runtime via insertLink arguments (no absolute-path-dependent fixtures committed).


Generated by Claude Code

Use path.resolve instead of path.join in Filesystem.resolveLink so that
an absolute symlink target is honored as an absolute path rather than
being concatenated onto the parent directory path.

Previously path.join swallowed the leading separator of an absolute
target, which:
  - turned an absolute in-package target into a broken relative link
    that dangles on extract, and
  - silently bypassed the out-of-package guard for absolute targets
    pointing outside the package.

path.resolve handles both absolute and relative targets through a single
code path; relative targets are unaffected.

Adds regression tests for an absolute in-package target (stored as the
correct relative link) and an absolute out-of-package target (rejected
with the existing 'links out of the package' error).

Fixes #366
@MarshallOfSound
MarshallOfSound marked this pull request as ready for review June 28, 2026 05:27
@MarshallOfSound
MarshallOfSound requested a review from a team as a code owner June 28, 2026 05:27
@MarshallOfSound
MarshallOfSound merged commit 0087cfa into main Jun 28, 2026
9 checks passed
@MarshallOfSound
MarshallOfSound deleted the fix/absolute-symlink-resolve-366 branch June 28, 2026 22:47
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.

Symlink with absolute path is packed incorrectly

3 participants