forked from qt-creator/qt-creator
Utils: Fix operator escaping
Stops CommandLine / ProcessArgs from escaping operators '&&', '||' and ';'. Fixes: QTCREATORBUG-29280 Change-Id: Idf4f429fec0d96b67266761297eea851c283ac4c Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -514,6 +514,9 @@ QString ProcessArgs::quoteArgUnix(const QString &arg)
|
||||
|
||||
QString ret(arg);
|
||||
if (hasSpecialCharsUnix(ret)) {
|
||||
if (arg == "&&" || arg == "||" || arg == "&" || arg == ';')
|
||||
return ret;
|
||||
|
||||
ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
|
||||
ret.prepend(QLatin1Char('\''));
|
||||
ret.append(QLatin1Char('\''));
|
||||
@@ -550,6 +553,9 @@ static QString quoteArgWin(const QString &arg)
|
||||
|
||||
QString ret(arg);
|
||||
if (hasSpecialCharsWin(ret)) {
|
||||
if (arg == "&&" || arg == "||" || arg == "&" || arg == ';')
|
||||
return ret;
|
||||
|
||||
// Quotes are escaped and their preceding backslashes are doubled.
|
||||
// It's impossible to escape anything inside a quoted string on cmd
|
||||
// level, so the outer quoting must be "suspended".
|
||||
|
@@ -188,17 +188,95 @@ private slots:
|
||||
QCOMPARE(cmd.arguments(), "and args");
|
||||
}
|
||||
|
||||
void testFromInputWithMacro_data()
|
||||
{
|
||||
QTest::addColumn<QString>("input");
|
||||
QTest::addColumn<QString>("expectedExecutable");
|
||||
QTest::addColumn<QString>("expectedArguments");
|
||||
|
||||
QTest::newRow("simple") << "command %{hello}"
|
||||
<< "command"
|
||||
<< (HostOsInfo::isWindowsHost() ? "\"hello world\""
|
||||
: "'hello world'");
|
||||
|
||||
QTest::newRow("simple-quoted")
|
||||
<< "command \"%{hello}\""
|
||||
<< "command" << (HostOsInfo::isWindowsHost() ? "\"hello world\"" : "'hello world'");
|
||||
|
||||
QTest::newRow("quoted-with-extra")
|
||||
<< "command \"%{hello}, he said\""
|
||||
<< "command"
|
||||
<< (HostOsInfo::isWindowsHost() ? "\"hello world, he said\"" : "'hello world, he said'");
|
||||
|
||||
QTest::newRow("convert-to-quote-win")
|
||||
<< "command 'this is a test'"
|
||||
<< "command"
|
||||
<< (HostOsInfo::isWindowsHost() ? "\"this is a test\"" : "'this is a test'");
|
||||
}
|
||||
|
||||
void testFromInputWithMacro()
|
||||
{
|
||||
QFETCH(QString, input);
|
||||
QFETCH(QString, expectedExecutable);
|
||||
QFETCH(QString, expectedArguments);
|
||||
|
||||
MacroExpander expander;
|
||||
expander.registerVariable("hello", "world var", [] { return "hello world"; });
|
||||
CommandLine cmd = CommandLine::fromUserInput("command macroarg: %{hello}", &expander);
|
||||
QCOMPARE(cmd.executable(), "command");
|
||||
|
||||
CommandLine cmd = CommandLine::fromUserInput(input, &expander);
|
||||
QCOMPARE(cmd.executable().toUserOutput(), expectedExecutable);
|
||||
|
||||
// TODO: Fix (macro) escaping on windows
|
||||
if (HostOsInfo::isWindowsHost())
|
||||
QEXPECT_FAIL("", "Windows does not correctly quote macro arguments", Continue);
|
||||
QEXPECT_FAIL("simple", "Windows does not correctly quote macro arguments", Continue);
|
||||
if (HostOsInfo::isWindowsHost())
|
||||
QEXPECT_FAIL("simple-quoted", "Windows removes quotes from macro arguments", Continue);
|
||||
if (HostOsInfo::isWindowsHost())
|
||||
QEXPECT_FAIL("convert-to-quote-win",
|
||||
"Windows should convert single to double quotes",
|
||||
Continue);
|
||||
|
||||
QCOMPARE(cmd.arguments(), "macroarg: 'hello world'");
|
||||
QCOMPARE(cmd.arguments(), expectedArguments);
|
||||
}
|
||||
|
||||
void testMultiCommand_data()
|
||||
{
|
||||
QTest::addColumn<QString>("input");
|
||||
QTest::addColumn<QString>("executable");
|
||||
QTest::addColumn<QString>("arguments");
|
||||
|
||||
QTest::newRow("command-and-command") << "command1 && command2"
|
||||
<< "command1"
|
||||
<< "&& command2";
|
||||
|
||||
QTest::newRow("command-and-command-nospace") << "command1&&command2"
|
||||
<< "command1"
|
||||
<< "&&command2";
|
||||
|
||||
QTest::newRow("command-semicolon-command") << "command1 ; command2"
|
||||
<< "command1"
|
||||
<< "; command2";
|
||||
|
||||
QTest::newRow("command-or-command") << "command1 || command2"
|
||||
<< "command1"
|
||||
<< "|| command2";
|
||||
}
|
||||
|
||||
void testMultiCommand()
|
||||
{
|
||||
QFETCH(QString, input);
|
||||
QFETCH(QString, executable);
|
||||
QFETCH(QString, arguments);
|
||||
|
||||
CommandLine cmdLine = CommandLine::fromUserInput(input);
|
||||
|
||||
QEXPECT_FAIL(
|
||||
"command-and-command-nospace",
|
||||
"CommandLine::fromUserInput does not handle multi-command without space correctly",
|
||||
Abort);
|
||||
|
||||
QCOMPARE(cmdLine.executable().path(), executable);
|
||||
QCOMPARE(cmdLine.arguments(), arguments);
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user