[clang-tools-extra] f393e1f - [clangd] Fix UB in scanPreamble
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 24 01:44:26 PST 2023
Author: Kadir Cetinkaya
Date: 2023-02-24T10:43:12+01:00
New Revision: f393e1f6b3b42e8f355e64e2fb479c571ab939bc
URL: https://github.com/llvm/llvm-project/commit/f393e1f6b3b42e8f355e64e2fb479c571ab939bc
DIFF: https://github.com/llvm/llvm-project/commit/f393e1f6b3b42e8f355e64e2fb479c571ab939bc.diff
LOG: [clangd] Fix UB in scanPreamble
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.
Differential Revision: https://reviews.llvm.org/D144708
Added:
Modified:
clang-tools-extra/clangd/Preamble.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index e97564497954..f50597f9ad20 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -332,6 +332,8 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) {
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;
@@ -345,8 +347,8 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) {
// twice. However, it's important to precisely follow the preamble bounds used
// elsewhere.
auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0);
- auto PreambleContents =
- llvm::MemoryBuffer::getMemBufferCopy(Contents.substr(0, Bounds.Size));
+ auto PreambleContents = llvm::MemoryBuffer::getMemBufferCopy(
+ llvm::StringRef(PI.Contents).take_front(Bounds.Size));
auto Clang = prepareCompilerInstance(
std::move(CI), nullptr, std::move(PreambleContents),
// Provide an empty FS to prevent preprocessor from performing IO. This
@@ -739,9 +741,8 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName,
// 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());
More information about the cfe-commits
mailing list