Skip to content

Commit 0250b43

Browse files
StefanStojanovicaduh95
authored andcommitted
fs: fix cpSync to handle non-ASCII characters
Fixes: #61878 PR-URL: #61950 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent e4c164e commit 0250b43

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/node_file.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3432,15 +3432,18 @@ static void CpSyncOverrideFile(const FunctionCallbackInfo<Value>& args) {
34323432
THROW_IF_INSUFFICIENT_PERMISSIONS(
34333433
env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView());
34343434

3435+
auto src_path = src.ToPath();
3436+
auto dest_path = dest.ToPath();
3437+
34353438
std::error_code error;
34363439

3437-
if (!std::filesystem::remove(*dest, error)) {
3440+
if (!std::filesystem::remove(dest_path, error)) {
34383441
return env->ThrowStdErrException(error, "unlink", *dest);
34393442
}
34403443

34413444
if (mode == 0) {
34423445
// if no mode is specified use the faster std::filesystem API
3443-
if (!std::filesystem::copy_file(*src, *dest, error)) {
3446+
if (!std::filesystem::copy_file(src_path, dest_path, error)) {
34443447
return env->ThrowStdErrException(error, "cp", *dest);
34453448
}
34463449
} else {
@@ -3453,7 +3456,7 @@ static void CpSyncOverrideFile(const FunctionCallbackInfo<Value>& args) {
34533456
}
34543457

34553458
if (preserve_timestamps) {
3456-
CopyUtimes(*src, *dest, env);
3459+
CopyUtimes(src_path, dest_path, env);
34573460
}
34583461
}
34593462

@@ -3496,8 +3499,11 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
34963499
bool verbatim_symlinks = args[5]->IsTrue();
34973500
bool preserve_timestamps = args[6]->IsTrue();
34983501

3502+
auto src_path = src.ToPath();
3503+
auto dest_path = dest.ToPath();
3504+
34993505
std::error_code error;
3500-
std::filesystem::create_directories(*dest, error);
3506+
std::filesystem::create_directories(dest_path, error);
35013507
if (error) {
35023508
return env->ThrowStdErrException(error, "cp", *dest);
35033509
}
@@ -3639,7 +3645,7 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
36393645
return true;
36403646
};
36413647

3642-
copy_dir_contents(std::filesystem::path(*src), std::filesystem::path(*dest));
3648+
copy_dir_contents(src_path, dest_path);
36433649
}
36443650

36453651
BindingData::FilePathIsFileReturnType BindingData::FilePathIsFile(
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Regression test for https://github.com/nodejs/node/issues/61878
2+
// fs.cpSync should copy files when destination path has UTF characters.
3+
import '../common/index.mjs';
4+
import { cpSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
5+
import { join } from 'node:path';
6+
import assert from 'node:assert';
7+
import tmpdir from '../common/tmpdir.js';
8+
9+
tmpdir.refresh();
10+
11+
const src = join(tmpdir.path, 'src');
12+
mkdirSync(join(src, 'subdir'), { recursive: true });
13+
writeFileSync(join(src, 'file1.txt'), 'Hello World');
14+
writeFileSync(join(src, 'subdir', 'nested.txt'), 'Nested File');
15+
16+
const dest = join(tmpdir.path, 'Eyjafjallajökull-Pranckevičius');
17+
cpSync(src, dest, { recursive: true, force: true });
18+
19+
const destFiles = readdirSync(dest);
20+
assert.ok(destFiles.includes('file1.txt'));
21+
assert.strictEqual(readFileSync(join(dest, 'file1.txt'), 'utf8'), 'Hello World');
22+
assert.ok(destFiles.includes('subdir'));
23+
assert.strictEqual(readFileSync(join(dest, 'subdir', 'nested.txt'), 'utf8'), 'Nested File');

0 commit comments

Comments
 (0)