From: Jonathan Wakely Date: Thu, 18 May 2017 15:30:42 +0000 (+0100) Subject: libstdc++/78236 fix past-the-end std::regex_iterator X-Git-Tag: releases/gcc-5.5.0~355 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5298e715c4df822d31a6292b893f3f0a60c0304d;p=thirdparty%2Fgcc.git libstdc++/78236 fix past-the-end std::regex_iterator Backport from mainline 2016-11-09 Tim Shen PR libstdc++/78236 * libstdc++-v3/include/bits/regex.h (regex_iterator::regex_iterator()): Define end() as _M_pregex == nullptr. * libstdc++-v3/include/bits/regex.tcc (regex_iterator::operator==(), regex_iterator::operator++()): Fix operator==() and operator++() to look at null-ness of _M_pregex on both sides. * testsuite/28_regex/regression.cc: New testcase. From-SVN: r248230 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index da49a499f14a..7674fb7ca9f9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,16 @@ 2017-05-18 Jonathan Wakely + Backport from mainline + 2016-11-09 Tim Shen + + PR libstdc++/78236 + * libstdc++-v3/include/bits/regex.h (regex_iterator::regex_iterator()): + Define end() as _M_pregex == nullptr. + * libstdc++-v3/include/bits/regex.tcc (regex_iterator::operator==(), + regex_iterator::operator++()): Fix operator==() and operator++() to + look at null-ness of _M_pregex on both sides. + * testsuite/28_regex/regression.cc: New testcase. + Backport from mainline 2016-12-15 Jonathan Wakely diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 90723e6e2551..c3cbfd7860f6 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -2454,7 +2454,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * one-past-the-end of a range. */ regex_iterator() - : _M_match() + : _M_pregex() { } /** diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc index 823ad51c3e8b..8aec031a6d30 100644 --- a/libstdc++-v3/include/bits/regex.tcc +++ b/libstdc++-v3/include/bits/regex.tcc @@ -509,12 +509,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: operator==(const regex_iterator& __rhs) const { - return (_M_match.empty() && __rhs._M_match.empty()) - || (_M_begin == __rhs._M_begin - && _M_end == __rhs._M_end - && _M_pregex == __rhs._M_pregex - && _M_flags == __rhs._M_flags - && _M_match[0] == __rhs._M_match[0]); + if (_M_pregex == nullptr && __rhs._M_pregex == nullptr) + return true; + return _M_pregex == __rhs._M_pregex + && _M_begin == __rhs._M_begin + && _M_end == __rhs._M_end + && _M_flags == __rhs._M_flags + && _M_match[0] == __rhs._M_match[0]; } template r("(f+)"); + { + std::cregex_iterator i(s, s+sizeof(s), r); + std::cregex_iterator j(s, s+sizeof(s), r); + VERIFY(i == j); + } + // The iterator manipulation code must be repeated in the same scope + // to expose the undefined read during the execution of the == + // operator (stack location reuse) + { + std::cregex_iterator i(s, s+sizeof(s), r); + std::cregex_iterator j; + VERIFY(!(i == j)); + } +} + int main() { test01(); test02(); + test06(); return 0; }