From a6072098415e3ccf8a2ac6542db35d1f72f8d08b Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 5 Oct 2022 23:10:24 +0300 Subject: [PATCH] fix: Remove usage of deprecated codecvt header (#1172) Based on https://stackoverflow.com/a/69410299/764870. --- src/util/file.cpp | 36 ++++++++++++++++++++++++++++++------ unittest/test_util_file.cpp | 8 ++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/util/file.cpp b/src/util/file.cpp index b3d3771fc..964d68461 100644 --- a/src/util/file.cpp +++ b/src/util/file.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -47,7 +48,6 @@ #include #include -#include #include #include #include @@ -171,11 +171,35 @@ read_file(const std::string& path, size_t size_hint) // it's actually needed. if (has_utf16_le_bom(result)) { result.erase(0, 2); // Remove BOM. - std::u16string result_as_u16((result.size() / 2) + 1, '\0'); - result_as_u16 = reinterpret_cast(result.c_str()); - std::wstring_convert, char16_t> - converter; - result = converter.to_bytes(result_as_u16); + if (result.empty()) + return result; + + std::wstring result_as_u16((result.size() / 2) + 1, '\0'); + result_as_u16 = reinterpret_cast(result.c_str()); + + const int size = WideCharToMultiByte(CP_UTF8, + WC_ERR_INVALID_CHARS, + result_as_u16.c_str(), + int(result_as_u16.size()), + nullptr, + 0, + nullptr, + nullptr); + if (size <= 0) + return nonstd::make_unexpected( + FMT("Failed to convert {} from UTF-16LE to UTF-8: {}", + path, + Win32Util::error_message(GetLastError()))); + + result = std::string(size, '\0'); + WideCharToMultiByte(CP_UTF8, + 0, + result_as_u16.c_str(), + int(result_as_u16.size()), + &result.at(0), + size, + nullptr, + nullptr); } } #endif diff --git a/unittest/test_util_file.cpp b/unittest/test_util_file.cpp index 9b99d1501..cc6771378 100644 --- a/unittest/test_util_file.cpp +++ b/unittest/test_util_file.cpp @@ -120,6 +120,14 @@ TEST_CASE("util::read_file with UTF-16 little endian encoding") auto read_data = util::read_file("test"); REQUIRE(read_data); CHECK(*read_data == "abc"); + + data.push_back('\0'); + data.push_back(static_cast(0xd8)); + data.push_back('d'); + data.push_back('\0'); + CHECK(util::write_file("test", data)); + read_data = util::read_file("test"); + REQUIRE(!read_data); } #endif -- 2.47.2