From 16ee0c0f9e58f9db9d8b261fbe63560f631c0597 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 13 May 2014 18:47:09 +0200 Subject: [PATCH] androiddeployqt: REG: Fix running tools with spaces in path The popen() function on Windows executes the command using /s, probably for legacy reasons, which causes the behavior that it removes the first and last quotes in the command line and otherwise preserves it perfectly. This causes strings in which both the executable name and at least one argument has to be quoted, to be unparsable by the shell once it has been processed. To work around this we wrap the string in quotes on Windows. Since we added quotes to arguments for the jarsigner command in Qt 5.3.0 we introduced a regression that made it impossible to sign APKs on Windows. Task-number: QTBUG-38962 Change-Id: I2b618e1996753645766d25ca06b14e1985d7eacd Reviewed-by: Paul Olav Tvete --- src/androiddeployqt/main.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/androiddeployqt/main.cpp b/src/androiddeployqt/main.cpp index 393e5cb..13ffbdb 100644 --- a/src/androiddeployqt/main.cpp +++ b/src/androiddeployqt/main.cpp @@ -73,6 +73,17 @@ void deleteRecursively(const QString &dirName) QDir().rmdir(dirName); } +FILE *openProcess(const QString &command) +{ +#if defined(Q_OS_WIN32) + QString processedCommand = QLatin1Char('\"') + command + QLatin1Char('\"'); +#else + QString processedCommand = command; +#endif + + return popen(processedCommand.toLocal8Bit().constData(), "r"); +} + struct Options { Options() @@ -1187,7 +1198,7 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName) readElf = QString::fromLatin1("\"%1\" -d -W %2").arg(readElf).arg(fileName); - FILE *readElfCommand = popen(readElf.toLocal8Bit().constData(), "r"); + FILE *readElfCommand = openProcess(readElf); if (readElfCommand == 0) { fprintf(stderr, "Cannot execute command %s", qPrintable(readElf)); return QStringList(); @@ -1331,7 +1342,7 @@ bool stripFile(const Options &options, const QString &fileName) strip = QString::fromLatin1("\"%1\" %2").arg(strip).arg(fileName); - FILE *stripCommand = popen(strip.toLocal8Bit().constData(), "r"); + FILE *stripCommand = openProcess(strip); if (stripCommand == 0) { fprintf(stderr, "Cannot execute command %s", qPrintable(strip)); return false; @@ -1412,7 +1423,7 @@ FILE *runAdb(const Options &options, const QString &arguments) if (options.verbose) fprintf(stdout, "Running command \"%s\"\n", adb.toLocal8Bit().constData()); - FILE *adbCommand = popen(adb.toLocal8Bit().constData(), "r"); + FILE *adbCommand = openProcess(adb); if (adbCommand == 0) { fprintf(stderr, "Cannot start adb: %s\n", qPrintable(adb)); return 0; @@ -1648,7 +1659,7 @@ bool createAndroidProject(const Options &options) if (options.verbose) fprintf(stdout, " -- Command: %s\n", qPrintable(androidTool)); - FILE *androidToolCommand = popen(androidTool.toLocal8Bit().constData(), "r"); + FILE *androidToolCommand = openProcess(androidTool); if (androidToolCommand == 0) { fprintf(stderr, "Cannot run command '%s'\n", qPrintable(androidTool)); return false; @@ -1708,7 +1719,7 @@ bool buildAndroidProject(const Options &options) QString ant = QString::fromLatin1("\"%1\" %2").arg(antTool).arg(options.releasePackage ? QLatin1String(" release") : QLatin1String(" debug")); - FILE *antCommand = popen(ant.toLocal8Bit().constData(), "r"); + FILE *antCommand = openProcess(ant); if (antCommand == 0) { fprintf(stderr, "Cannot run ant command: %s\n.", qPrintable(ant)); return false; @@ -1905,7 +1916,7 @@ bool signPackage(const Options &options) + QLatin1String("-unsigned.apk")) .arg(options.keyStoreAlias); - FILE *jarSignerCommand = popen(jarSignerTool.toLocal8Bit().constData(), "r"); + FILE *jarSignerCommand = openProcess(jarSignerTool); if (jarSignerCommand == 0) { fprintf(stderr, "Couldn't run jarsigner.\n"); return false; @@ -1947,7 +1958,7 @@ bool signPackage(const Options &options) + apkName(options) + QLatin1String(".apk")); - FILE *zipAlignCommand = popen(zipAlignTool.toLocal8Bit(), "r"); + FILE *zipAlignCommand = openProcess(zipAlignTool); if (zipAlignCommand == 0) { fprintf(stderr, "Couldn't run zipalign.\n"); return false; -- 2.7.4