r220614 - Lex: Fix an invalid access into a SmallString

David Majnemer david.majnemer at gmail.com
Sat Oct 25 04:40:41 PDT 2014


Author: majnemer
Date: Sat Oct 25 06:40:40 2014
New Revision: 220614

URL: http://llvm.org/viewvc/llvm-project?rev=220614&view=rev
Log:
Lex: Fix an invalid access into a SmallString

We would crash because we used operator[] to access past the end of a
SmallString.  This occured because our token had length zero.

Instead, form the pointer using .data() and arithmetic.  This is safe
because this forms a one-past-the-end pointer and it is only used to
compare with another one-past-the-end pointer.

This fixes PR21379.

Modified:
    cfe/trunk/lib/Lex/MacroArgs.cpp
    cfe/trunk/lib/Lex/TokenLexer.cpp
    cfe/trunk/test/Preprocessor/macro_paste_bad.c

Modified: cfe/trunk/lib/Lex/MacroArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroArgs.cpp?rev=220614&r1=220613&r2=220614&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/MacroArgs.cpp (original)
+++ cfe/trunk/lib/Lex/MacroArgs.cpp Sat Oct 25 06:40:40 2014
@@ -233,14 +233,14 @@ Token MacroArgs::StringifyArgument(const
       // in place and avoid copies where possible.
       unsigned CurStrLen = Result.size();
       Result.resize(CurStrLen+Tok.getLength());
-      const char *BufPtr = &Result[CurStrLen];
+      const char *BufPtr = Result.data() + CurStrLen;
       bool Invalid = false;
       unsigned ActualTokLen = PP.getSpelling(Tok, BufPtr, &Invalid);
 
       if (!Invalid) {
         // If getSpelling returned a pointer to an already uniqued version of
         // the string instead of filling in BufPtr, memcpy it onto our string.
-        if (BufPtr != &Result[CurStrLen])
+        if (ActualTokLen && BufPtr != &Result[CurStrLen])
           memcpy(&Result[CurStrLen], BufPtr, ActualTokLen);
 
         // If the token was dirty, the spelling may be shorter than the token.

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=220614&r1=220613&r2=220614&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Sat Oct 25 06:40:40 2014
@@ -531,12 +531,13 @@ bool TokenLexer::PasteTokens(Token &Tok)
       memcpy(&Buffer[0], BufPtr, LHSLen);
     if (Invalid)
       return true;
-    
-    BufPtr = &Buffer[LHSLen];
+
+    BufPtr = Buffer.data() + LHSLen;
     unsigned RHSLen = PP.getSpelling(RHS, BufPtr, &Invalid);
     if (Invalid)
       return true;
-    if (BufPtr != &Buffer[LHSLen])   // Really, we want the chars in Buffer!
+    if (RHSLen && BufPtr != &Buffer[LHSLen])
+      // Really, we want the chars in Buffer!
       memcpy(&Buffer[LHSLen], BufPtr, RHSLen);
 
     // Trim excess space.

Modified: cfe/trunk/test/Preprocessor/macro_paste_bad.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/macro_paste_bad.c?rev=220614&r1=220613&r2=220614&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/macro_paste_bad.c (original)
+++ cfe/trunk/test/Preprocessor/macro_paste_bad.c Sat Oct 25 06:40:40 2014
@@ -34,3 +34,11 @@ int VA;   // expected-warning {{__VA_ARG
 
 #define LOG_ON_ERROR(x) x ## #y; // expected-error {{'#' is not followed by a macro parameter}}
 LOG_ON_ERROR(0);
+
+#define PR21379A(x) printf ##x // expected-note {{macro 'PR21379A' defined here}}
+PR21379A(0 {, }) // expected-error {{too many arguments provided to function-like macro invocation}}
+                 // expected-note at -1 {{parentheses are required around macro argument containing braced initializer list}}
+
+#define PR21379B(x) printf #x // expected-note {{macro 'PR21379B' defined here}}
+PR21379B(0 {, }) // expected-error {{too many arguments provided to function-like macro invocation}}
+                 // expected-note at -1 {{parentheses are required around macro argument containing braced initializer list}}





More information about the cfe-commits mailing list