Guard filesystem reads against unresolved symlinks - #97902
Conversation
Failing test suitesCommit: 43d169f | About building and testing Next.js
Expand output● twoslash › should annotate twoslash types default ● twoslash › should annotate twoslash types esnext
Expand output● output: standalone with twoslash › should annotate twoslash types default ● output: standalone with twoslash › should annotate twoslash types esnext
Expand output● build trace with extra entries › production mode › should build and trace correctly
Expand output● output: standalone with twoslash › should annotate twoslash types default ● output: standalone with twoslash › should annotate twoslash types esnext
Expand output● twoslash › should annotate twoslash types default ● twoslash › should annotate twoslash types esnext |
Stats from current PR🔴 2 regressions
📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
Build Cache
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📎 Tarball URLCommit: 43d169f |
|
There is a merge conflict already |
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
0c5e423 to
efc933c
Compare
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
What?
Adds debug-only OS realpath validation to successful
DiskFileSystemfile and directory reads. When a successfully canonicalized path differs from the supplied path, the read returns a normal task error that names both paths.Fixes pattern and glob traversal so physical directory enumeration uses resolved paths while returned matches keep their logical, symlink-relative spelling.
Why?
Reading a directory through an unresolved symlink parent gives the same filesystem object multiple path identities. That can make Turbo Tasks dependency tracking and invalidation inconsistent. These paths are expected to be resolved before successful reads, matching the resolve-parent-first behavior used by node-file-trace.
The checks return errors rather than asserting because paths can disagree temporarily under eventual consistency. Propagating a task error avoids panicking a worker thread while still exposing invalid callers during development.
How?
The validation lives directly in
DiskFileSystem::readandDiskFileSystem::raw_read_dir. It calls the OS canonicalization API inline instead of the Turbo Tasks realpath task, keeping the diagnostic out of the task dependency graph. The guard runs only after the OS read succeeds: missing paths, non-directories, and invalid filenames preserve their existingNotFoundbehavior, including deliberate directory probes on symlinks to files.read_matchesresolves each physical directory immediately before enumeration in both its finite-constant fast path and recursive slow path. It still constructsPatternMatchvalues from the original logical lookup path, preserving request keys, trace output, and leaf-level symlink affecting sources. Resolving the enumeration path also tracks the parent symlink chain so replacing a link invalidates the walk.read_globsimilarly enumerates the already-resolved directory target while rebuilding returned entries relative to the original glob root. This keeps direct, chained, and unresolvable symlink entries consistently logical.Verification
cargo fmt -p turbo-tasks-fs -p turbopack-core -- --checkcargo clippy -p turbo-tasks-fs -p turbopack-core --all-targetscargo test -p turbo-tasks-fs(127 passed)cargo test -p turbopack-core(155 passed)release-with-assertions(9 passed): esbuild, ffmpeg installer, loopback/socket.io, four sharp variants, and asset symlinkcargo check -p turbo-tasks-fs --releasepnpm build-allbench/heavy-npm-depsTurbopack development smoke test (HTTP 200)Notes
The disk guard is cross-platform, while its symlink-parent regression test is Unix-only, matching neighbouring symlink tests. On Windows, OS canonicalization can also normalize casing and 8.3 short names; a debug read using a non-canonical spelling will therefore return the same diagnostic error.