]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++/78236 fix past-the-end std::regex_iterator
authorJonathan Wakely <jwakely@redhat.com>
Thu, 18 May 2017 15:30:42 +0000 (16:30 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 18 May 2017 15:30:42 +0000 (16:30 +0100)
Backport from mainline
2016-11-09  Tim Shen  <timshen@google.com>

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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/regex.h
libstdc++-v3/include/bits/regex.tcc
libstdc++-v3/testsuite/28_regex/regression.cc

index da49a499f14aa4e914f3a11b40d523c4e5ad66db..7674fb7ca9f96e5d6a79101e4ebc45ebd4b96682 100644 (file)
@@ -1,5 +1,16 @@
 2017-05-18  Jonathan Wakely  <jwakely@redhat.com>
 
+       Backport from mainline
+       2016-11-09  Tim Shen  <timshen@google.com>
+
+       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  <jwakely@redhat.com>
 
index 90723e6e25518eb755588e2a93d82ef50f0c8277..c3cbfd7860f6cfc7b7b901917ccd5a2985a0eb34 100644 (file)
@@ -2454,7 +2454,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        * one-past-the-end of a range.
        */
       regex_iterator()
-      : _M_match()
+      : _M_pregex()
       { }
 
       /**
index 823ad51c3e8b9139cdb339b070ab7690b0571228..8aec031a6d3048414ec6978b85bc926f02d9e65d 100644 (file)
@@ -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<typename _Bi_iter,
@@ -538,7 +539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            {
              if (__start == _M_end)
                {
-                 _M_match = value_type();
+                 _M_pregex = nullptr;
                  return *this;
                }
              else
@@ -571,7 +572,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              _M_match._M_begin = _M_begin;
            }
          else
-           _M_match = value_type();
+           _M_pregex = nullptr;
        }
       return *this;
     }
index 660d17070e6016680c956cc80e0c011ee9d8ae72..0747cfcce78d6a76d8d24846cfec62656f626e5b 100644 (file)
@@ -48,11 +48,33 @@ test02()
   VERIFY(std::regex_search("/abcd", rx));
 }
 
+// PR libstdc++/78236
+void
+test06()
+{
+  char const s[] = "afoo";
+  std::basic_regex<char> 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;
 }