From d00a5b3d7b2e52300ce35127f8778573a43111b2 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Wed, 22 Jul 2020 00:56:57 +0700 Subject: [PATCH] Revert "[Windows] Fix limit on command line size" This reverts commit d4020ef7c474b5e695d77aa100d7f68dc0c66b4e. It broke LLDB buildbot: http://lab.llvm.org:8011/builders/lldb-x64-windows-ninja/builds/17702. --- include/llvm/Support/Program.h | 2 +- lib/Support/Windows/Program.inc | 39 +++++++++++---------------- unittests/Support/CommandLineTest.cpp | 12 --------- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index d729d388365..dbda064cda0 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -218,7 +218,7 @@ namespace sys { /// to build a single flat command line appropriate for calling CreateProcess /// on /// Windows. - ErrorOr flattenWindowsCommandLine(ArrayRef Args); + std::string flattenWindowsCommandLine(ArrayRef Args); #endif } } diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc index c98c7841882..9fe05d24ec2 100644 --- a/lib/Support/Windows/Program.inc +++ b/lib/Support/Windows/Program.inc @@ -189,14 +189,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, // Windows wants a command line, not an array of args, to pass to the new // process. We have to concatenate them all, while quoting the args that // have embedded spaces (or are empty). - auto Result = flattenWindowsCommandLine(Args); - if (std::error_code ec = Result.getError()) { - SetLastError(ec.value()); - MakeErrMsg(ErrMsg, - std::string("Unable to convert command-line to UTF-16")); - return false; - } - std::wstring Command = *Result; + std::string Command = flattenWindowsCommandLine(Args); // The pointer to the environment block for the new process. std::vector EnvBlock; @@ -278,8 +271,14 @@ static bool Execute(ProcessInfo &PI, StringRef Program, return false; } - std::vector CommandUtf16(Command.size() + 1, 0); - std::copy(Command.begin(), Command.end(), CommandUtf16.begin()); + SmallVector CommandUtf16; + if (std::error_code ec = windows::UTF8ToUTF16(Command, CommandUtf16)) { + SetLastError(ec.value()); + MakeErrMsg(ErrMsg, + std::string("Unable to convert command-line to UTF-16")); + return false; + } + BOOL rc = CreateProcessW(ProgramUtf16.data(), CommandUtf16.data(), 0, 0, TRUE, CREATE_UNICODE_ENVIRONMENT, EnvBlock.empty() ? 0 : EnvBlock.data(), 0, &si, @@ -377,7 +376,7 @@ static std::string quoteSingleArg(StringRef Arg) { } namespace llvm { -ErrorOr sys::flattenWindowsCommandLine(ArrayRef Args) { +std::string sys::flattenWindowsCommandLine(ArrayRef Args) { std::string Command; for (StringRef Arg : Args) { if (argNeedsQuotes(Arg)) @@ -388,11 +387,7 @@ ErrorOr sys::flattenWindowsCommandLine(ArrayRef Args) { Command.push_back(' '); } - SmallVector CommandUtf16; - if (std::error_code ec = windows::UTF8ToUTF16(Command, CommandUtf16)) - return ec; - - return std::wstring(CommandUtf16.begin(), CommandUtf16.end()); + return Command; } ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, @@ -537,16 +532,12 @@ llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents, bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef Args) { - // The documentation on CreateProcessW states that the size of the argument - // lpCommandLine must not be greater than 32767 characters, including the - // Unicode terminating null character. We use smaller value to reduce risk - // of getting invalid command line due to unaccounted factors. - static const size_t MaxCommandStringLength = 32000; + // The documented max length of the command line passed to CreateProcess. + static const size_t MaxCommandStringLength = 32768; SmallVector FullArgs; FullArgs.push_back(Program); FullArgs.append(Args.begin(), Args.end()); - auto Result = flattenWindowsCommandLine(FullArgs); - assert(!Result.getError()); - return (Result->size() + 1) <= MaxCommandStringLength; + std::string Result = flattenWindowsCommandLine(FullArgs); + return (Result.size() + 1) <= MaxCommandStringLength; } } diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp index e8c2cef18e3..e1b706e2a78 100644 --- a/unittests/Support/CommandLineTest.cpp +++ b/unittests/Support/CommandLineTest.cpp @@ -763,18 +763,6 @@ TEST(CommandLineTest, DefaultOptions) { TEST(CommandLineTest, ArgumentLimit) { std::string args(32 * 4096, 'a'); EXPECT_FALSE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data())); - std::string args2(256, 'a'); - EXPECT_TRUE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args2.data())); - if (Triple(sys::getProcessTriple()).isOSWindows()) { - // We use 32000 as a limit for command line length. Program name ('cl'), - // separating spaces and termination null character occupy 5 symbols. - std::string long_arg(32000 - 5, 'b'); - EXPECT_TRUE( - llvm::sys::commandLineFitsWithinSystemLimits("cl", long_arg.data())); - long_arg += 'b'; - EXPECT_FALSE( - llvm::sys::commandLineFitsWithinSystemLimits("cl", long_arg.data())); - } } TEST(CommandLineTest, ResponseFileWindows) {