Fix escape handling in qWinCmdArgs
-DKEY="VALUE" was correctly turned into -DKEY=VALUE, but -DKEY=\"VALUE\" was turned into -DKEY=\VALUE" due to the erroneous check ('quote' is still 0 when encountering the first '\' character). This fixes QCoreApplication::arguments() as used by moc.exe after porting to QCommandLineParser. Further investigation shows that double-quotes and single-quotes are handled differently. The tests now ensure that this parser respects what Windows sends in argv, and in particular that QTBUG-15379 doesn't regress, as well as fixing QTBUG-30628. Task-number: QTBUG-15379, QTBUG-30628 Change-Id: I95062c9a6022632b321b2f6fae3089f07be7b5c6 Reviewed-by: Richard J. Moore <rich@kde.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
ad46d5b82b
commit
4ff6951550
@ -83,7 +83,7 @@ static QVector<Char*> qWinCmdLine(Char *cmdParam, int length, int &argc)
|
||||
if (*p && p < p_end) { // arg starts
|
||||
int quote;
|
||||
Char *start, *r;
|
||||
if (*p == Char('\"') || *p == Char('\'')) { // " or ' quote
|
||||
if (*p == Char('\"')) {
|
||||
quote = *p;
|
||||
start = ++p;
|
||||
} else {
|
||||
@ -101,10 +101,11 @@ static QVector<Char*> qWinCmdLine(Char *cmdParam, int length, int &argc)
|
||||
}
|
||||
}
|
||||
if (*p == '\\') { // escape char?
|
||||
if (*(p+1) == quote)
|
||||
// testing by looking at argc, argv shows that it only escapes quotes and backslashes
|
||||
if (p < p_end && (*(p+1) == Char('\"') || *(p+1) == Char('\\')))
|
||||
p++;
|
||||
} else {
|
||||
if (!quote && (*p == Char('\"') || *p == Char('\''))) { // " or ' quote
|
||||
if (!quote && (*p == Char('\"'))) {
|
||||
quote = *p++;
|
||||
continue;
|
||||
} else if (QChar((short)(*p)).isSpace() && !quote)
|
||||
|
@ -50,6 +50,13 @@ int main(int argc, char *argv[])
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setApplicationVersion("1.0");
|
||||
|
||||
// Test for QCoreApplication::arguments()
|
||||
const QStringList incomingArgs = QCoreApplication::arguments();
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (incomingArgs.at(i) != QLatin1String(argv[i]))
|
||||
qDebug() << "ERROR: arguments[" << i << "] was" << incomingArgs.at(i) << "expected" << argv[i];
|
||||
}
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("Test helper");
|
||||
parser.addHelpOption();
|
||||
@ -87,6 +94,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
printf("Positional arguments: %s\n", qPrintable(parser.positionalArguments().join(",")));
|
||||
printf("Macros: %s\n", qPrintable(parser.values("D").join(",")));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ private slots:
|
||||
void testVersionOption();
|
||||
void testHelpOption_data();
|
||||
void testHelpOption();
|
||||
void testQuoteEscaping();
|
||||
};
|
||||
|
||||
static char *empty_argv[] = { const_cast<char*>("tst_qcommandlineparser") };
|
||||
@ -534,6 +535,25 @@ void tst_QCommandLineParser::testHelpOption()
|
||||
#endif // !QT_NO_PROCESS
|
||||
}
|
||||
|
||||
void tst_QCommandLineParser::testQuoteEscaping()
|
||||
{
|
||||
QCoreApplication app(empty_argc, empty_argv);
|
||||
QProcess process;
|
||||
process.start("testhelper/qcommandlineparser_test_helper", QStringList() <<
|
||||
QString::number(QCommandLineParser::ParseAsCompactedShortOptions) <<
|
||||
"-DKEY1=\"VALUE1\"" << "-DKEY2=\\\"VALUE2\\\"" <<
|
||||
"-DQTBUG-15379=C:\\path\\'file.ext" <<
|
||||
"-DQTBUG-30628=C:\\temp\\'file'.ext");
|
||||
QVERIFY(process.waitForFinished(5000));
|
||||
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||
QString output = process.readAll();
|
||||
QVERIFY2(!output.contains("ERROR"), qPrintable(output));
|
||||
QVERIFY2(output.contains("KEY1=\"VALUE1\""), qPrintable(output));
|
||||
QVERIFY2(output.contains("KEY2=\\\"VALUE2\\\""), qPrintable(output));
|
||||
QVERIFY2(output.contains("QTBUG-15379=C:\\path\\'file.ext"), qPrintable(output));
|
||||
QVERIFY2(output.contains("QTBUG-30628=C:\\temp\\'file'.ext"), qPrintable(output));
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QCommandLineParser)
|
||||
#include "tst_qcommandlineparser.moc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user