This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix regex_iterator end() state and operator==()


This fixes libstdc++/78236. I'm surprised that this bug was not
revealed until now :P.

Bootstrapped and tested under x86_64-linux-gnu.

I'm happy with however many backports.

-- 
Regards,
Tim Shen
commit 8aee66b743b5b0ef09cbc9587ebbacf6665ba0cb
Author: Tim Shen <timshen@google.com>
Date:   Mon Nov 7 21:50:49 2016 -0800

    	* 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.

diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index a7d45e6..aadf312 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 4a3d7c3..3f8969d 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -496,12 +496,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,
@@ -525,7 +526,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    {
 	      if (__start == _M_end)
 		{
-		  _M_match = value_type();
+		  _M_pregex = nullptr;
 		  return *this;
 		}
 	      else
@@ -558,7 +559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      _M_match._M_begin = _M_begin;
 	    }
 	  else
-	    _M_match = value_type();
+	    _M_pregex = nullptr;
 	}
       return *this;
     }
diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc
index effb356..5214fe3 100644
--- a/libstdc++-v3/testsuite/28_regex/regression.cc
+++ b/libstdc++-v3/testsuite/28_regex/regression.cc
@@ -72,6 +72,27 @@ test05()
   VERIFY(regex_match_debug("-", std::regex("[a-]")));
 }
 
+// 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()
 {
@@ -80,6 +101,7 @@ main()
   test03();
   test04();
   test05();
+  test06();
   return 0;
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]