Utils: Improve and test CommandLine::fromUserInput

Change-Id: Ia18f5b01d91200e6ad65735496395215c6393533
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-03-13 13:56:50 +01:00
parent 2d15be91bf
commit 8f1cbd2e52
2 changed files with 91 additions and 10 deletions

View File

@@ -1429,16 +1429,20 @@ CommandLine::CommandLine(const FilePath &exe, const QString &args, RawType)
CommandLine CommandLine::fromUserInput(const QString &cmdline, MacroExpander *expander) CommandLine CommandLine::fromUserInput(const QString &cmdline, MacroExpander *expander)
{ {
CommandLine cmd; if (cmdline.isEmpty())
const int pos = cmdline.indexOf(' '); return {};
if (pos == -1) {
cmd.m_executable = FilePath::fromString(cmdline); QString input = cmdline.trimmed();
} else {
cmd.m_executable = FilePath::fromString(cmdline.left(pos)); QStringList result = ProcessArgs::splitArgs(cmdline, HostOsInfo::hostOs());
cmd.m_arguments = cmdline.right(cmdline.length() - pos - 1);
if (expander) if (result.isEmpty())
cmd.m_arguments = expander->expand(cmd.m_arguments); return {};
}
auto cmd = CommandLine(FilePath::fromUserInput(result.value(0)), result.mid(1));
if (expander)
cmd.m_arguments = expander->expand(cmd.m_arguments);
return cmd; return cmd;
} }

View File

@@ -7,6 +7,7 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/launcherinterface.h> #include <utils/launcherinterface.h>
#include <utils/macroexpander.h>
#include <utils/processinterface.h> #include <utils/processinterface.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/temporarydirectory.h> #include <utils/temporarydirectory.h>
@@ -123,6 +124,82 @@ private slots:
QString actual = run(shell); QString actual = run(shell);
QCOMPARE(actual, expected); QCOMPARE(actual, expected);
} }
void testFromUserInput_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<QString>("executable");
QTest::addColumn<QString>("arguments");
QTest::newRow("empty") << ""
<< ""
<< "";
QTest::newRow("command") << "command"
<< "command"
<< "";
QTest::newRow("command-with-args") << "command and args"
<< "command"
<< "and args";
if (!HostOsInfo::isWindowsHost()) {
QTest::newRow("command-with-space-slash") << "command\\ with-space and args"
<< "command with-space"
<< "and args";
QTest::newRow("command-with-space-single-quote") << "'command with-space' and args"
<< "command with-space"
<< "and args";
}
QTest::newRow("command-with-space-double-quote") << "\"command with-space\" and args"
<< "command with-space"
<< "and args";
QTest::newRow("command-with-space-double-quote-in-name")
<< "\"command\\\"with-quote\" and args"
<< "command\"with-quote"
<< "and args";
QTest::newRow("inside-space-quoted") << "command\" \"withspace args here"
<< "command withspace"
<< "args here";
}
void testFromUserInput()
{
QFETCH(QString, input);
QFETCH(QString, executable);
QFETCH(QString, arguments);
CommandLine cmd = CommandLine::fromUserInput(input);
QCOMPARE(cmd.executable(), FilePath::fromUserInput(executable));
QCOMPARE(cmd.arguments(), arguments);
}
void testFromInputFails()
{
if (HostOsInfo::isWindowsHost())
QSKIP("The test does not work on Windows.");
CommandLine cmd = CommandLine::fromUserInput("command\\\\\\ with-space and args");
QEXPECT_FAIL("",
"CommandLine::fromUserInput (and FilePath::fromUserInput) does not handle "
"backslashes correctly",
Continue);
QCOMPARE(cmd.executable().fileName(), "command\\ with-space");
QCOMPARE(cmd.arguments(), "and args");
}
void testFromInputWithMacro()
{
MacroExpander expander;
expander.registerVariable("hello", "world var", [] { return "hello world"; });
CommandLine cmd = CommandLine::fromUserInput("command macroarg: %{hello}", &expander);
QCOMPARE(cmd.executable(), "command");
if (HostOsInfo::isWindowsHost())
QEXPECT_FAIL("", "Windows does not correctly quote macro arguments", Continue);
QCOMPARE(cmd.arguments(), "macroarg: 'hello world'");
}
}; };
int main(int argc, char *argv[]) int main(int argc, char *argv[])