]> granicus.if.org Git - clang/commitdiff
Fix use-after-free bug in Tooling.
authorAlexander Kornienko <alexfh@google.com>
Tue, 8 Jan 2019 16:55:13 +0000 (16:55 +0000)
committerAlexander Kornienko <alexfh@google.com>
Tue, 8 Jan 2019 16:55:13 +0000 (16:55 +0000)
Summary:
`buildASTFromCodeWithArgs()` was creating a memory buffer referencing a
stack-allocated string.  This diff changes the implementation to copy the code
string into the memory buffer so that said buffer owns the memory.

Patch by Yitzhak Mandelbaum.

Reviewers: alexfh

Reviewed By: alexfh

Subscribers: cfe-commits, EricWF

Differential Revision: https://reviews.llvm.org/D55765

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

include/clang/Tooling/Tooling.h
lib/Tooling/Tooling.cpp
unittests/Analysis/ExprMutationAnalyzerTest.cpp

index 358acf3e2d03ddeeacbf2514ef753d847c7f964e..662a980547df6bc5132e6f1461a7638357d8a364 100644 (file)
@@ -205,7 +205,7 @@ bool runToolOnCodeWithArgs(
 ///
 /// \return The resulting AST or null if an error occurred.
 std::unique_ptr<ASTUnit>
-buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
+buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
                      std::make_shared<PCHContainerOperations>());
 
@@ -223,10 +223,10 @@ buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
 ///
 /// \return The resulting AST or null if an error occurred.
 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
-    const Twine &Code, const std::vector<std::string> &Args,
-    const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool",
+    StringRef Code, const std::vector<std::string> &Args,
+    StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
-      std::make_shared<PCHContainerOperations>(),
+        std::make_shared<PCHContainerOperations>(),
     ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
 
 /// Utility to run a FrontendAction in a single clang invocation.
index 84a4ac648c36bdb40438ad710579f0dc7b3b9b22..63aa64a5330d3929527a6c1f295f28eaa6ee34d0 100644 (file)
@@ -574,20 +574,16 @@ namespace clang {
 namespace tooling {
 
 std::unique_ptr<ASTUnit>
-buildASTFromCode(const Twine &Code, const Twine &FileName,
+buildASTFromCode(StringRef Code, StringRef FileName,
                  std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
   return buildASTFromCodeWithArgs(Code, std::vector<std::string>(), FileName,
                                   "clang-tool", std::move(PCHContainerOps));
 }
 
 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
-    const Twine &Code, const std::vector<std::string> &Args,
-    const Twine &FileName, const Twine &ToolName,
-    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    StringRef Code, const std::vector<std::string> &Args, StringRef FileName,
+    StringRef ToolName, std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     ArgumentsAdjuster Adjuster) {
-  SmallString<16> FileNameStorage;
-  StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
-
   std::vector<std::unique_ptr<ASTUnit>> ASTs;
   ASTBuilderAction Action(ASTs);
   llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem(
@@ -599,13 +595,11 @@ std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
       new FileManager(FileSystemOptions(), OverlayFileSystem));
 
   ToolInvocation Invocation(
-      getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileNameRef), FileNameRef),
+      getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileName), FileName),
       &Action, Files.get(), std::move(PCHContainerOps));
 
-  SmallString<1024> CodeStorage;
-  InMemoryFileSystem->addFile(FileNameRef, 0,
-                              llvm::MemoryBuffer::getMemBuffer(
-                                  Code.toNullTerminatedStringRef(CodeStorage)));
+  InMemoryFileSystem->addFile(FileName, 0,
+                              llvm::MemoryBuffer::getMemBufferCopy(Code));
   if (!Invocation.run())
     return nullptr;
 
index 9c6bc783b338af8bb71af6ebe6a9757cf24c348b..68c921e43988bd8fc297ec22b5523972f7d254e4 100644 (file)
@@ -11,6 +11,7 @@
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <cctype>
@@ -32,7 +33,9 @@ using StmtMatcher = internal::Matcher<Stmt>;
 std::unique_ptr<ASTUnit>
 buildASTFromCodeWithArgs(const Twine &Code,
                          const std::vector<std::string> &Args) {
-  auto AST = tooling::buildASTFromCodeWithArgs(Code, Args);
+  SmallString<1024> CodeStorage;
+  auto AST =
+      tooling::buildASTFromCodeWithArgs(Code.toStringRef(CodeStorage), Args);
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
   return AST;
 }