aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Support/CommandLineTest.cpp
diff options
context:
space:
mode:
authorShoaib Meenai <smeenai@fb.com>2019-04-15 21:31:28 +0000
committerShoaib Meenai <smeenai@fb.com>2019-04-15 21:31:28 +0000
commitc8df4fb9c3865eac52a99602c26bbc070098c3d4 (patch)
treebcd85d457a958e3866247a52683b90563a79e508 /llvm/unittests/Support/CommandLineTest.cpp
parentc8497467edc5766ae81ffbde58159f8c6af50803 (diff)
downloadllvm-c8df4fb9c3865eac52a99602c26bbc070098c3d4.zip
llvm-c8df4fb9c3865eac52a99602c26bbc070098c3d4.tar.gz
llvm-c8df4fb9c3865eac52a99602c26bbc070098c3d4.tar.bz2
[Support] Fix recursive response file expansion guard
Response file expansion limits the amount of expansion to prevent potential infinite recursion. However, the current logic assumes that any argument beginning with @ is a response file, which is not true for e.g. `-Xlinker -rpath -Xlinker @executable_path/../lib` on Darwin. Having too many of these non-response file arguments beginning with @ prevents actual response files from being expanded. Instead, limit based on the number of successful response file expansions, which should still prevent infinite recursion but also avoid false positives. Differential Revision: https://reviews.llvm.org/D60631 llvm-svn: 358452
Diffstat (limited to 'llvm/unittests/Support/CommandLineTest.cpp')
-rw-r--r--llvm/unittests/Support/CommandLineTest.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index 782a816..99db7e2 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -813,6 +813,43 @@ TEST(CommandLineTest, RecursiveResponseFiles) {
EXPECT_STREQ(Argv[i], ResponseFileRef.c_str());
}
+TEST(CommandLineTest, ResponseFilesAtArguments) {
+ SmallString<128> TestDir;
+ std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
+ EXPECT_TRUE(!EC);
+
+ SmallString<128> ResponseFilePath;
+ sys::path::append(ResponseFilePath, TestDir, "test.rsp");
+
+ std::ofstream ResponseFile(ResponseFilePath.c_str());
+ EXPECT_TRUE(ResponseFile.is_open());
+ ResponseFile << "-foo" << "\n";
+ ResponseFile << "-bar" << "\n";
+ ResponseFile.close();
+
+ // Ensure we expand rsp files after lots of non-rsp arguments starting with @.
+ constexpr size_t NON_RSP_AT_ARGS = 64;
+ llvm::SmallVector<const char *, 4> Argv = {"test/test"};
+ Argv.append(NON_RSP_AT_ARGS, "@non_rsp_at_arg");
+ std::string ResponseFileRef = std::string("@") + ResponseFilePath.c_str();
+ Argv.push_back(ResponseFileRef.c_str());
+
+ llvm::BumpPtrAllocator A;
+ llvm::StringSaver Saver(A);
+ bool Res = llvm::cl::ExpandResponseFiles(
+ Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, false);
+ EXPECT_FALSE(Res);
+
+ // ASSERT instead of EXPECT to prevent potential out-of-bounds access.
+ ASSERT_EQ(Argv.size(), 1 + NON_RSP_AT_ARGS + 2);
+ size_t i = 0;
+ EXPECT_STREQ(Argv[i++], "test/test");
+ for (; i < 1 + NON_RSP_AT_ARGS; ++i)
+ EXPECT_STREQ(Argv[i], "@non_rsp_at_arg");
+ EXPECT_STREQ(Argv[i++], "-foo");
+ EXPECT_STREQ(Argv[i++], "-bar");
+}
+
TEST(CommandLineTest, SetDefautValue) {
cl::ResetCommandLineParser();