[libcxx-commits] [libcxx] 27c4eaa - [libc++] Validate the entire regex is consumed

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sat Nov 9 08:03:10 PST 2019


Author: Mark de Wever
Date: 2019-11-09T17:01:37+01:00
New Revision: 27c4eaac8c066eb1f7c5ad26c6fbc3e78eded778

URL: https://github.com/llvm/llvm-project/commit/27c4eaac8c066eb1f7c5ad26c6fbc3e78eded778
DIFF: https://github.com/llvm/llvm-project/commit/27c4eaac8c066eb1f7c5ad26c6fbc3e78eded778.diff

LOG: [libc++] Validate the entire regex is consumed

This change would have warned about the bug found in D62451.
No unit tests since the exception should never throw.

Differential Revision: https://reviews.llvm.org/D62452

Added: 
    

Modified: 
    libcxx/include/regex
    libcxx/src/regex.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/regex b/libcxx/include/regex
index d13f9addb70a..d6f5585bb923 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -965,7 +965,8 @@ enum error_type
     error_stack,
     __re_err_grammar,
     __re_err_empty,
-    __re_err_unknown
+    __re_err_unknown,
+    __re_err_parse
 };
 
 }  // regex_constants
@@ -2539,8 +2540,7 @@ public:
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
         {
-        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
-        __parse(__p, __p + __traits_.length(__p));
+        __init(__p, __p + __traits_.length(__p));
         }
 
     _LIBCPP_INLINE_VISIBILITY
@@ -2548,8 +2548,7 @@ public:
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
         {
-        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
-        __parse(__p, __p + __len);
+        __init(__p, __p + __len);
         }
 
 //     basic_regex(const basic_regex&) = default;
@@ -2561,8 +2560,7 @@ public:
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
         {
-        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
-        __parse(__p.begin(), __p.end());
+        __init(__p.begin(), __p.end());
         }
 
     template <class _ForwardIterator>
@@ -2572,8 +2570,7 @@ public:
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
         {
-        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
-        __parse(__first, __last);
+        __init(__first, __last);
         }
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
@@ -2582,8 +2579,7 @@ public:
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
         {
-        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
-        __parse(__il.begin(), __il.end());
+        __init(__il.begin(), __il.end());
         }
 #endif  // _LIBCPP_CXX03_LANG
 
@@ -2698,6 +2694,9 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     unsigned __loop_count() const {return __loop_count_;}
 
+    template <class _ForwardIterator>
+        void
+        __init(_ForwardIterator __first, _ForwardIterator __last);
     template <class _ForwardIterator>
         _ForwardIterator
         __parse(_ForwardIterator __first, _ForwardIterator __last);
@@ -3054,6 +3053,17 @@ __lookahead<_CharT, _Traits>::__exec(__state& __s) const
     }
 }
 
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+void
+basic_regex<_CharT, _Traits>::__init(_ForwardIterator __first, _ForwardIterator __last)
+{
+    if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
+    _ForwardIterator __temp = __parse(__first, __last);
+    if ( __temp != __last)
+        __throw_regex_error<regex_constants::__re_err_parse>();
+}
+
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator

diff  --git a/libcxx/src/regex.cpp b/libcxx/src/regex.cpp
index a971f646459b..d31e49487432 100644
--- a/libcxx/src/regex.cpp
+++ b/libcxx/src/regex.cpp
@@ -53,6 +53,8 @@ make_error_type_string(regex_constants::error_type ecode)
         return "An invalid regex grammar has been requested.";
     case regex_constants::__re_err_empty:
         return "An empty regex is not allowed in the POSIX grammar.";
+    case regex_constants::__re_err_parse:
+        return "The parser did not consume the entire regular expression.";
     default:
         break;
     }


        


More information about the libcxx-commits mailing list