Skip to content

Commit 8362525

Browse files
committed
fs: fix cpSync crash on utf characters
1 parent 01f751b commit 8362525

File tree

4 files changed

+25
-2
lines changed

4 files changed

+25
-2
lines changed

src/node_file.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,14 +3130,14 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
31303130
ToNamespacedPath(env, &src);
31313131
THROW_IF_INSUFFICIENT_PERMISSIONS(
31323132
env, permission::PermissionScope::kFileSystemRead, src.ToStringView());
3133-
auto src_path = std::filesystem::path(src.ToStringView());
3133+
auto src_path = std::filesystem::path(src.ToWString());
31343134

31353135
BufferValue dest(isolate, args[1]);
31363136
CHECK_NOT_NULL(*dest);
31373137
ToNamespacedPath(env, &dest);
31383138
THROW_IF_INSUFFICIENT_PERMISSIONS(
31393139
env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView());
3140-
auto dest_path = std::filesystem::path(dest.ToStringView());
3140+
auto dest_path = std::filesystem::path(dest.ToWString());
31413141

31423142
bool dereference = args[2]->IsTrue();
31433143
bool recursive = args[3]->IsTrue();

src/util.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ void DumpJavaScriptBacktrace(FILE* fp);
126126
#define ABORT_NO_BACKTRACE() abort()
127127
#endif
128128

129+
#ifdef _WIN32
130+
#include <windows.h>
131+
#endif
132+
129133
// Caller of this macro must not be marked as [[noreturn]]. Printing of
130134
// backtraces may not work correctly in [[noreturn]] functions because
131135
// when generating code for them the compiler can choose not to
@@ -562,6 +566,14 @@ class BufferValue : public MaybeStackBuffer<char> {
562566
inline std::string_view ToStringView() const {
563567
return std::string_view(out(), length());
564568
}
569+
inline std::wstring ToWString() const {
570+
#ifdef _WIN32
571+
auto size_needed = MultiByteToWideChar(CP_UTF8, 0, out(), (int)length(), NULL, 0);
572+
std::wstring wstrTo(length(), 0);
573+
MultiByteToWideChar(CP_UTF8, 0, out(), (int)length(), &wstrTo[0], size_needed);
574+
return wstrTo;
575+
#endif;
576+
}
565577
};
566578

567579
#define SPREAD_BUFFER_ARG(val, name) \
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
purpose: 'testing copy'
3+
};

test/parallel/test-fs-cp.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ function nextdir() {
3030

3131
// Synchronous implementation of copy.
3232

33+
// It copies a nested folder containing UTF characters.
34+
{
35+
const src = './test/fixtures/copy/utf/新建文件';
36+
const dest = nextdir();
37+
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
38+
assertDirEquivalent(src, dest);
39+
}
40+
3341
// It copies a nested folder structure with files and folders.
3442
{
3543
const src = './test/fixtures/copy/kitchen-sink';

0 commit comments

Comments
 (0)