diff --git a/include/fmt/format.cc b/include/fmt/format.cc index 429657fb..6da96f71 100644 --- a/include/fmt/format.cc +++ b/include/fmt/format.cc @@ -280,9 +280,16 @@ const uint64_t internal::basic_data::POWERS_OF_10_64[] = { FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) { static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; - if (s.size() > INT_MAX) + if (s.size() > INT_MAX || s.data() == nullptr) FMT_THROW(windows_error(ERROR_INVALID_PARAMETER, ERROR_MSG)); int s_size = static_cast(s.size()); + if (s_size == 0) // MultiByteToWideChar does not support zero length, handle separately + { + buffer_.resize(1); + buffer_[0] = 0; + return; + } + int length = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0); if (length == 0) @@ -303,9 +310,16 @@ FMT_FUNC internal::utf16_to_utf8::utf16_to_utf8(wstring_view s) { } FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) { - if (s.size() > INT_MAX) + if (s.size() > INT_MAX || s.data() == nullptr) return ERROR_INVALID_PARAMETER; int s_size = static_cast(s.size()); + if (s_size == 0) // MultiByteToWideChar does not support zero length, handle separately + { + buffer_.resize(1); + buffer_[0] = 0; + return 0; + } + int length = WideCharToMultiByte( CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL); if (length == 0) diff --git a/test/util-test.cc b/test/util-test.cc index 97dabfbb..c9db1ae1 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -665,6 +665,13 @@ TEST(UtilTest, UTF16ToUTF8) { EXPECT_EQ(s.size(), u.size()); } +TEST(UtilTest, UTF16ToUTF8EmptyString) { + std::string s = ""; + fmt::internal::UTF16ToUTF8 u(L""); + EXPECT_EQ(s, u.str()); + EXPECT_EQ(s.size(), u.size()); +} + TEST(UtilTest, UTF8ToUTF16) { std::string s = "лошадка"; fmt::internal::utf8_to_utf16 u(s.c_str()); @@ -672,6 +679,13 @@ TEST(UtilTest, UTF8ToUTF16) { EXPECT_EQ(7, u.size()); } +TEST(UtilTest, UTF8ToUTF16EmptyString) { + std::string s = ""; + fmt::internal::UTF8ToUTF16 u(s.c_str()); + EXPECT_EQ(L"", u.str()); + EXPECT_EQ(s.size(), u.size()); +} + template void check_utf_conversion_error( const char *message,