Skip to content

fs: resolve symlinks before parent components - #65457

Open
jazelly wants to merge 1 commit into
nodejs:mainfrom
jazelly:fix-60295
Open

jazelly wants to merge 1 commit into
nodejs:mainfrom
jazelly:fix-60295

Conversation

@jazelly

@jazelly jazelly commented Aug 21, 2026 •

Copy link
Copy Markdown
Member

fs.realpath() and fs.realpathSync() resolved symlink targets with
path.resolve(), which collapses .. before the preceding symlink is
resolved. A link like d -> c/../d was turned back into d, causing
an infinite loop.

Fixed this by resolving .. against the already resolved parent instead.

This matches how native implements realpath:
.. is applied to the already-resolved prefix, and symlink targets are
spliced into the remaining path without lexical normalization.

Fixes: #60295
Signed-off-by: jazelly xzha4350@gmail.com

@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to file-system APIs and the fs module. needs-ci PRs that need a full CI run. labels Aug 21, 2026
The JavaScript implementation of `fs.realpath()` and
`fs.realpathSync()` joined a symlink target with the rest of the path
through `path.resolve()`, which collapses `..` lexically before the
preceding components have been resolved. A link such as
`d -> c/../d`, where `c` is itself a symlink, was therefore rewritten
back to `d` and the walk never terminated.

Keep `.` and `..` in the path while walking it, and apply `..` to the
already resolved parent, matching `realpath(3)` and
`fs.realpathSync.native()`. Only normalize the final result, and skip
caching link targets containing `..`, whose resolution depends on the
path walked before them.

Fixes: nodejs#60295
Signed-off-by: jazelly <xzha4350@gmail.com>
@jazelly
jazelly marked this pull request as ready for review October 4, 2026 21:06
@jazelly

jazelly commented Oct 4, 2026

Copy link
Copy Markdown
Member Author

cc @nodejs/fs

@codecov

codecov Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.22222% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.43%. Comparing base (54b4e37) to head (9d00621).
⚠️ Report is 864 commits behind head on main.

Files with missing lines Patch % Lines
lib/fs.js 92.22% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65457      +/-   ##
==========================================
+ Coverage   90.13%   90.43%   +0.30%     
==========================================
  Files         751      790      +39     
  Lines      253635   275506   +21871     
  Branches    47786    52852    +5066     
==========================================
+ Hits       228615   249162   +20547     
- Misses      16268    16742     +474     
- Partials     8752     9602     +850     
Files with missing lines Coverage Δ
lib/fs.js 97.11% <92.22%> (-1.32%) ⬇️

... and 368 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jazelly jazelly added the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fs Issues and PRs related to file-system APIs and the fs module. needs-ci PRs that need a full CI run. request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fs.realpath infinite loop

2 participants