diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-04 17:19:55 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-04 17:19:55 +0000 |
commit | 36e549211c43f8bb653897505be3cd6e75bc461b (patch) | |
tree | 51d24fd829c29cb8633b241a2c12b9fdd9596f15 /libstdc++-v3/include/bits | |
parent | 79bac32ec3283a9a73faeec11b8d905e4cf1445a (diff) | |
download | gcc-36e549211c43f8bb653897505be3cd6e75bc461b.tar.gz |
PR libstdc++/64797
* include/bits/locale_conv.h (wstring_convert::_M_conv): Handle
incomplete multibyte sequences correctly.
* include/std/codecvt (codecvt_utf8, codecvt_utf16,
codecvt_utf8_utf16): Limit _Maxcode to maximum Unicode code point.
* src/c++11/codecvt.cc (invalid_mb_sequence, incomplete_mb_character):
Define constants.
(is_high_surrogate, is_low_surrogate, surrogate_pair_to_code_point):
Define convenience functions.
(read_utf8_code_point): Return relevant constant to distinguish
incomplete characters from invalid sequences.
(read_utf16_code_point): Likewise. Check for invalid sequences.
(ucs4_in, utf16_in): Use incomplete_mb_character constant.
(utf16_out): Check for invalid sequences.
(utf16_span): Fix condition.
(ucs2_out): Use is_high_surrogate.
(ucs2_in): Use incomplete_mb_character constant and fix condition.
* testsuite/22_locale/codecvt/char16_t.cc: Fix whitespace.
* testsuite/22_locale/conversions/buffer/1.cc: New.
* testsuite/22_locale/conversions/string/2.cc: Use char16_t and
char32_t instead of wchar_t.
* testsuite/22_locale/conversions/string/3.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221189 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/bits')
-rw-r--r-- | libstdc++-v3/include/bits/locale_conv.h | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h index c8a44f42421..b53754d1541 100644 --- a/libstdc++-v3/include/bits/locale_conv.h +++ b/libstdc++-v3/include/bits/locale_conv.h @@ -198,18 +198,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __outstr = __err ? _OutStr(__err->get_allocator()) : _OutStr(); size_t __outchars = 0; auto __next = __first; + const auto __maxlen = _M_cvt->max_length(); codecvt_base::result __result; do { - __outstr.resize(__outstr.size() + (__last - __next)); + __outstr.resize(__outstr.size() + (__last - __next) + __maxlen); auto __outnext = &__outstr.front() + __outchars; auto const __outlast = &__outstr.back() + 1; __result = ((*_M_cvt).*__memfn)(_M_state, __next, __last, __next, __outnext, __outlast, __outnext); __outchars = __outnext - &__outstr.front(); } - while (__result == codecvt_base::partial && __next != __last); + while (__result == codecvt_base::partial && __next != __last + && (__outstr.size() - __outchars) < __maxlen); __outstr.resize(__outchars); _M_count = __next - __first; @@ -428,7 +430,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _M_put(__next, __pending); if (!_M_put(__outbuf, __outnext - __outbuf)) - return false; + return false; } while (__next != __last && __next != __start); |