]> granicus.if.org Git - clang/commitdiff
PR23057: fix use-after-free due to local token buffer in ParseCXXAmbiguousParenExpres...
authorAlexey Bataev <a.bataev@hotmail.com>
Thu, 4 Feb 2016 04:22:09 +0000 (04:22 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Thu, 4 Feb 2016 04:22:09 +0000 (04:22 +0000)
Differential Revision: http://reviews.llvm.org/D16572
A    test/Parser/cxx-ambig-paren-expr-asan.cpp
M    lib/Parse/ParseExprCXX.cpp

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

lib/Parse/ParseExprCXX.cpp
test/Parser/cxx-ambig-paren-expr-asan.cpp [new file with mode: 0644]

index 53009caf8c7946f8229e077cadfc7dbcf82401c7..760c30b81249b20f4faf32904d658606e2adb52a 100644 (file)
@@ -3081,6 +3081,14 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
     ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
   }
 
+  // Create a fake EOF to mark end of Toks buffer.
+  Token AttrEnd;
+  AttrEnd.startToken();
+  AttrEnd.setKind(tok::eof);
+  AttrEnd.setLocation(Tok.getLocation());
+  AttrEnd.setEofData(Toks.data());
+  Toks.push_back(AttrEnd);
+
   // The current token should go after the cached tokens.
   Toks.push_back(Tok);
   // Re-enter the stored parenthesized tokens into the token stream, so we may
@@ -3105,6 +3113,10 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
     Tracker.consumeClose();
     ColonProt.restore();
 
+    // Consume EOF marker for Toks buffer.
+    assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData());
+    ConsumeAnyToken();
+
     if (ParseAs == CompoundLiteral) {
       ExprType = CompoundLiteral;
       if (DeclaratorInfo.isInvalidType())
@@ -3141,10 +3153,16 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
 
   // Match the ')'.
   if (Result.isInvalid()) {
-    SkipUntil(tok::r_paren, StopAtSemi);
+    while (Tok.isNot(tok::eof))
+      ConsumeAnyToken();
+    assert(Tok.getEofData() == AttrEnd.getEofData());
+    ConsumeAnyToken();
     return ExprError();
   }
 
   Tracker.consumeClose();
+  // Consume EOF marker for Toks buffer.
+  assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData());
+  ConsumeAnyToken();
   return Result;
 }
diff --git a/test/Parser/cxx-ambig-paren-expr-asan.cpp b/test/Parser/cxx-ambig-paren-expr-asan.cpp
new file mode 100644 (file)
index 0000000..ec9d6b9
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+// This syntax error used to cause use-after free due to token local buffer
+// in ParseCXXAmbiguousParenExpression.
+int H((int()[)]);
+// expected-error@-1 {{expected expression}}
+// expected-error@-2 {{expected ']'}}
+// expected-note@-3 {{to match this '['}}
+// expected-error@-4 {{expected ';' after top level declarator}}