From 2d068e534f1671459e1b135852c1b3c10502e929 Mon Sep 17 00:00:00 2001 From: Adrian McCarthy Date: Wed, 27 May 2020 13:53:47 -0700 Subject: [PATCH] Fix Windows command line bug when last token in response file is "" Patch by Neil Dhar Current state machine for parsing tokens from response files in Windows does not correctly handle the case where the last token is "". The current implementation handles the last token by only adding it if it is not empty, however this does not cover the case where the last token is meant to be the empty string. We can cover this case by checking whether the state machine was last in the UNQUOTED state, which indicates that the last character of the input was a non-whitespace character. Differential Revision: https://reviews.llvm.org/D78346 --- llvm/lib/Support/CommandLine.cpp | 2 +- llvm/unittests/Support/CommandLineTest.cpp | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index aa7e796..25612b7 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -1009,7 +1009,7 @@ tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver, } } - if (!Token.empty()) + if (State == UNQUOTED) AddToken(Saver.save(Token.str())); } diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index a6b26b3..3e7ec8d 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -253,8 +253,8 @@ TEST(CommandLineTest, TokenizeGNUCommandLine) { } TEST(CommandLineTest, TokenizeWindowsCommandLine1) { - const char Input[] = "a\\b c\\\\d e\\\\\"f g\" h\\\"i j\\\\\\\"k \"lmn\" o pqr " - "\"st \\\"u\" \\v"; + const char Input[] = + R"(a\b c\\d e\\"f g" h\"i j\\\"k "lmn" o pqr "st \"u" \v)"; const char *const Output[] = { "a\\b", "c\\\\d", "e\\f g", "h\"i", "j\\\"k", "lmn", "o", "pqr", "st \"u", "\\v" }; testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input, Output, @@ -268,6 +268,17 @@ TEST(CommandLineTest, TokenizeWindowsCommandLine2) { array_lengthof(Output)); } +TEST(CommandLineTest, TokenizeWindowsCommandLineQuotedLastArgument) { + const char Input1[] = R"(a b c d "")"; + const char *const Output1[] = {"a", "b", "c", "d", ""}; + testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input1, Output1, + array_lengthof(Output1)); + const char Input2[] = R"(a b c d ")"; + const char *const Output2[] = {"a", "b", "c", "d"}; + testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input2, Output2, + array_lengthof(Output2)); +} + TEST(CommandLineTest, TokenizeConfigFile1) { const char *Input = "\\"; const char *const Output[] = { "\\" }; -- 2.7.4