forked from OSchip/llvm-project
Fix use-after-free bug in Tooling.
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 llvm-svn: 350638
This commit is contained in:
parent
0d99031de0
commit
973fcc25fb
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue