[Lexer] Don't read out of bounds if a conflict marker is at the end of a file
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 1 Apr 2016 09:58:45 +0000 (09:58 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 1 Apr 2016 09:58:45 +0000 (09:58 +0000)
This can happen as we look for '<<<<' while scanning tokens but then expect
'<<<<\n' to tell apart perforce from diff3 conflict markers. Just harden
the pointer arithmetic.

Found by libfuzzer + asan!

llvm-svn: 265125

clang/lib/Lex/Lexer.cpp
clang/test/Lexer/eof-conflict-marker.c [new file with mode: 0644]

index 52146d7..946f36f 100644 (file)
@@ -2610,7 +2610,7 @@ static const char *FindConflictEnd(const char *CurPtr, const char *BufferEnd,
                                    ConflictMarkerKind CMK) {
   const char *Terminator = CMK == CMK_Perforce ? "<<<<\n" : ">>>>>>>";
   size_t TermLen = CMK == CMK_Perforce ? 5 : 7;
-  StringRef RestOfBuffer(CurPtr+TermLen, BufferEnd-CurPtr-TermLen);
+  auto RestOfBuffer = StringRef(CurPtr, BufferEnd - CurPtr).substr(TermLen);
   size_t Pos = RestOfBuffer.find(Terminator);
   while (Pos != StringRef::npos) {
     // Must occur at start of line.
diff --git a/clang/test/Lexer/eof-conflict-marker.c b/clang/test/Lexer/eof-conflict-marker.c
new file mode 100644 (file)
index 0000000..e0c3540
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// vim: set binary noeol:
+
+// This file intentionally ends without a \n on the last line.  Make sure your
+// editor doesn't add one.
+
+>>>> ORIGINAL
+// expected-error@-1 {{version control conflict marker in file}}
+<<<<
+// expected-error@-1 {{expected identifier or '('}}
+<<<<
\ No newline at end of file