diff --git a/src/node_file.cc b/src/node_file.cc index d7926d9a07a3a6..0fe01e8b08127c 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -3425,15 +3425,18 @@ static void CpSyncOverrideFile(const FunctionCallbackInfo& args) { THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView()); + auto src_path = src.ToPath(); + auto dest_path = dest.ToPath(); + std::error_code error; - if (!std::filesystem::remove(*dest, error)) { + if (!std::filesystem::remove(dest_path, error)) { return env->ThrowStdErrException(error, "unlink", *dest); } if (mode == 0) { // if no mode is specified use the faster std::filesystem API - if (!std::filesystem::copy_file(*src, *dest, error)) { + if (!std::filesystem::copy_file(src_path, dest_path, error)) { return env->ThrowStdErrException(error, "cp", *dest); } } else { @@ -3446,7 +3449,7 @@ static void CpSyncOverrideFile(const FunctionCallbackInfo& args) { } if (preserve_timestamps) { - CopyUtimes(*src, *dest, env); + CopyUtimes(src_path, dest_path, env); } } @@ -3489,8 +3492,11 @@ static void CpSyncCopyDir(const FunctionCallbackInfo& args) { bool verbatim_symlinks = args[5]->IsTrue(); bool preserve_timestamps = args[6]->IsTrue(); + auto src_path = src.ToPath(); + auto dest_path = dest.ToPath(); + std::error_code error; - std::filesystem::create_directories(*dest, error); + std::filesystem::create_directories(dest_path, error); if (error) { return env->ThrowStdErrException(error, "cp", *dest); } @@ -3632,7 +3638,7 @@ static void CpSyncCopyDir(const FunctionCallbackInfo& args) { return true; }; - copy_dir_contents(std::filesystem::path(*src), std::filesystem::path(*dest)); + copy_dir_contents(src_path, dest_path); } BindingData::FilePathIsFileReturnType BindingData::FilePathIsFile( diff --git a/test/parallel/test-fs-cp-sync-unicode-dest.mjs b/test/parallel/test-fs-cp-sync-unicode-dest.mjs new file mode 100644 index 00000000000000..0638b98180c5da --- /dev/null +++ b/test/parallel/test-fs-cp-sync-unicode-dest.mjs @@ -0,0 +1,23 @@ +// Regression test for https://github.com/nodejs/node/issues/61878 +// fs.cpSync should copy files when destination path has UTF characters. +import '../common/index.mjs'; +import { cpSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; +import assert from 'node:assert'; +import tmpdir from '../common/tmpdir.js'; + +tmpdir.refresh(); + +const src = join(tmpdir.path, 'src'); +mkdirSync(join(src, 'subdir'), { recursive: true }); +writeFileSync(join(src, 'file1.txt'), 'Hello World'); +writeFileSync(join(src, 'subdir', 'nested.txt'), 'Nested File'); + +const dest = join(tmpdir.path, 'Eyjafjallajökull-Pranckevičius'); +cpSync(src, dest, { recursive: true, force: true }); + +const destFiles = readdirSync(dest); +assert.ok(destFiles.includes('file1.txt')); +assert.strictEqual(readFileSync(join(dest, 'file1.txt'), 'utf8'), 'Hello World'); +assert.ok(destFiles.includes('subdir')); +assert.strictEqual(readFileSync(join(dest, 'subdir', 'nested.txt'), 'utf8'), 'Nested File');