fs.cpSync fails when copying to a directory with a name starting with the source directory name
Version
v22.6.0
Platform
Darwin ikemoto-macmini.local 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:21 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8103 arm64
Subsystem
fs module
What steps will reproduce the bug?
fs = require("fs");
fs.cpSync("./foo", "./foobar", { recursive: true });
How often does it reproduce? Is there a required condition?
This bug reproduces consistently in Node.js v22.6.0. It works correctly in v22.5.1.
What is the expected behavior? Why is that the expected behavior?
The expected behavior, as seen in v22.5.1, is that the ./foo
directory should be copied to ./foobar
. This is the normal operation of the fs.cpSync
function and aligns with the documented behavior.
What do you see instead?
In v22.6.0, the following error is thrown:
node:internal/fs/cp/cp-sync:56
fsBinding.cpSyncCheckPaths(src, dest, opts.dereference, opts.recursive);
^
Error: Cannot copy ./foo to a subdirectory of self ./foobar
at cpSyncFn (node:internal/fs/cp/cp-sync:56:13)
at Object.cpSync (node:fs:3044:3)
at Object.<anonymous> (/Users/ikemo/tmp/main.js:2:4)
at Module._compile (node:internal/modules/cjs/loader:1546:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
at Module.load (node:internal/modules/cjs/loader:1317:32)
at Module._load (node:internal/modules/cjs/loader:1127:12)
at TracingChannel.traceSync (node:diagnostics_channel:315:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:166:5) {
code: 'ERR_FS_CP_EINVAL'
}
Additional information
The issue is caused by the misuse of the starts_with
function in a newly added check. This check incorrectly prevents copying to directories whose names start with the source directory name. For details, see:
https://github.com/nodejs/node/pull/53614/files#diff-70e3325bd2115867617ae2a16321c5de53c070ff2841976fe5b849675a5111e6R3186-R3190