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:
		@@ -4418,7 +4418,8 @@ basic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first,
 | 
			
		||||
        case 'c':
 | 
			
		||||
            if ((__t = _VSTD::next(__first)) != __last)
 | 
			
		||||
            {
 | 
			
		||||
                if ('A' <= *__t <= 'Z' || 'a' <= *__t <= 'z')
 | 
			
		||||
                if (('A' <= *__t && *__t <= 'Z') || 
 | 
			
		||||
                    ('a' <= *__t && *__t <= 'z'))
 | 
			
		||||
                {
 | 
			
		||||
                    if (__str)
 | 
			
		||||
                        *__str = _CharT(*__t % 32);
 | 
			
		||||
@@ -4426,7 +4427,15 @@ basic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first,
 | 
			
		||||
                        __push_char(_CharT(*__t % 32));
 | 
			
		||||
                    __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;
 | 
			
		||||
        case 'u':
 | 
			
		||||
            ++__first;
 | 
			
		||||
 
 | 
			
		||||
@@ -17,21 +17,29 @@
 | 
			
		||||
#include <regex>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
static bool error_escape_thrown(const char *pat) 
 | 
			
		||||
{
 | 
			
		||||
    bool result = false;
 | 
			
		||||
    try {
 | 
			
		||||
        std::regex re(pat);
 | 
			
		||||
    } catch (std::regex_error &ex) {
 | 
			
		||||
        result = (ex.code() == std::regex_constants::error_escape);
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main() 
 | 
			
		||||
{
 | 
			
		||||
    // Correct: Exception thrown for invalid escape char in a character class
 | 
			
		||||
    try {
 | 
			
		||||
        std::regex char_class_escape("[\\a]");
 | 
			
		||||
        assert(false);
 | 
			
		||||
    } catch (std::regex_error &ex) {
 | 
			
		||||
        assert(ex.code() == std::regex_constants::error_escape);
 | 
			
		||||
    }
 | 
			
		||||
    assert(error_escape_thrown("[\\a]"));
 | 
			
		||||
    assert(error_escape_thrown("\\a"));
 | 
			
		||||
 | 
			
		||||
    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"));
 | 
			
		||||
 | 
			
		||||
    // Failure: No exception thrown for invalid escape char in this case.
 | 
			
		||||
    try {
 | 
			
		||||
        std::regex escape("\\a");
 | 
			
		||||
        assert(false);
 | 
			
		||||
    } catch (std::regex_error &ex) {
 | 
			
		||||
        assert(ex.code() == std::regex_constants::error_escape);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user