From 859195c24e48fb92371bc353b9441885b297676a Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Tue, 11 Jul 2023 01:23:12 +0200 Subject: [PATCH] Better Unicode argument handling in FUSE driver on Windows --- include/dwarfs_tool_main.h | 2 +- src/dwarfs.cpp | 2 +- src/dwarfs_main.cpp | 20 ++++++++++++++++++-- src/universal.cpp | 34 +++------------------------------- 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/include/dwarfs_tool_main.h b/include/dwarfs_tool_main.h index 60d1e3a3..1fa3faf4 100644 --- a/include/dwarfs_tool_main.h +++ b/include/dwarfs_tool_main.h @@ -35,6 +35,6 @@ int mkdwarfs_main(int argc, sys_char** argv); int dwarfsck_main(int argc, sys_char** argv); int dwarfsextract_main(int argc, sys_char** argv); int dwarfsbench_main(int argc, sys_char** argv); -int dwarfs_main(int argc, char** argv); +int dwarfs_main(int argc, sys_char** argv); } // namespace dwarfs diff --git a/src/dwarfs.cpp b/src/dwarfs.cpp index 6ee8b158..9482a470 100644 --- a/src/dwarfs.cpp +++ b/src/dwarfs.cpp @@ -22,6 +22,6 @@ #include "dwarfs/error.h" #include "dwarfs_tool_main.h" -int main(int argc, char** argv) { +int SYS_MAIN(int argc, dwarfs::sys_char** argv) { return dwarfs::safe_main([&] { return dwarfs::dwarfs_main(argc, argv); }); } diff --git a/src/dwarfs_main.cpp b/src/dwarfs_main.cpp index 71ec556c..f6a4a5f4 100644 --- a/src/dwarfs_main.cpp +++ b/src/dwarfs_main.cpp @@ -993,7 +993,8 @@ int option_hdl(void* data, char const* arg, int key, return 1; } - opts->fsimage = std::filesystem::canonical(std::filesystem::path(arg)); + opts->fsimage = std::filesystem::canonical( + std::filesystem::path(reinterpret_cast(arg))); return 0; @@ -1203,8 +1204,23 @@ void load_filesystem(dwarfs_userdata& userdata) { ti << "file system initialized"; } -int dwarfs_main(int argc, char** argv) { +int dwarfs_main(int argc, sys_char** argv) { +#ifdef _WIN32 + std::vector argv_strings; + std::vector argv_copy; + argv_strings.reserve(argc); + argv_copy.reserve(argc); + + for (int i = 0; i < argc; ++i) { + argv_strings.push_back(sys_string_to_string(argv[i])); + argv_copy.push_back(argv_strings.back().data()); + } + + struct fuse_args args = FUSE_ARGS_INIT(argc, argv_copy.data()); +#else struct fuse_args args = FUSE_ARGS_INIT(argc, argv); +#endif + dwarfs_userdata userdata(std::cerr); auto& opts = userdata.opts; diff --git a/src/universal.cpp b/src/universal.cpp index a937b3e5..b3a20de3 100644 --- a/src/universal.cpp +++ b/src/universal.cpp @@ -29,6 +29,7 @@ #include #include +#include #ifdef _WIN32 #include @@ -36,24 +37,13 @@ #include "dwarfs/error.h" #include "dwarfs/tool.h" +#include "dwarfs/util.h" #include "dwarfs_tool_main.h" namespace { using namespace dwarfs; -std::string to_narrow_string(sys_char const* str) { -#ifdef _WIN32 - std::wstring_view view(str); - std::string rv(view.size(), 0); - std::transform(view.begin(), view.end(), rv.begin(), - [](sys_char c) { return static_cast(c); }); - return rv; -#else - return std::string(str); -#endif -} - #ifdef _WIN32 FARPROC WINAPI delay_hook(unsigned dliNotify, PDelayLoadInfo pdli) { switch (dliNotify) { @@ -71,20 +61,6 @@ FARPROC WINAPI delay_hook(unsigned dliNotify, PDelayLoadInfo pdli) { ::exit(1); } - -int dwarfs_main_helper(int argc, sys_char** argv) { - std::vector argv_strings; - std::vector argv_copy; - argv_strings.reserve(argc); - argv_copy.reserve(argc); - - for (int i = 0; i < argc; ++i) { - argv_strings.push_back(to_narrow_string(argv[i])); - argv_copy.push_back(argv_strings.back().data()); - } - - return dwarfs_main(argc, argv_copy.data()); -} #endif #ifdef _WIN32 @@ -94,11 +70,7 @@ int dwarfs_main_helper(int argc, sys_char** argv) { #endif std::map const functions{ -#ifdef _WIN32 - {"dwarfs", &dwarfs_main_helper}, -#else {"dwarfs", &dwarfs_main}, -#endif {"mkdwarfs", &mkdwarfs_main}, {"dwarfsck", &dwarfsck_main}, {"dwarfsextract", &dwarfsextract_main}, @@ -113,7 +85,7 @@ extern "C" const PfnDliHook __pfnDliFailureHook2 = delay_hook; int SYS_MAIN(int argc, sys_char** argv) { if (argc > 1) { - auto tool_arg = to_narrow_string(argv[1]); + auto tool_arg = sys_string_to_string(argv[1]); if (tool_arg.starts_with("--tool=")) { if (auto it = functions.find(tool_arg.substr(7)); it != functions.end()) { std::vector argv_copy;