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);
|
QString ret(arg);
|
||||||
if (hasSpecialCharsUnix(ret)) {
|
if (hasSpecialCharsUnix(ret)) {
|
||||||
|
if (arg == "&&" || arg == "||" || arg == "&" || arg == ';')
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
|
ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
|
||||||
ret.prepend(QLatin1Char('\''));
|
ret.prepend(QLatin1Char('\''));
|
||||||
ret.append(QLatin1Char('\''));
|
ret.append(QLatin1Char('\''));
|
||||||
@@ -550,6 +553,9 @@ static QString quoteArgWin(const QString &arg)
|
|||||||
|
|
||||||
QString ret(arg);
|
QString ret(arg);
|
||||||
if (hasSpecialCharsWin(ret)) {
|
if (hasSpecialCharsWin(ret)) {
|
||||||
|
if (arg == "&&" || arg == "||" || arg == "&" || arg == ';')
|
||||||
|
return ret;
|
||||||
|
|
||||||
// Quotes are escaped and their preceding backslashes are doubled.
|
// Quotes are escaped and their preceding backslashes are doubled.
|
||||||
// It's impossible to escape anything inside a quoted string on cmd
|
// It's impossible to escape anything inside a quoted string on cmd
|
||||||
// level, so the outer quoting must be "suspended".
|
// level, so the outer quoting must be "suspended".
|
||||||
|
@@ -188,17 +188,95 @@ private slots:
|
|||||||
QCOMPARE(cmd.arguments(), "and args");
|
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()
|
void testFromInputWithMacro()
|
||||||
{
|
{
|
||||||
|
QFETCH(QString, input);
|
||||||
|
QFETCH(QString, expectedExecutable);
|
||||||
|
QFETCH(QString, expectedArguments);
|
||||||
|
|
||||||
MacroExpander expander;
|
MacroExpander expander;
|
||||||
expander.registerVariable("hello", "world var", [] { return "hello world"; });
|
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())
|
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