From 176002400886bc7f438236c727a61831efd5e565 Mon Sep 17 00:00:00 2001 From: yamachu Date: Wed, 22 Jan 2025 20:24:38 +0900 Subject: [PATCH] src: fix to generate path from wchar_t via wstring Take a similar approach to node_file and allow the creation of paths code point must be specified to convert from wchar_t to utf8. PR-URL: https://github.com/nodejs/node/pull/56696 Fixes: https://github.com/nodejs/node/issues/56650 Refs: https://github.com/nodejs/node/pull/56657 Reviewed-By: James M Snell Reviewed-By: Yagiz Nizipli Reviewed-By: Luigi Pinca --- src/node_file.cc | 15 +-------------- src/node_modules.cc | 24 ++++++++++++++++++++---- src/util-inl.h | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/node_file.cc b/src/node_file.cc index 984bc55ee9b941..8e29bb39887625 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -3146,21 +3146,8 @@ static void GetFormatOfExtensionlessFile( } #ifdef _WIN32 -std::wstring ConvertToWideString(const std::string& str) { - int size_needed = MultiByteToWideChar( - CP_UTF8, 0, &str[0], static_cast(str.size()), nullptr, 0); - std::wstring wstrTo(size_needed, 0); - MultiByteToWideChar(CP_UTF8, - 0, - &str[0], - static_cast(str.size()), - &wstrTo[0], - size_needed); - return wstrTo; -} - #define BufferValueToPath(str) \ - std::filesystem::path(ConvertToWideString(str.ToString())) + std::filesystem::path(ConvertToWideString(str.ToString(), CP_UTF8)) std::string ConvertWideToUTF8(const std::wstring& wstr) { if (wstr.empty()) return std::string(); diff --git a/src/node_modules.cc b/src/node_modules.cc index 85c8e21cf026ff..38d2c65c7f3282 100644 --- a/src/node_modules.cc +++ b/src/node_modules.cc @@ -349,8 +349,16 @@ void BindingData::GetNearestParentPackageJSON( path_value_str.push_back(kPathSeparator); } - auto package_json = - TraverseParent(realm, std::filesystem::path(path_value_str)); + std::filesystem::path path; + +#ifdef _WIN32 + std::wstring wide_path = ConvertToWideString(path_value_str, GetACP()); + path = std::filesystem::path(wide_path); +#else + path = std::filesystem::path(path_value_str); +#endif + + auto package_json = TraverseParent(realm, path); if (package_json != nullptr) { args.GetReturnValue().Set(package_json->Serialize(realm)); @@ -375,8 +383,16 @@ void BindingData::GetNearestParentPackageJSONType( path_value_str.push_back(kPathSeparator); } - auto package_json = - TraverseParent(realm, std::filesystem::path(path_value_str)); + std::filesystem::path path; + +#ifdef _WIN32 + std::wstring wide_path = ConvertToWideString(path_value_str, GetACP()); + path = std::filesystem::path(wide_path); +#else + path = std::filesystem::path(path_value_str); +#endif + + auto package_json = TraverseParent(realm, path); if (package_json == nullptr) { return; diff --git a/src/util-inl.h b/src/util-inl.h index a35e15eeed6576..b5ae5950b62767 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -562,6 +562,22 @@ bool IsWindowsBatchFile(const char* filename) { #endif // _WIN32 } +#ifdef _WIN32 +inline std::wstring ConvertToWideString(const std::string& str, + UINT code_page) { + int size_needed = MultiByteToWideChar( + code_page, 0, &str[0], static_cast(str.size()), nullptr, 0); + std::wstring wstrTo(size_needed, 0); + MultiByteToWideChar(code_page, + 0, + &str[0], + static_cast(str.size()), + &wstrTo[0], + size_needed); + return wstrTo; +} +#endif // _WIN32 + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS