diff --git a/src/node_file.cc b/src/node_file.cc index c2cd5998e6f..e8b06a1c3fd 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -4616,8 +4616,8 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo& args) { std::error_code error_code; auto src_status = dereference - ? std::filesystem::symlink_status(src_path, error_code) - : std::filesystem::status(src_path, error_code); + ? std::filesystem::status(src_path, error_code) + : std::filesystem::symlink_status(src_path, error_code); if (error_code) { #ifdef _WIN32 @@ -4635,9 +4635,7 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo& args) { bool dest_exists = !error_code && dest_status.type() != std::filesystem::file_type::not_found; - bool src_is_dir = - (src_status.type() == std::filesystem::file_type::directory) || - (dereference && src_status.type() == std::filesystem::file_type::symlink); + bool src_is_dir = src_status.type() == std::filesystem::file_type::directory; auto src_path_str = ConvertPathToUTF8(src_path); auto dest_path_str = ConvertPathToUTF8(dest_path); diff --git a/test/parallel/test-fs-cp-dereference-symlink-to-file.mjs b/test/parallel/test-fs-cp-dereference-symlink-to-file.mjs new file mode 100644 index 00000000000..8c921630366 --- /dev/null +++ b/test/parallel/test-fs-cp-dereference-symlink-to-file.mjs @@ -0,0 +1,42 @@ +// This tests that cp() and cpSync() copy the target file of a symlink passed +// as src when dereference is true and recursive is not set. + +import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs'; +import { nextdir } from '../common/fs.js'; +import assert from 'node:assert'; +import { + cp, + cpSync, + lstatSync, + mkdirSync, + readFileSync, + symlinkSync, + writeFileSync, +} from 'node:fs'; +import { join } from 'node:path'; +import tmpdir from '../common/tmpdir.js'; + +tmpdir.refresh(); + +const src = nextdir(); +mkdirSync(src); +writeFileSync(join(src, 'foo.txt'), 'foo'); +symlinkSync(join(src, 'foo.txt'), join(src, 'link.txt')); + +const opts = mustNotMutateObjectDeep({ dereference: true }); + +{ + const dest = join(nextdir(), 'foo.txt'); + cpSync(join(src, 'link.txt'), dest, opts); + assert(lstatSync(dest).isFile()); + assert.strictEqual(readFileSync(dest, 'utf8'), 'foo'); +} + +{ + const dest = join(nextdir(), 'foo.txt'); + cp(join(src, 'link.txt'), dest, opts, mustCall((err) => { + assert.ifError(err); + assert(lstatSync(dest).isFile()); + assert.strictEqual(readFileSync(dest, 'utf8'), 'foo'); + })); +}