diff options
author | Philip Schuchardt <vpicaver@gmail.com> | 2016-05-12 12:28:48 -0400 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2016-05-20 12:43:33 +0000 |
commit | fbf6502160988e0376c26d83732329b226465f27 (patch) | |
tree | 2b8225a952432353241828ef436eb63a21175190 | |
parent | db832c1886607e0d2da7ef6c6a13e72cad140cea (diff) |
Quote arguments in response files
This bug fix adds quotes around arguments with spaces
or tabs in the response files. It also escapes quotes
if they're found in the argument list.
Task-number: QBS-812
Autotest-by: Joerg Bornemann <joerg.bornemann@qt.io>
Change-Id: I4f4479e413b467e64f55c3068475d0dbb1990798
Reviewed-by: Jake Petroules <jake.petroules@qt.io>
Reviewed-by: Philip Schuchardt <vpicaver@gmail.com>
5 files changed, 94 insertions, 1 deletions
diff --git a/src/lib/corelib/buildgraph/processcommandexecutor.cpp b/src/lib/corelib/buildgraph/processcommandexecutor.cpp index 34d63c0ba..048dc7823 100644 --- a/src/lib/corelib/buildgraph/processcommandexecutor.cpp +++ b/src/lib/corelib/buildgraph/processcommandexecutor.cpp @@ -130,7 +130,7 @@ void ProcessCommandExecutor::doStart() return; } for (int i = cmd->responseFileArgumentIndex(); i < cmd->arguments().count(); ++i) { - responseFile.write(cmd->arguments().at(i).toLocal8Bit()); + responseFile.write(qbs::Internal::shellQuote(cmd->arguments().at(i)).toLocal8Bit()); responseFile.write("\n"); } responseFile.close(); diff --git a/tests/auto/blackbox/testdata/response-files/cat-response-file.cpp b/tests/auto/blackbox/testdata/response-files/cat-response-file.cpp new file mode 100644 index 000000000..44457548b --- /dev/null +++ b/tests/auto/blackbox/testdata/response-files/cat-response-file.cpp @@ -0,0 +1,39 @@ +#include <iostream> +#include <fstream> +#include <cstring> +#include <string> + +using namespace std; + +int main(int argc, char *argv[]) +{ + if (argc < 3) { + cerr << "cat-response-file: not enough arguments: " << argc - 1 << endl; + return 1; + } + if (strlen(argv[2]) < 2) { + cerr << "cat-response-file: second argument is too short: " << argv[2] << endl; + return 2; + } + if (argv[2][0] != '@') { + cerr << "cat-response-file: second argument does not start with @: " << argv[2] << endl; + return 3; + } + ifstream inf(argv[2] + 1); + if (!inf.is_open()) { + cerr << "cat-response-file: cannot open input file " << argv[2] + 1 << endl; + return 4; + } + ofstream ouf(argv[1]); + if (!ouf.is_open()) { + cerr << "cat-response-file: cannot open output file " << argv[1] << endl; + return 5; + } + string line; + while (getline(inf, line)) + ouf << line << endl; + inf.close(); + ouf.close(); + return 0; +} + diff --git a/tests/auto/blackbox/testdata/response-files/response-files.qbs b/tests/auto/blackbox/testdata/response-files/response-files.qbs new file mode 100644 index 000000000..7913287e1 --- /dev/null +++ b/tests/auto/blackbox/testdata/response-files/response-files.qbs @@ -0,0 +1,37 @@ +import qbs +import qbs.FileInfo +import qbs.TextFile + +Project { + CppApplication { + name: "cat-response-file" + files: ["cat-response-file.cpp"] + cpp.enableExceptions: true + } + Product { + name: "response-file-text" + type: ["text"] + Depends { name: "cat-response-file" } + Group { + fileTagsFilter: ["text"] + qbs.install: true + } + Rule { + inputsFromDependencies: ["application"] + Artifact { + filePath: "response-file-content.txt" + fileTags: ["text"] + } + prepare: { + var filePath = inputs["application"][0].filePath; + var args = [output.filePath, "foo", "with space", "bar"]; + var cmd = new Command(filePath, args); + cmd.responseFileThreshold = 1; + cmd.responseFileArgumentIndex = 1; + cmd.responseFileUsagePrefix = '@'; + cmd.silent = true; + return cmd; + } + } + } +} diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 1c8daf33c..8e843f826 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -1726,6 +1726,22 @@ void TestBlackbox::reproducibleBuild_data() QTest::newRow("reproducible build") << true; } +void TestBlackbox::responseFiles() +{ + QDir::setCurrent(testDataDir + "/response-files"); + QbsRunParameters params; + params.command = "install"; + params.arguments << "--install-root" << "installed"; + QCOMPARE(runQbs(params), 0); + QFile file("installed/response-file-content.txt"); + QVERIFY(file.open(QIODevice::ReadOnly)); + const QList<QByteArray> expected = {"foo", "\"with space\"", "bar", ""}; + QList<QByteArray> lines = file.readAll().split('\n'); + for (int i = 0; i < lines.count(); ++i) + lines[i] = lines.at(i).trimmed(); + QCOMPARE(lines, expected); +} + void TestBlackbox::ruleConditions() { QDir::setCurrent(testDataDir + "/ruleConditions"); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 048c4987b..a89b9e537 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -188,6 +188,7 @@ private slots: void referenceErrorInExport(); void reproducibleBuild(); void reproducibleBuild_data(); + void responseFiles(); void ruleConditions(); void ruleCycle(); void subProfileChangeTracking(); |