Bill Fisher: This patch fixes an ill-formed comparison when parsing control escapes, e.g. "\cA\ca". The code will now throw an error_escape exception for invalid control sequences like "\c:" or "\c".

I've added the test cases to bad_escape.pass.cpp.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@186335 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant 2013-07-15 18:21:11 +00:00
parent 1f96a4df58
commit 1e1d05121d
2 changed files with 32 additions and 15 deletions

View File

@ -4418,7 +4418,8 @@ basic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first,
case 'c': case 'c':
if ((__t = _VSTD::next(__first)) != __last) if ((__t = _VSTD::next(__first)) != __last)
{ {
if ('A' <= *__t <= 'Z' || 'a' <= *__t <= 'z') if (('A' <= *__t && *__t <= 'Z') ||
('a' <= *__t && *__t <= 'z'))
{ {
if (__str) if (__str)
*__str = _CharT(*__t % 32); *__str = _CharT(*__t % 32);
@ -4426,7 +4427,15 @@ basic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first,
__push_char(_CharT(*__t % 32)); __push_char(_CharT(*__t % 32));
__first = ++__t; __first = ++__t;
} }
#ifndef _LIBCPP_NO_EXCEPTIONS
else
throw regex_error(regex_constants::error_escape);
#endif // _LIBCPP_NO_EXCEPTIONS
} }
#ifndef _LIBCPP_NO_EXCEPTIONS
else
throw regex_error(regex_constants::error_escape);
#endif // _LIBCPP_NO_EXCEPTIONS
break; break;
case 'u': case 'u':
++__first; ++__first;

View File

@ -17,21 +17,29 @@
#include <regex> #include <regex>
#include <cassert> #include <cassert>
int main() static bool error_escape_thrown(const char *pat)
{ {
// Correct: Exception thrown for invalid escape char in a character class bool result = false;
try { try {
std::regex char_class_escape("[\\a]"); std::regex re(pat);
assert(false);
} catch (std::regex_error &ex) { } catch (std::regex_error &ex) {
assert(ex.code() == std::regex_constants::error_escape); result = (ex.code() == std::regex_constants::error_escape);
}
return result;
} }
// Failure: No exception thrown for invalid escape char in this case. int main()
try { {
std::regex escape("\\a"); assert(error_escape_thrown("[\\a]"));
assert(false); assert(error_escape_thrown("\\a"));
} catch (std::regex_error &ex) {
assert(ex.code() == std::regex_constants::error_escape); assert(error_escape_thrown("[\\e]"));
} assert(error_escape_thrown("\\e"));
assert(error_escape_thrown("[\\c:]"));
assert(error_escape_thrown("\\c:"));
assert(error_escape_thrown("\\c"));
assert(!error_escape_thrown("[\\cA]"));
assert(!error_escape_thrown("\\cA"));
} }