Skip to content

Commit

Permalink
[libc++] Validate the entire regex is consumed
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mordante committed Nov 9, 2019
1 parent b9be5ce commit 27c4eaa
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
32 changes: 21 additions & 11 deletions libcxx/include/regex
Expand Up @@ -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
Expand Down Expand Up @@ -2539,17 +2540,15 @@ 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
basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
: __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;
Expand All @@ -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>
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions libcxx/src/regex.cpp
Expand Up @@ -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;
}
Expand Down

0 comments on commit 27c4eaa

Please sign in to comment.