diff --git a/src/node_file.cc b/src/node_file.cc index f569eea1a7f9b8..7978737c7e1822 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -3193,7 +3193,8 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo& args) { std::string dest_path_str = dest_path.string(); // Check if dest_path is a subdirectory of src_path. - if (src_is_dir && dest_path_str.starts_with(src_path.string())) { + if (src_is_dir && + dest_path.parent_path().string().starts_with(src_path.string())) { std::string message = "Cannot copy " + src_path.string() + " to a subdirectory of self " + dest_path.string(); return THROW_ERR_FS_CP_EINVAL(env, message.c_str()); diff --git a/test/parallel/test-fs-cp.mjs b/test/parallel/test-fs-cp.mjs index 16a52bc12c49f1..3545ee4edfd35b 100644 --- a/test/parallel/test-fs-cp.mjs +++ b/test/parallel/test-fs-cp.mjs @@ -24,8 +24,8 @@ import tmpdir from '../common/tmpdir.js'; tmpdir.refresh(); let dirc = 0; -function nextdir() { - return tmpdir.resolve(`copy_${++dirc}`); +function nextdir(dirname) { + return tmpdir.resolve(dirname || `copy_${++dirc}`); } // Synchronous implementation of copy. @@ -312,6 +312,32 @@ function nextdir() { ); } +// It must not throw error if attempt is made to copy to dest +// directory with same prefix as src directory +// regression test for https://github.com/nodejs/node/issues/54285 +{ + const src = nextdir('prefix'); + const dest = nextdir('prefix-a'); + mkdirSync(src); + mkdirSync(dest); + cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true })); +} + +// It throws error if attempt is made to copy src to dest +// when src is parent directory of the parent of dest +{ + const src = nextdir('a'); + const destParent = nextdir('a/b'); + const dest = nextdir('a/b/c'); + mkdirSync(src); + mkdirSync(destParent); + mkdirSync(dest); + assert.throws( + () => cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true })), + { code: 'ERR_FS_CP_EINVAL' }, + ) +} + // It throws error if attempt is made to copy to subdirectory of self. { const src = './test/fixtures/copy/kitchen-sink';