From 27f8e2dbce774410c5443a7f425eb53c2a869f54 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 9 Jun 2021 01:00:19 +0200 Subject: [PATCH] Utils: Fix splitting in ChannelBuffer::takeFirstLine() Escape the '\r' Change-Id: I8cee40dc4a65f893f1a11c7cf066777498c37339 Reviewed-by: Christian Stenger --- src/libs/utils/qtcprocess.cpp | 2 +- .../auto/utils/qtcprocess/tst_qtcprocess.cpp | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 42e80914f72..d6ffe3ebf8f 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -875,7 +875,7 @@ QString ChannelBuffer::linesRead() // Check for first complete line inside the rawData and return it, removing the line from the buffer Utils::optional ChannelBuffer::takeFirstLine() { - const int firstLineEnd = qMax(rawData.indexOf('\n'), rawData.indexOf('r')); + const int firstLineEnd = qMax(rawData.indexOf('\n'), rawData.indexOf('\r')); if (firstLineEnd == -1) return Utils::nullopt; diff --git a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp index aa002acba6f..4de142a4e5f 100644 --- a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp +++ b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp @@ -37,6 +37,15 @@ using namespace Utils; const char kExitCodeSubProcessCode[] = "QTC_TST_QTCPROCESS_EXITCODE_CODE"; const char kRunBlockingStdOutSubProcessMagicWord[] = "42"; const char kRunBlockingStdOutSubProcessWithEndl[] = "QTC_TST_QTCPROCESS_RUNBLOCKINGSTDOUT_WITHENDL"; +const char kLineCallback[] = "QTC_TST_QTCPROCESS_LINECALLBACK"; + +Q_GLOBAL_STATIC_WITH_ARGS(const QStringList, lineCallbackData, + ({ + "This is the first line\r", + "Here comes the second one\r", + "Let's also have a third one\r", + "Actually four are better\r", + })) static void exitCodeSubProcessMain() { @@ -57,6 +66,13 @@ static void blockingStdOutSubProcessMain() exit(0); } +static void lineCallbackMain() +{ + for (const QString &line : *lineCallbackData()) + std::cerr << qPrintable(line); + exit(0); +} + class MacroMapExpander : public AbstractMacroExpander { public: virtual bool resolveMacro(const QString &name, QString *ret, QSet &seen) @@ -102,6 +118,7 @@ private slots: void exitCode(); void runBlockingStdOut_data(); void runBlockingStdOut(); + void lineCallback(); private: void iteratorEditsHelper(OsType osType); @@ -121,6 +138,8 @@ void tst_QtcProcess::initTestCase() exitCodeSubProcessMain(); if (qEnvironmentVariableIsSet(kRunBlockingStdOutSubProcessWithEndl)) blockingStdOutSubProcessMain(); + if (qEnvironmentVariableIsSet(kLineCallback)) + lineCallbackMain(); homeStr = QLatin1String("@HOME@"); home = QDir::homePath(); @@ -871,6 +890,23 @@ void tst_QtcProcess::runBlockingStdOut() QVERIFY2(readLastLine, "Last line was read."); } +void tst_QtcProcess::lineCallback() +{ + QtcProcess process; + QStringList args = QCoreApplication::arguments(); + const QString binary = args.takeFirst(); + process.setCommand(CommandLine(binary, args)); + Environment env = Environment::systemEnvironment(); + env.set(kLineCallback, "Yes"); + process.setEnvironment(env); + int lineNumber = 0; + process.setStdErrLineCallback([&lineNumber](const QString &actual) { + const QString expected = lineCallbackData()->at(lineNumber++).trimmed(); + QCOMPARE(actual, expected); + }); + process.start(); + process.waitForFinished(); +} QTEST_MAIN(tst_QtcProcess) #include "tst_qtcprocess.moc"