kadircet created this revision.
kadircet added a reviewer: hokein.
Herald added a subscriber: arphaman.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

getMemBufferCopy triggers an UB when it receives a default constructed
StringRef. Make sure that we're always passing the null-terminated string
created in ParseInputs throughout the scanPreamble.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144708

Files:
  clang-tools-extra/clangd/Preamble.cpp


Index: clang-tools-extra/clangd/Preamble.cpp
===================================================================
--- clang-tools-extra/clangd/Preamble.cpp
+++ clang-tools-extra/clangd/Preamble.cpp
@@ -332,6 +332,8 @@
   EmptyFS FS;
   // Build and run Preprocessor over the preamble.
   ParseInputs PI;
+  // Memory buffers below expect null-terminated && non-null strings. So make
+  // sure to always use PI.Contents!
   PI.Contents = Contents.str();
   PI.TFS = &FS;
   PI.CompileCommand = Cmd;
@@ -346,7 +348,7 @@
   // elsewhere.
   auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0);
   auto PreambleContents =
-      llvm::MemoryBuffer::getMemBufferCopy(Contents.substr(0, Bounds.Size));
+      llvm::MemoryBuffer::getMemBufferCopy(PI.Contents.substr(0, Bounds.Size));
   auto Clang = prepareCompilerInstance(
       std::move(CI), nullptr, std::move(PreambleContents),
       // Provide an empty FS to prevent preprocessor from performing IO. This
@@ -371,7 +373,7 @@
     return std::move(Err);
   Action.EndSourceFile();
   SP.Includes = std::move(Includes.MainFileIncludes);
-  llvm::append_range(SP.Lines, llvm::split(Contents, "\n"));
+  llvm::append_range(SP.Lines, llvm::split(PI.Contents, "\n"));
   return SP;
 }
 
@@ -739,9 +741,8 @@
   //   whole preamble, which is terribly slow.
   // - If scanning for Modified fails, cannot figure out newly added ones so
   //   there's nothing to do but generate an empty patch.
-  auto BaselineScan = scanPreamble(
-      // Contents needs to be null-terminated.
-      Baseline.Preamble.getContents(), Modified.CompileCommand);
+  auto BaselineScan =
+      scanPreamble(Baseline.Preamble.getContents(), Modified.CompileCommand);
   if (!BaselineScan) {
     elog("Failed to scan baseline of {0}: {1}", FileName,
          BaselineScan.takeError());


Index: clang-tools-extra/clangd/Preamble.cpp
===================================================================
--- clang-tools-extra/clangd/Preamble.cpp
+++ clang-tools-extra/clangd/Preamble.cpp
@@ -332,6 +332,8 @@
   EmptyFS FS;
   // Build and run Preprocessor over the preamble.
   ParseInputs PI;
+  // Memory buffers below expect null-terminated && non-null strings. So make
+  // sure to always use PI.Contents!
   PI.Contents = Contents.str();
   PI.TFS = &FS;
   PI.CompileCommand = Cmd;
@@ -346,7 +348,7 @@
   // elsewhere.
   auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0);
   auto PreambleContents =
-      llvm::MemoryBuffer::getMemBufferCopy(Contents.substr(0, Bounds.Size));
+      llvm::MemoryBuffer::getMemBufferCopy(PI.Contents.substr(0, Bounds.Size));
   auto Clang = prepareCompilerInstance(
       std::move(CI), nullptr, std::move(PreambleContents),
       // Provide an empty FS to prevent preprocessor from performing IO. This
@@ -371,7 +373,7 @@
     return std::move(Err);
   Action.EndSourceFile();
   SP.Includes = std::move(Includes.MainFileIncludes);
-  llvm::append_range(SP.Lines, llvm::split(Contents, "\n"));
+  llvm::append_range(SP.Lines, llvm::split(PI.Contents, "\n"));
   return SP;
 }
 
@@ -739,9 +741,8 @@
   //   whole preamble, which is terribly slow.
   // - If scanning for Modified fails, cannot figure out newly added ones so
   //   there's nothing to do but generate an empty patch.
-  auto BaselineScan = scanPreamble(
-      // Contents needs to be null-terminated.
-      Baseline.Preamble.getContents(), Modified.CompileCommand);
+  auto BaselineScan =
+      scanPreamble(Baseline.Preamble.getContents(), Modified.CompileCommand);
   if (!BaselineScan) {
     elog("Failed to scan baseline of {0}: {1}", FileName,
          BaselineScan.takeError());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to