fs: fix cpSync to handle non-ASCII characters

Fixes: https://github.com/nodejs/node/issues/61878
PR-URL: https://github.com/nodejs/node/pull/61950
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Stefan Stojanovic authored and GitHub committed 2026-03-10 14:11:23 +00:00
1 parent ae228c1ff5
commit 95ee87da53
2 files changed
+34 -5

No files matched your search

+11 -5
View File
@@ -3425,15 +3425,18 @@ static void CpSyncOverrideFile(const FunctionCallbackInfo<Value>& 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<Value>& args) {
}
if (preserve_timestamps) {
CopyUtimes(*src, *dest, env);
CopyUtimes(src_path, dest_path, env);
}
}
@@ -3489,8 +3492,11 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& 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<Value>& 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(
@@ -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');