Skip to content

Commit 27c4eaa

Browse files
committed
[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
1 parent b9be5ce commit 27c4eaa

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

libcxx/include/regex

+21-11
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,8 @@ enum error_type
965965
error_stack,
966966
__re_err_grammar,
967967
__re_err_empty,
968-
__re_err_unknown
968+
__re_err_unknown,
969+
__re_err_parse
969970
};
970971

971972
} // regex_constants
@@ -2539,17 +2540,15 @@ public:
25392540
: __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
25402541
__end_(0)
25412542
{
2542-
if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
2543-
__parse(__p, __p + __traits_.length(__p));
2543+
__init(__p, __p + __traits_.length(__p));
25442544
}
25452545

25462546
_LIBCPP_INLINE_VISIBILITY
25472547
basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
25482548
: __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
25492549
__end_(0)
25502550
{
2551-
if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
2552-
__parse(__p, __p + __len);
2551+
__init(__p, __p + __len);
25532552
}
25542553

25552554
// basic_regex(const basic_regex&) = default;
@@ -2561,8 +2560,7 @@ public:
25612560
: __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
25622561
__end_(0)
25632562
{
2564-
if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
2565-
__parse(__p.begin(), __p.end());
2563+
__init(__p.begin(), __p.end());
25662564
}
25672565

25682566
template <class _ForwardIterator>
@@ -2572,8 +2570,7 @@ public:
25722570
: __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
25732571
__end_(0)
25742572
{
2575-
if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
2576-
__parse(__first, __last);
2573+
__init(__first, __last);
25772574
}
25782575
#ifndef _LIBCPP_CXX03_LANG
25792576
_LIBCPP_INLINE_VISIBILITY
@@ -2582,8 +2579,7 @@ public:
25822579
: __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
25832580
__end_(0)
25842581
{
2585-
if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
2586-
__parse(__il.begin(), __il.end());
2582+
__init(__il.begin(), __il.end());
25872583
}
25882584
#endif // _LIBCPP_CXX03_LANG
25892585

@@ -2698,6 +2694,9 @@ private:
26982694
_LIBCPP_INLINE_VISIBILITY
26992695
unsigned __loop_count() const {return __loop_count_;}
27002696

2697+
template <class _ForwardIterator>
2698+
void
2699+
__init(_ForwardIterator __first, _ForwardIterator __last);
27012700
template <class _ForwardIterator>
27022701
_ForwardIterator
27032702
__parse(_ForwardIterator __first, _ForwardIterator __last);
@@ -3054,6 +3053,17 @@ __lookahead<_CharT, _Traits>::__exec(__state& __s) const
30543053
}
30553054
}
30563055

3056+
template <class _CharT, class _Traits>
3057+
template <class _ForwardIterator>
3058+
void
3059+
basic_regex<_CharT, _Traits>::__init(_ForwardIterator __first, _ForwardIterator __last)
3060+
{
3061+
if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
3062+
_ForwardIterator __temp = __parse(__first, __last);
3063+
if ( __temp != __last)
3064+
__throw_regex_error<regex_constants::__re_err_parse>();
3065+
}
3066+
30573067
template <class _CharT, class _Traits>
30583068
template <class _ForwardIterator>
30593069
_ForwardIterator

libcxx/src/regex.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ make_error_type_string(regex_constants::error_type ecode)
5353
return "An invalid regex grammar has been requested.";
5454
case regex_constants::__re_err_empty:
5555
return "An empty regex is not allowed in the POSIX grammar.";
56+
case regex_constants::__re_err_parse:
57+
return "The parser did not consume the entire regular expression.";
5658
default:
5759
break;
5860
}

0 commit comments

Comments
 (0)