diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index 76bf6b71569..1cdb6dfbc97 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -312,9 +312,15 @@ namespace nvhttp { save_state() { pt::ptree root; - if (fs::exists(config::nvhttp.file_state)) { + fs::path state_path(config::nvhttp.file_state); + if (fs::exists(state_path)) { try { - pt::read_json(config::nvhttp.file_state, root); + std::ifstream ifs(state_path); + if (!ifs.is_open()) { + BOOST_LOG(error) << "Couldn't open "sv << config::nvhttp.file_state << " for reading"; + return; + } + pt::read_json(ifs, root); } catch (std::exception &e) { BOOST_LOG(error) << "Couldn't read "sv << config::nvhttp.file_state << ": "sv << e.what(); @@ -339,7 +345,12 @@ namespace nvhttp { root.add_child("root.named_devices"s, named_cert_nodes); try { - pt::write_json(config::nvhttp.file_state, root); + std::ofstream ofs(state_path); + if (!ofs.is_open()) { + BOOST_LOG(error) << "Couldn't open "sv << config::nvhttp.file_state << " for writing"; + return; + } + pt::write_json(ofs, root); } catch (std::exception &e) { BOOST_LOG(error) << "Couldn't write "sv << config::nvhttp.file_state << ": "sv << e.what(); @@ -349,7 +360,8 @@ namespace nvhttp { void load_state() { - if (!fs::exists(config::nvhttp.file_state)) { + fs::path state_path(config::nvhttp.file_state); + if (!fs::exists(state_path)) { BOOST_LOG(debug) << "File "sv << config::nvhttp.file_state << " doesn't exist"sv; http::unique_id = uuid_util::uuid_t::generate().string(); return; @@ -357,7 +369,13 @@ namespace nvhttp { pt::ptree tree; try { - pt::read_json(config::nvhttp.file_state, tree); + std::ifstream ifs(state_path); + if (!ifs.is_open()) { + BOOST_LOG(error) << "Couldn't open "sv << config::nvhttp.file_state << " for reading"; + http::unique_id = uuid_util::uuid_t::generate().string(); + return; + } + pt::read_json(ifs, tree); } catch (std::exception &e) { BOOST_LOG(error) << "Couldn't read "sv << config::nvhttp.file_state << ": "sv << e.what(); diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 9f2908225ae..9401109f5d1 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -1287,6 +1287,9 @@ namespace platf { int chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8, size, wide, size); if (chars <= 0) { + auto winerr = GetLastError(); + BOOST_LOG(warning) << "unicode(): MultiByteToWideChar failed, error=" << winerr + << ", size=" << size; return; } diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index f97fb7564a7..0c7ee209488 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -1036,7 +1036,7 @@ namespace platf { */ bp::child run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { - std::wstring start_dir = from_utf8(working_dir.string()); + std::wstring start_dir = working_dir.wstring(); HANDLE job = group ? group->native_handle() : nullptr; STARTUPINFOEXW startup_info = create_startup_info(file, job ? &job : nullptr, ec); PROCESS_INFORMATION process_info; @@ -2012,12 +2012,38 @@ namespace platf { return {}; } - // Get the output size required to store the string + // Get the output size required to store the string (strict UTF-8 validation) auto output_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, string.data(), string.size(), nullptr, 0); if (output_size == 0) { auto winerr = GetLastError(); - BOOST_LOG(error) << "Failed to get UTF-16 buffer size: "sv << winerr; - return {}; + + // Log hex dump of the first bytes to help diagnose the invalid string + std::ostringstream hex_dump; + auto dump_len = std::min(string.size(), 64); + for (size_t i = 0; i < dump_len; i++) { + hex_dump << std::hex << std::setfill('0') << std::setw(2) + << (static_cast(string[i]) & 0xFF); + if (i + 1 < dump_len) hex_dump << ' '; + } + BOOST_LOG(error) << "Failed to get UTF-16 buffer size: "sv << winerr + << " (len=" << string.size() + << ", hex=[" << hex_dump.str() << "]" + << ", str=\"" << string.substr(0, 64) << "\")"; + + // Fallback: try converting from the system's default ANSI code page (e.g. GBK on Chinese Windows) + output_size = MultiByteToWideChar(CP_ACP, 0, string.data(), string.size(), nullptr, 0); + if (output_size == 0) { + BOOST_LOG(error) << "Fallback ANSI conversion also failed: "sv << GetLastError(); + return {}; + } + BOOST_LOG(warning) << "from_utf8: falling back to ANSI code page conversion for non-UTF-8 string"; + + std::wstring output(output_size, L'\0'); + output_size = MultiByteToWideChar(CP_ACP, 0, string.data(), string.size(), output.data(), output.size()); + if (output_size == 0) { + return {}; + } + return output; } // Perform the conversion