]> granicus.if.org Git - clang/commitdiff
Don't crash w/ a diagnostic range containing a null byte
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 17 Feb 2016 22:37:45 +0000 (22:37 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 17 Feb 2016 22:37:45 +0000 (22:37 +0000)
We prematurely ended the line at the null byte which caused us to crash
down stream because we tried to reason about columns beyond the end of
the line.

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

lib/Frontend/TextDiagnostic.cpp
test/Misc/diag-null-bytes-in-line.cpp [new file with mode: 0644]

index d4e156d44582ff0bb0839548a9b2627b3cbac0dd..5dda151d5581d79ea00b119ff46e6070fe6c75a3 100644 (file)
@@ -1082,10 +1082,13 @@ void TextDiagnostic::emitSnippetAndCaret(
 
   // Get information about the buffer it points into.
   bool Invalid = false;
-  const char *BufStart = SM.getBufferData(FID, &Invalid).data();
+  StringRef BufData = SM.getBufferData(FID, &Invalid);
   if (Invalid)
     return;
 
+  const char *BufStart = BufData.data();
+  const char *BufEnd = BufStart + BufData.size();
+
   unsigned LineNo = SM.getLineNumber(FID, FileOffset);
   unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
   
@@ -1101,15 +1104,20 @@ void TextDiagnostic::emitSnippetAndCaret(
   // Compute the line end.  Scan forward from the error position to the end of
   // the line.
   const char *LineEnd = TokPtr;
-  while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0')
+  while (*LineEnd != '\n' && *LineEnd != '\r' && LineEnd != BufEnd)
     ++LineEnd;
 
   // Arbitrarily stop showing snippets when the line is too long.
   if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint)
     return;
 
+  // Trim trailing null-bytes.
+  StringRef Line(LineStart, LineEnd - LineStart);
+  while (Line.size() > ColNo && Line.back() == '\0')
+    Line = Line.drop_back();
+
   // Copy the line of code into an std::string for ease of manipulation.
-  std::string SourceLine(LineStart, LineEnd);
+  std::string SourceLine(Line.begin(), Line.end());
 
   // Build the byte to column map.
   const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop);
diff --git a/test/Misc/diag-null-bytes-in-line.cpp b/test/Misc/diag-null-bytes-in-line.cpp
new file mode 100644 (file)
index 0000000..1eba91f
Binary files /dev/null and b/test/Misc/diag-null-bytes-in-line.cpp differ