fs: fix cpSync directory iterator exception#62519
fs: fix cpSync directory iterator exception#62519gushiaoke wants to merge 2 commits intonodejs:mainfrom
Conversation
Replace std::filesystem::directory_iterator with libuv's uv_fs_scandir to avoid process abort when copying directories with non-ASCII paths. Previously, std::filesystem::directory_iterator could throw uncatchable exceptions when encountering encoding issues (e.g., GBK-encoded Chinese paths on Windows). In environments with buggy libc++ implementations (especially Electron), this triggers __libcpp_verbose_abort(), causing immediate process termination that cannot be caught by JavaScript try-catch blocks. This patch uses libuv's uv_fs_scandir and uv_fs_scandir_next instead, which properly handle path encoding and return errors that can be converted to JavaScript exceptions. This approach is consistent with other fs operations in Node.js (e.g., fs.readdirSync) and ensures: 1. No process abort on encoding errors 2. Errors are catchable by JavaScript 3. fs.cpSync() can successfully copy directories with non-ASCII paths 4. Consistent behavior across different C++ standard library implementations The fix also adds proper cleanup of uv_fs_t requests on all error paths to prevent resource leaks.
Add test to ensure fs.cpSync properly handles directory iteration errors without causing process abort.
bb4fdc4 to
b2309bc
Compare
π Updated the fixI've improved this PR based on a key insight: just catching the exception doesn't solve the problem - the operation still fails and users can't copy their files. What changed:Before (v1): Only added error handling for
Now (v2): Use libuv's
Why libuv?Node.js already uses libuv for
This is a more complete fix that solves both the crash and the functionality issue. |
|
Closing this PR. After further analysis, the core issue (CJK path encoding) was already fixed by #61950, and the remaining edge cases (permissions, symlinks, path length) don't warrant replacing std::filesystem with libuv for directory iteration. |
Fix: fs.cpSync() fails with non-ASCII paths (process abort or operation failure)
π Problem
fs.cpSync()can cause process abort (not catchable by try-catch) when copying directories with certain non-ASCII characters in paths, especially on Windows with GBK encoding.Root Cause
In
src/node_file.ccline 3741,std::filesystem::directory_iteratoris constructed without proper error handling for encoding issues:When the iterator construction fails due to encoding issues (e.g., libc++ bugs handling GBK-encoded paths), it throws
std::filesystem::filesystem_error. In some environments (especially Electron with bundled libc++), this uncaught exception triggers__libcpp_verbose_abort(), causing immediate process termination.Even if the exception is caught, the operation still fails - users cannot copy their files.
Impact
try-catchblocks cannot catch this error (process abort)Real-World Example
β Solution
Replace
std::filesystem::directory_iteratorwith libuv'suv_fs_scandiranduv_fs_scandir_next, which:fs.readdirSync)Before (Broken)
After (Fixed)
π Changes
src/node_file.cc: Replace
std::filesystem::directory_iteratorwithuv_fs_scandiruv_fs_lstatto get entry type instead ofdir_entry.is_*()uv_fs_trequests on all error pathsenv->ThrowUVExceptiontest/parallel/test-fs-cpsync-error-handling.js: Add test cases for error handling
π§ͺ Testing
π Related Issues
fs.readdirSyncalready usesuv_fs_scandirand works correctlyπ― Why libuv instead of just fixing the exception?
Option 1 (Previous approach): Just catch the exception
std::filesystemimplementationOption 2 (This PR): Use libuv like other fs operations
π Checklist
π Diff Summary