Author: Dmitry Polukhin Date: 2021-06-30T01:07:47-07:00 New Revision: fceaf8621179aa758c44f3eaee02d789abfd455b
URL: https://github.com/llvm/llvm-project/commit/fceaf8621179aa758c44f3eaee02d789abfd455b DIFF: https://github.com/llvm/llvm-project/commit/fceaf8621179aa758c44f3eaee02d789abfd455b.diff LOG: [clang] Fix UB when string.front() is used for the empty string Compilation database might have empty string as a command line argument. But ExpandResponseFilesDatabase::expand doesn't expect this and assumes that string.front() can be used for any argument. It is undefined behaviour if string is empty. With debug build mode it causes crash in clangd. Test Plan: check-clang Differential Revision: https://reviews.llvm.org/D105120 Added: Modified: clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp clang/unittests/Tooling/CompilationDatabaseTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp index a825370afcf56..29787b8a88942 100644 --- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp +++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp @@ -54,7 +54,8 @@ class ExpandResponseFilesDatabase : public CompilationDatabase { Argv.reserve(Cmd.CommandLine.size()); for (auto &Arg : Cmd.CommandLine) { Argv.push_back(Arg.c_str()); - SeenRSPFile |= Arg.front() == '@'; + if (!Arg.empty()) + SeenRSPFile |= Arg.front() == '@'; } if (!SeenRSPFile) continue; diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp index 9a04de32c852d..218a352f86f06 100644 --- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -700,6 +700,10 @@ class MemDBTest : public ::testing::Test { SmallVector<StringRef, 8> Argv = {Clang, File, "-D", File}; llvm::SplitString(Flags, Argv); + // Trim double quotation from the argumnets if any. + for (auto *It = Argv.begin(); It != Argv.end(); ++It) + *It = It->trim("\""); + SmallString<32> Dir; llvm::sys::path::system_temp_directory(false, Dir); @@ -962,5 +966,12 @@ TEST_F(ExpandResponseFilesTest, ExpandResponseFiles) { EXPECT_EQ(getCommand("bar.cpp"), "clang bar.cpp -D bar.cpp -Dflag"); } +TEST_F(ExpandResponseFilesTest, ExpandResponseFilesEmptyArgument) { + addFile(path(StringRef("rsp1.rsp")), "-Dflag"); + + add("foo.cpp", "clang", "@rsp1.rsp \"\""); + EXPECT_EQ(getCommand("foo.cpp"), "clang foo.cpp -D foo.cpp -Dflag "); +} + } // end namespace tooling } // end namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits