[PATCH] libstdc++: Fix reverse iteration in _Utf16_view
Tomasz Kaminski
tkaminsk@redhat.com
Mon Oct 13 09:18:30 GMT 2025
On Sat, Oct 11, 2025 at 1:40 AM Jonathan Wakely <jwakely@redhat.com> wrote:
> When iterating over a range of char16_t in reverse the _Utf_view was
> incorrectly treating U+DC00 as a valid high surrogate that can precede
> the low surrogate. But U+DC00 is a low surrogate, and so should not be
> allowed before another low surrogate. The check should be u2 >= 0xDC00
> rather than u2 > 0xDC00.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/unicode.h (_Utf_view::_M_read_reverse_utf16):
> Fix check for high surrogate preceding low surrogate.
> * testsuite/ext/unicode/view.cc: Check unpaired low surrogates.
> ---
>
> Tested x86_64-linux.
>
LGTM. Nice catch.
>
> libstdc++-v3/include/bits/unicode.h | 2 +-
> libstdc++-v3/testsuite/ext/unicode/view.cc | 5 +++++
> 2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/bits/unicode.h
> b/libstdc++-v3/include/bits/unicode.h
> index 00efbe89ca8e..44872db4ed68 100644
> --- a/libstdc++-v3/include/bits/unicode.h
> +++ b/libstdc++-v3/include/bits/unicode.h
> @@ -527,7 +527,7 @@ namespace __unicode
> {
> // read a low surrogate, expect a high surrogate before it.
> uint16_t __u2 = *--_M_curr();
> - if (__u2 < 0xD800 || __u2 > 0xDC00) [[unlikely]]
> + if (__u2 < 0xD800 || __u2 >= 0xDC00) [[unlikely]]
> __c = _S_error(); // unpaired low surrogate
> else
> {
> diff --git a/libstdc++-v3/testsuite/ext/unicode/view.cc
> b/libstdc++-v3/testsuite/ext/unicode/view.cc
> index 4ccf646e0945..40c8fcf34fb7 100644
> --- a/libstdc++-v3/testsuite/ext/unicode/view.cc
> +++ b/libstdc++-v3/testsuite/ext/unicode/view.cc
> @@ -94,6 +94,11 @@ test_illformed_utf16()
> compare(uc::_Utf16_view(s4), u"\uFFFD\uFFFD"sv);
> std::array s5{ s[1], s[0], s[1] };
> compare(uc::_Utf16_view(s5), u"\uFFFD\N{CLOWN FACE}"sv);
> +
> + std::array<char16_t, 2> s6{ 0xDC00, 0xDC01 };
> + compare(uc::_Utf16_view(s6), u"\uFFFD\uFFFD"sv);
> + std::array<char16_t, 2> s7{ 0xD7FF, 0xDC00 };
> + compare(uc::_Utf16_view(s7), u"\uD7FF\uFFFD"sv);
> }
>
> constexpr void
> --
> 2.51.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20251013/ad30a1d0/attachment.htm>
More information about the Libstdc++
mailing list