Skip to content

Commit 79ffefa

Browse files
jazellytargos
authored andcommitted
fs: convert to u8 string for filesystem path
PR-URL: #54653 Fixes: #54476 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 20d3a80 commit 79ffefa

File tree

4 files changed

+61
-31
lines changed

4 files changed

+61
-31
lines changed

src/node_file.cc

+46-31
Original file line numberDiff line numberDiff line change
@@ -3035,22 +3035,24 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
30353035
ToNamespacedPath(env, &src);
30363036
THROW_IF_INSUFFICIENT_PERMISSIONS(
30373037
env, permission::PermissionScope::kFileSystemRead, src.ToStringView());
3038-
auto src_path = std::filesystem::path(src.ToStringView());
3038+
3039+
auto src_path = std::filesystem::path(src.ToU8StringView());
30393040

30403041
BufferValue dest(isolate, args[1]);
30413042
CHECK_NOT_NULL(*dest);
30423043
ToNamespacedPath(env, &dest);
30433044
THROW_IF_INSUFFICIENT_PERMISSIONS(
30443045
env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView());
3045-
auto dest_path = std::filesystem::path(dest.ToStringView());
30463046

3047+
auto dest_path = std::filesystem::path(dest.ToU8StringView());
30473048
bool dereference = args[2]->IsTrue();
30483049
bool recursive = args[3]->IsTrue();
30493050

