From: Orgad Shaneh Date: Wed, 5 Oct 2022 20:10:24 +0000 (+0300) Subject: fix: Remove usage of deprecated codecvt header (#1172) X-Git-Tag: v4.7~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6072098415e3ccf8a2ac6542db35d1f72f8d08b;p=thirdparty%2Fccache.git fix: Remove usage of deprecated codecvt header (#1172) Based on https://stackoverflow.com/a/69410299/764870. --- 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