Detect and throw on a class of bad regexes that we mistakenly accepted before. Thanks to Trevor Smigiel for the report

llvm-svn: 243030
This commit is contained in:
Marshall Clow 2015-07-23 18:27:51 +00:00
parent 3f07e7b063
commit 983d178108
3 changed files with 51 additions and 1 deletions

View File

@ -4305,6 +4305,14 @@ basic_regex<_CharT, _Traits>::__parse_atom(_ForwardIterator __first,
}
}
break;
case '*':
case '+':
case '?':
case '{':
#ifndef _LIBCPP_NO_EXCEPTIONS
throw regex_error(regex_constants::error_badrepeat);
#endif
break;
default:
__first = __parse_pattern_character(__first, __last);
break;

View File

@ -22,7 +22,7 @@ static bool error_escape_thrown(const char *pat)
bool result = false;
try {
std::regex re(pat);
} catch (std::regex_error &ex) {
} catch (const std::regex_error &ex) {
result = (ex.code() == std::regex_constants::error_escape);
}
return result;

View File

@ -0,0 +1,42 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <regex>
// template <class charT, class traits = regex_traits<charT>> class basic_regex;
// template <class ST, class SA>
// basic_regex(const basic_string<charT, ST, SA>& s);
#include <regex>
#include <cassert>
static bool error_badrepeat_thrown(const char *pat)
{
bool result = false;
try {
std::regex re(pat);
} catch (const std::regex_error &ex) {
result = (ex.code() == std::regex_constants::error_badrepeat);
}
return result;
}
int main()
{
assert(error_badrepeat_thrown("?a"));
assert(error_badrepeat_thrown("*a"));
assert(error_badrepeat_thrown("+a"));
assert(error_badrepeat_thrown("{a"));
assert(error_badrepeat_thrown("?(a+)"));
assert(error_badrepeat_thrown("*(a+)"));
assert(error_badrepeat_thrown("+(a+)"));
assert(error_badrepeat_thrown("{(a+)"));
}