30503051
std::error_code error_code;
30513052
auto src_status = dereference
30523053
? std::filesystem::symlink_status(src_path, error_code)
30533054
: std::filesystem::status(src_path, error_code);
3055+
30543056
if (error_code) {
30553057
#ifdef _WIN32
30563058
int errorno = uv_translate_sys_error(error_code.value());
@@ -3074,34 +3076,41 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
30743076
if (!error_code) {
30753077
// Check if src and dest are identical.
30763078
if (std::filesystem::equivalent(src_path, dest_path)) {
3077-
std::string message =
3078-
"src and dest cannot be the same " + dest_path.string();
3079-
return THROW_ERR_FS_CP_EINVAL(env, message.c_str());
3079+
std::u8string message =
3080+
u8"src and dest cannot be the same " + dest_path.u8string();
3081+
return THROW_ERR_FS_CP_EINVAL(
3082+
env, reinterpret_cast<const char*>(message.c_str()));
30803083
}
30813084

30823085
const bool dest_is_dir =
30833086
dest_status.type() == std::filesystem::file_type::directory;
30843087

30853088
if (src_is_dir && !dest_is_dir) {
3086-
std::string message = "Cannot overwrite non-directory " +
3087-
src_path.string() + " with directory " +
3088-
dest_path.string();
3089-
return THROW_ERR_FS_CP_DIR_TO_NON_DIR(env, message.c_str());
3089+
std::u8string message = u8"Cannot overwrite non-directory " +
3090+
src_path.u8string() + u8" with directory " +
3091+
dest_path.u8string();
3092+
return THROW_ERR_FS_CP_DIR_TO_NON_DIR(
3093+
env, reinterpret_cast<const char*>(message.c_str()));
30903094
}
30913095

30923096
if (!src_is_dir && dest_is_dir) {
3093-
std::string message = "Cannot overwrite directory " + dest_path.string() +
3094-
" with non-directory " + src_path.string();
3095-
return THROW_ERR_FS_CP_NON_DIR_TO_DIR(env, message.c_str());
3097+
std::u8string message = u8"Cannot overwrite directory " +
3098+
dest_path.u8string() + u8" with non-directory " +
3099+
src_path.u8string();
3100+
return THROW_ERR_FS_CP_NON_DIR_TO_DIR(
3101+
env, reinterpret_cast<const char*>(message.c_str()));
30963102
}
30973103
}
30983104

3099-
std::string dest_path_str = dest_path.string();
3105+
std::u8string dest_path_str = dest_path.u8string();
3106+
31003107
// Check if dest_path is a subdirectory of src_path.
3101-
if (src_is_dir && dest_path_str.starts_with(src_path.string())) {
3102-
std::string message = "Cannot copy " + src_path.string() +
3103-
" to a subdirectory of self " + dest_path.string();
3104-
return THROW_ERR_FS_CP_EINVAL(env, message.c_str());
3108+
if (src_is_dir && dest_path_str.starts_with(src_path.u8string())) {
3109+
std::u8string message = u8"Cannot copy " + src_path.u8string() +
3110+
u8" to a subdirectory of self " +
3111+
dest_path.u8string();
3112+
return THROW_ERR_FS_CP_EINVAL(
3113+
env, reinterpret_cast<const char*>(message.c_str()));
31053114
}
31063115

31073116
auto dest_parent = dest_path.parent_path();
@@ -3112,9 +3121,11 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
31123121
dest_parent.parent_path() != dest_parent) {
31133122
if (std::filesystem::equivalent(
31143123
src_path, dest_path.parent_path(), error_code)) {
3115-
std::string message = "Cannot copy " + src_path.string() +
3116-
" to a subdirectory of self " + dest_path.string();
3117-
return THROW_ERR_FS_CP_EINVAL(env, message.c_str());
3124+
std::u8string message = u8"Cannot copy " + src_path.u8string() +
3125+
u8" to a subdirectory of self " +
3126+
dest_path.u8string();
3127+
return THROW_ERR_FS_CP_EINVAL(
3128+
env, reinterpret_cast<const char*>(message.c_str()));
31183129
}
31193130

31203131
// If equivalent fails, it's highly likely that dest_parent does not exist
@@ -3126,25 +3137,29 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
31263137
}
31273138

31283139
if (src_is_dir && !recursive) {
3129-
std::string message =
3130-
"Recursive option not enabled, cannot copy a directory: " +
3131-
src_path.string();
3132-
return THROW_ERR_FS_EISDIR(env, message.c_str());
3140+
std::u8string message =
3141+
u8"Recursive option not enabled, cannot copy a directory: " +
3142+
src_path.u8string();
3143+
return THROW_ERR_FS_EISDIR(env,
3144+
reinterpret_cast<const char*>(message.c_str()));
31333145
}
31343146

31353147
switch (src_status.type()) {
31363148
case std::filesystem::file_type::socket: {
3137-
std::string message = "Cannot copy a socket file: " + dest_path.string();
3138-
return THROW_ERR_FS_CP_SOCKET(env, message.c_str());
3149+
std::u8string message = u8"Cannot copy a socket file: " + dest_path_str;
3150+
return THROW_ERR_FS_CP_SOCKET(
3151+
env, reinterpret_cast<const char*>(message.c_str()));
31393152
}
31403153
case std::filesystem::file_type::fifo: {
3141-
std::string message = "Cannot copy a FIFO pipe: " + dest_path.string();
3142-
return THROW_ERR_FS_CP_FIFO_PIPE(env, message.c_str());
3154+
std::u8string message = u8"Cannot copy a FIFO pipe: " + dest_path_str;
3155+
return THROW_ERR_FS_CP_FIFO_PIPE(
3156+
env, reinterpret_cast<const char*>(message.c_str()));
31433157
}
31443158
case std::filesystem::file_type::unknown: {
3145-
std::string message =
3146-
"Cannot copy an unknown file type: " + dest_path.string();
3147-
return THROW_ERR_FS_CP_UNKNOWN(env, message.c_str());
3159+
std::u8string message =
3160+
u8"Cannot copy an unknown file type: " + dest_path_str;
3161+
return THROW_ERR_FS_CP_UNKNOWN(
3162+
env, reinterpret_cast<const char*>(message.c_str()));
31483163
}
31493164
default:
31503165
break;

src/util.h

+4
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,10 @@ class BufferValue : public MaybeStackBuffer<char> {
562562
inline std::string_view ToStringView() const {
563563
return std::string_view(out(), length());
564564
}
565+
inline std::u8string_view ToU8StringView() const {
566+
return std::u8string_view(reinterpret_cast<const char8_t*>(out()),
567+
length());
568+
}
565569
};
566570

567571
#define SPREAD_BUFFER_ARG(val, name) \
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

+8
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)