From 1e1d05121d63b0156cef8e85f51ff448bc66a7db Mon Sep 17 00:00:00 2001
From: Howard Hinnant <hhinnant@apple.com>
Date: Mon, 15 Jul 2013 18:21:11 +0000
Subject: [PATCH] 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
---
 include/regex                                 | 11 +++++-
 .../re.regex.construct/bad_escape.pass.cpp    | 36 +++++++++++--------
 2 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/include/regex b/include/regex
index 19e08b13..3ec2ff92 100644
--- a/include/regex
+++ b/include/regex
@@ -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;
diff --git a/test/re/re.regex/re.regex.construct/bad_escape.pass.cpp b/test/re/re.regex/re.regex.construct/bad_escape.pass.cpp
index 75845a23..94555274 100644
--- a/test/re/re.regex/re.regex.construct/bad_escape.pass.cpp
+++ b/test/re/re.regex/re.regex.construct/bad_escape.pass.cpp
@@ -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);
-    }
 }