@@ -3127,6 +3127,55 @@ static void GetFormatOfExtensionlessFile(
31273127 return args.GetReturnValue().Set(EXTENSIONLESS_FORMAT_JAVASCRIPT);
31283128}
31293129
3130+ #ifdef _WIN32
3131+ std::wstring ConvertToWideString(const std::string& str) {
3132+ int size_needed = MultiByteToWideChar(
3133+ CP_UTF8, 0, &str[0], static_cast<int>(str.size()), nullptr, 0);
3134+ std::wstring wstrTo(size_needed, 0);
3135+ MultiByteToWideChar(CP_UTF8,
3136+ 0,
3137+ &str[0],
3138+ static_cast<int>(str.size()),
3139+ &wstrTo[0],
3140+ size_needed);
3141+ return wstrTo;
3142+ }
3143+
3144+ #define BufferValueToPath(str) \
3145+ std::filesystem::path(ConvertToWideString(str.ToString()))
3146+
3147+ std::string ConvertWideToUTF8(const std::wstring& wstr) {
3148+ if (wstr.empty()) return std::string();
3149+
3150+ int size_needed = WideCharToMultiByte(CP_UTF8,
3151+ 0,
3152+ &wstr[0],
3153+ static_cast<int>(wstr.size()),
3154+ nullptr,
3155+ 0,
3156+ nullptr,
3157+ nullptr);
3158+ std::string strTo(size_needed, 0);
3159+ WideCharToMultiByte(CP_UTF8,
3160+ 0,
3161+ &wstr[0],
3162+ static_cast<int>(wstr.size()),
3163+ &strTo[0],
3164+ size_needed,
3165+ nullptr,
3166+ nullptr);
3167+ return strTo;
3168+ }
3169+
3170+ #define PathToString(path) ConvertWideToUTF8(path.wstring());
3171+
3172+ #else // _WIN32
3173+
3174+ #define BufferValueToPath(str) std::filesystem::path(str.ToStringView());
3175+ #define PathToString(path) path.native();
3176+
3177+ #endif // _WIN32
3178+
31303179static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
31313180 Environment* env = Environment::GetCurrent(args);
31323181 Isolate* isolate = env->isolate();
@@ -3139,15 +3188,15 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
31393188 THROW_IF_INSUFFICIENT_PERMISSIONS(
31403189 env, permission::PermissionScope::kFileSystemRead, src.ToStringView());
31413190
3142- auto src_path = std::filesystem::path (src.ToU8StringView() );
3191+ auto src_path = BufferValueToPath (src);
31433192
31443193 BufferValue dest(isolate, args[1]);
31453194 CHECK_NOT_NULL(*dest);
31463195 ToNamespacedPath(env, &dest);
31473196 THROW_IF_INSUFFICIENT_PERMISSIONS(
31483197 env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView());
31493198
3150- auto dest_path = std::filesystem::path (dest.ToU8StringView() );
3199+ auto dest_path = BufferValueToPath (dest);
31513200 bool dereference = args[2]->IsTrue();
31523201 bool recursive = args[3]->IsTrue();
31533202
@@ -3176,47 +3225,41 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
31763225 (src_status.type() == std::filesystem::file_type::directory) ||
31773226 (dereference && src_status.type() == std::filesystem::file_type::symlink);
31783227
3228+ auto src_path_str = PathToString(src_path);
3229+ auto dest_path_str = PathToString(dest_path);
3230+
31793231 if (!error_code) {
31803232 // Check if src and dest are identical.
31813233 if (std::filesystem::equivalent(src_path, dest_path)) {
3182- std::u8string message =
3183- u8"src and dest cannot be the same " + dest_path.u8string();
3184- return THROW_ERR_FS_CP_EINVAL(
3185- env, reinterpret_cast<const char*>(message.c_str()));
3234+ std::string message = "src and dest cannot be the same %s";
3235+ return THROW_ERR_FS_CP_EINVAL(env, message.c_str(), dest_path_str);
31863236 }
31873237
31883238 const bool dest_is_dir =
31893239 dest_status.type() == std::filesystem::file_type::directory;
3190-
31913240 if (src_is_dir && !dest_is_dir) {
3192- std::u8string message = u8"Cannot overwrite non-directory " +
3193- src_path.u8string() + u8" with directory " +
3194- dest_path.u8string();
3241+ std::string message =
3242+ "Cannot overwrite non-directory %s with directory %s";
31953243 return THROW_ERR_FS_CP_DIR_TO_NON_DIR(
3196- env, reinterpret_cast<const char*>( message.c_str()) );
3244+ env, message.c_str(), src_path_str, dest_path_str );
31973245 }
31983246
31993247 if (!src_is_dir && dest_is_dir) {
3200- std::u8string message = u8"Cannot overwrite directory " +
3201- dest_path.u8string() + u8" with non-directory " +
3202- src_path.u8string();
3248+ std::string message =
3249+ "Cannot overwrite directory %s with non-directory %s";
32033250 return THROW_ERR_FS_CP_NON_DIR_TO_DIR(
3204- env, reinterpret_cast<const char*>( message.c_str()) );
3251+ env, message.c_str(), dest_path_str, src_path_str );
32053252 }
32063253 }
32073254
3208- std::u8string dest_path_str = dest_path.u8string();
3209- std::u8string src_path_str = src_path.u8string();
32103255 if (!src_path_str.ends_with(std::filesystem::path::preferred_separator)) {
32113256 src_path_str += std::filesystem::path::preferred_separator;
32123257 }
32133258 // Check if dest_path is a subdirectory of src_path.
32143259 if (src_is_dir && dest_path_str.starts_with(src_path_str)) {
3215- std::u8string message = u8"Cannot copy " + src_path.u8string() +
3216- u8" to a subdirectory of self " +
3217- dest_path.u8string();
3260+ std::string message = "Cannot copy %s to a subdirectory of self %s";
32183261 return THROW_ERR_FS_CP_EINVAL(
3219- env, reinterpret_cast<const char*>( message.c_str()) );
3262+ env, message.c_str(), src_path_str, dest_path_str );
32203263 }
32213264
32223265 auto dest_parent = dest_path.parent_path();
@@ -3227,11 +3270,9 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
32273270 dest_parent.parent_path() != dest_parent) {
32283271 if (std::filesystem::equivalent(
32293272 src_path, dest_path.parent_path(), error_code)) {
3230- std::u8string message = u8"Cannot copy " + src_path.u8string() +
3231- u8" to a subdirectory of self " +
3232- dest_path.u8string();
3273+ std::string message = "Cannot copy %s to a subdirectory of self %s";
32333274 return THROW_ERR_FS_CP_EINVAL(
3234- env, reinterpret_cast<const char*>( message.c_str()) );
3275+ env, message.c_str(), src_path_str, dest_path_str );
32353276 }
32363277
32373278 // If equivalent fails, it's highly likely that dest_parent does not exist
@@ -3243,29 +3284,23 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
32433284 }
32443285
32453286 if (src_is_dir && !recursive) {
3246- std::u8string message =
3247- u8"Recursive option not enabled, cannot copy a directory: " +
3248- src_path.u8string();
3249- return THROW_ERR_FS_EISDIR(env,
3250- reinterpret_cast<const char*>(message.c_str()));
3287+ std::string message =
3288+ "Recursive option not enabled, cannot copy a directory: %s";
3289+ return THROW_ERR_FS_EISDIR(env, message.c_str(), src_path_str);
32513290 }
32523291
32533292 switch (src_status.type()) {
32543293 case std::filesystem::file_type::socket: {
3255- std::u8string message = u8"Cannot copy a socket file: " + dest_path_str;
3256- return THROW_ERR_FS_CP_SOCKET(
3257- env, reinterpret_cast<const char*>(message.c_str()));
3294+ std::string message = "Cannot copy a socket file: %s";
3295+ return THROW_ERR_FS_CP_SOCKET(env, message.c_str(), dest_path_str);
32583296 }
32593297 case std::filesystem::file_type::fifo: {
3260- std::u8string message = u8"Cannot copy a FIFO pipe: " + dest_path_str;
3261- return THROW_ERR_FS_CP_FIFO_PIPE(
3262- env, reinterpret_cast<const char*>(message.c_str()));
3298+ std::string message = "Cannot copy a FIFO pipe: %s";
3299+ return THROW_ERR_FS_CP_FIFO_PIPE(env, message.c_str(), dest_path_str);
32633300 }
32643301 case std::filesystem::file_type::unknown: {
3265- std::u8string message =
3266- u8"Cannot copy an unknown file type: " + dest_path_str;
3267- return THROW_ERR_FS_CP_UNKNOWN(
3268- env, reinterpret_cast<const char*>(message.c_str()));
3302+ std::string message = "Cannot copy an unknown file type: %s";
3303+ return THROW_ERR_FS_CP_UNKNOWN(env, message.c_str(), dest_path_str);
32693304 }
32703305 default:
32713306 break;
0 commit comments