]> granicus.if.org Git - clang/commitdiff
PR17359: Fix off-by-one OOB on _Pragma("") and an unescaping bug
authorReid Kleckner <reid@kleckner.net>
Wed, 25 Sep 2013 16:42:48 +0000 (16:42 +0000)
committerReid Kleckner <reid@kleckner.net>
Wed, 25 Sep 2013 16:42:48 +0000 (16:42 +0000)
Previously the code would reduce a run of backslashes to a single
backslash, and now it will properly leave behind every other backslash.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191382 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/Pragma.cpp
test/Preprocessor/_Pragma.c

index 8d3dedc37520d442a87ccf46d01bfd667e644a6d..4c6d889bf3314a8a244600b739077bdcde608c37 100644 (file)
@@ -263,14 +263,14 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
 
     // Remove escaped quotes and escapes.
     unsigned ResultPos = 1;
-    for (unsigned i = 1, e = StrVal.size() - 2; i != e; ++i) {
-      if (StrVal[i] != '\\' ||
-          (StrVal[i + 1] != '\\' && StrVal[i + 1] != '"')) {
-        // \\ -> '\' and \" -> '"'.
-        StrVal[ResultPos++] = StrVal[i];
-      }
+    for (unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
+      // Skip escapes.  \\ -> '\' and \" -> '"'.
+      if (StrVal[i] == '\\' && i + 1 < e &&
+          (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
+        ++i;
+      StrVal[ResultPos++] = StrVal[i];
     }
-    StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 2);
+    StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
   }
 
   // Remove the front quote, replacing it with a space, so that the pragma
index 0a83b149ff75d28b7f2a72b4ed169b4f69826b79..15725a422299fe2caf0993fa3192b99ef86ba00d 100644 (file)
@@ -5,6 +5,9 @@ _Pragma ("GCC system_header")  // expected-warning {{system_header ignored in ma
 // rdar://6880630
 _Pragma("#define macro")    // expected-warning {{unknown pragma ignored}}
 
+_Pragma("") // expected-warning {{unknown pragma ignored}}
+_Pragma("message(\"foo \\\\\\\\ bar\")") // expected-warning {{foo \\ bar}}
+
 #ifdef macro
 #error #define invalid
 #endif