fix: resolve symlinks in safeRemoveDirSync to fix cleanup with symlinked paths #13894
+132
−1
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.
When rendering a
.qmddocument withembed-resources: trueusing an absolute path through a symlinked directory, the render fails during cleanup with:Root Cause
The path mismatch occurs in this sequence:
/home/c/cr173/tmp/quarto-bug/test.qmdproject.dirkeeps the symlink path (Quarto'snormalizePath()does NOT resolve symlinks)rmarkdown:::abs_path(intermediates_dir)calls R'snormalizePath()which DOES resolve symlinks/home/vis/cr173/tmp/quarto-bug/test_filessafeRemoveDirSync()compares these paths as strings, which failsThe knitr symlink resolution happens in
src/resources/rmd/execute.R:The deeper issue is that
src/core/deno/monkey-patch.tsreplacesDeno.realPathSyncwithnormalizePath, which intentionally does NOT resolve symlinks. This was done in commit3bb0b45dc(Aug 2022) to work around a Windows UNC path bug whereDeno.realPathSyncreturned malformed paths likeUNC\x.org\...instead of\\x.org\....That UNC bug was fixed in Deno v1.16 (denoland/deno#12243). Quarto now uses Deno 2.3.1+, so the original workaround is no longer needed.
Fix
Rather than removing the monkey-patch globally (which would require auditing all code paths), this fix:
src/deno_ral/original-real-path.tsthat saves the originalDeno.realPathSyncbefore monkey-patchingsrc/quarto.tsBEFORE the monkey-patch importsafeRemoveDirSync()to resolve both paths using the originalrealPathSyncbefore comparisonThe separate module with no imports avoids circular dependencies:
This is a targeted fix that only affects the safety boundary check, with fallback to original paths if resolution fails.
Testing
tests/unit/ral/safe-remove-dir.test.tsfor symlink handlingtests/smoke/render/render-symlink-embed-resources.test.tsFollow-up Consideration
Since the UNC bug was fixed in Deno v1.16 (2021), and Quarto now uses Deno 2.3.1+, the monkey-patch may no longer be necessary at all. A follow-up issue could review whether the monkey-patch can be removed entirely, which would restore proper symlink resolution globally.
References:
Fixes #13890