Commit 27c4eaac authored by Mark de Wever's avatar Mark de Wever
Browse files

[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
parent b9be5ce8
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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;
    }