From 692fe84331894a55afe679f47259329098c45682 Mon Sep 17 00:00:00 2001 From: Jan Wojciechowski Date: Sun, 5 Mar 2023 09:40:34 +0100 Subject: [PATCH] Fix condition for trailing bytes count in UTF-8 decoder. Test added to check if a replacement characters is added to output. --- include/SFML/System/Utf.inl | 2 +- test/System/String.test.cpp | 36 ++++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/include/SFML/System/Utf.inl b/include/SFML/System/Utf.inl index 02211135..d72931af 100644 --- a/include/SFML/System/Utf.inl +++ b/include/SFML/System/Utf.inl @@ -69,7 +69,7 @@ In Utf<8>::decode(In begin, In end, std::uint32_t& output, std::uint32_t replace // decode the character int trailingBytes = trailing[static_cast(*begin)]; - if (begin + trailingBytes < end) + if (trailingBytes < std::distance(begin, end)) { output = 0; diff --git a/test/System/String.test.cpp b/test/System/String.test.cpp index 20cde7f7..a0f96661 100644 --- a/test/System/String.test.cpp +++ b/test/System/String.test.cpp @@ -230,18 +230,30 @@ TEST_CASE("[System] sf::String") SUBCASE("fromUtf8()") { - constexpr std::array characters{'w', 'x', 'y', 'z'}; - const sf::String string = sf::String::fromUtf8(characters.begin(), characters.end()); - CHECK(std::string(string) == "wxyz"s); - CHECK(std::wstring(string) == L"wxyz"s); - CHECK(string.toAnsiString() == "wxyz"s); - CHECK(string.toWideString() == L"wxyz"s); - CHECK(string.toUtf8() == std::basic_string{'w', 'x', 'y', 'z'}); - CHECK(string.toUtf16() == u"wxyz"s); - CHECK(string.toUtf32() == U"wxyz"s); - CHECK(string.getSize() == 4); - CHECK(!string.isEmpty()); - CHECK(string.getData() != nullptr); + SUBCASE("Nominal") + { + constexpr std::array characters{'w', 'x', 'y', 'z'}; + const sf::String string = sf::String::fromUtf8(characters.begin(), characters.end()); + CHECK(std::string(string) == "wxyz"s); + CHECK(std::wstring(string) == L"wxyz"s); + CHECK(string.toAnsiString() == "wxyz"s); + CHECK(string.toWideString() == L"wxyz"s); + CHECK(string.toUtf8() == std::basic_string{'w', 'x', 'y', 'z'}); + CHECK(string.toUtf16() == u"wxyz"s); + CHECK(string.toUtf32() == U"wxyz"s); + CHECK(string.getSize() == 4); + CHECK(!string.isEmpty()); + CHECK(string.getData() != nullptr); + } + + SUBCASE("Insufficient input") + { + constexpr std::array characters{251}; + const sf::String string = sf::String::fromUtf8(characters.begin(), characters.end()); + constexpr char32_t defaultReplacementCharacter = 0; + CHECK(string.getSize() == 1); + CHECK(string[0] == defaultReplacementCharacter); + } } SUBCASE("fromUtf16()")