Skip to content

Commit

Permalink
Fixed UTF8/16 converters to support empty string input
Browse files Browse the repository at this point in the history
Previously an exception was thrown since Win32 WideCharToMultiByte API
returns error on zero-length input.
  • Loading branch information
vgalka-sl authored and vitaut committed Mar 14, 2018
1 parent c37c4c4 commit acb469a
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include/fmt/format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,13 @@ FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) {
if (s.size() > INT_MAX)
FMT_THROW(windows_error(ERROR_INVALID_PARAMETER, ERROR_MSG));
int s_size = static_cast<int>(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)
Expand All @@ -306,6 +313,13 @@ FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) {
if (s.size() > INT_MAX)
return ERROR_INVALID_PARAMETER;
int s_size = static_cast<int>(s.size());
if (s_size == 0) {
// WideCharToMultiByte 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)
Expand Down
14 changes: 14 additions & 0 deletions test/util-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -665,13 +665,27 @@ TEST(UtilTest, UTF16ToUTF8) {
EXPECT_EQ(s.size(), u.size());
}

TEST(UtilTest, UTF16ToUTF8EmptyString) {
std::string s = "";
fmt::internal::utf16_to_utf8 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());
EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", u.str());
EXPECT_EQ(7, u.size());
}

TEST(UtilTest, UTF8ToUTF16EmptyString) {
std::string s = "";
fmt::internal::utf8_to_utf16 u(s.c_str());
EXPECT_EQ(L"", u.str());
EXPECT_EQ(s.size(), u.size());
}

template <typename Converter, typename Char>
void check_utf_conversion_error(
const char *message,
Expand Down

0 comments on commit acb469a

Please sign in to comment.