summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorAssam Boudjelthia <assam.boudjelthia@qt.io>2022-04-15 16:00:57 +0300
committerAssam Boudjelthia <assam.boudjelthia@qt.io>2022-04-21 11:52:52 +0300
commita9f18a6ec065b1538667e13f4d81db6cdee5b948 (patch)
tree4926cc0fd53fc1495687c74790e7e4271ab3a36d /src/tools
parent905bfb850389431f8928b89ce55dbabcab35b2d0 (diff)
Android: de-duplicate shellquote helpers code in deploy and test tools
Move shellquote helper functions into a common place instead of having a copy in each tool's code. Change-Id: I9723c11f894a211864788a7635773610c0fde739 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/androiddeployqt/main.cpp74
-rw-r--r--src/tools/androidtestrunner/CMakeLists.txt2
-rw-r--r--src/tools/androidtestrunner/main.cpp73
-rw-r--r--src/tools/shared/shellquote_shared.h107
4 files changed, 112 insertions, 144 deletions
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 94496fe61c..7f6a5d30f1 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -47,6 +47,7 @@
#include <QMap>
#include <depfile_shared.h>
+#include <shellquote_shared.h>
#include <algorithm>
@@ -249,77 +250,6 @@ static const QHash<QByteArray, QByteArray> elfArchitectures = {
{"x86_64", "x86_64"}
};
-// Copy-pasted from qmake/library/ioutil.cpp
-inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
-{
- for (int x = arg.length() - 1; x >= 0; --x) {
- ushort c = arg.unicode()[x].unicode();
- if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
- return true;
- }
- return false;
-}
-
-static QString shellQuoteUnix(const QString &arg)
-{
- // Chars that should be quoted (TM). This includes:
- static const uchar iqm[] = {
- 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
- 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
- }; // 0-32 \'"$`<>|;&(){}*?#!~[]
-
- if (!arg.length())
- return "\"\""_L1;
-
- QString ret(arg);
- if (hasSpecialChars(ret, iqm)) {
- ret.replace(u'\'', "'\\''"_L1);
- ret.prepend(u'\'');
- ret.append(u'\'');
- }
- return ret;
-}
-
-static QString shellQuoteWin(const QString &arg)
-{
- // Chars that should be quoted (TM). This includes:
- // - control chars & space
- // - the shell meta chars "&()<>^|
- // - the potential separators ,;=
- static const uchar iqm[] = {
- 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
- };
-
- if (!arg.length())
- return "\"\""_L1;
-
- QString ret(arg);
- if (hasSpecialChars(ret, iqm)) {
- // Quotes are escaped and their preceding backslashes are doubled.
- // It's impossible to escape anything inside a quoted string on cmd
- // level, so the outer quoting must be "suspended".
- ret.replace(QRegularExpression("(\\\\*)\""_L1), "\"\\1\\1\\^\"\""_L1);
- // The argument must not end with a \ since this would be interpreted
- // as escaping the quote -- rather put the \ behind the quote: e.g.
- // rather use "foo"\ than "foo\"
- qsizetype i = ret.length();
- while (i > 0 && ret.at(i - 1) == u'\\')
- --i;
- ret.insert(i, u'"');
- ret.prepend(u'"');
- }
- return ret;
-}
-
-static QString shellQuote(const QString &arg)
-{
- if (QDir::separator() == u'\\')
- return shellQuoteWin(arg);
- else
- return shellQuoteUnix(arg);
-}
-
QString architectureFromName(const QString &name)
{
QRegularExpression architecture(QStringLiteral("_(armeabi-v7a|arm64-v8a|x86|x86_64).so$"));
@@ -362,8 +292,6 @@ static QString llvmReadobjPath(const Options &options)
options.ndkHost));
}
-
-
QString fileArchitecture(const Options &options, const QString &path)
{
auto arch = architectureFromName(path);
diff --git a/src/tools/androidtestrunner/CMakeLists.txt b/src/tools/androidtestrunner/CMakeLists.txt
index a078913fbf..e4cd663d3a 100644
--- a/src/tools/androidtestrunner/CMakeLists.txt
+++ b/src/tools/androidtestrunner/CMakeLists.txt
@@ -16,6 +16,8 @@ qt_internal_add_tool(${target_name}
QT_NO_FOREACH
PUBLIC_LIBRARIES
Qt::Gui
+ INCLUDE_DIRECTORIES
+ ../shared
)
qt_internal_return_unless_building_tools()
set_target_properties(${target_name} PROPERTIES
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp
index efcc6ed7bc..3b9e53a5a5 100644
--- a/src/tools/androidtestrunner/main.cpp
+++ b/src/tools/androidtestrunner/main.cpp
@@ -39,6 +39,8 @@
#include <functional>
#include <thread>
+#include <shellquote_shared.h>
+
#ifdef Q_CC_MSVC
#define popen _popen
#define QT_POPEN_READ "rb"
@@ -189,77 +191,6 @@ static bool execCommand(const QString &command, QByteArray *output = nullptr, bo
return pclose(process) == 0;
}
-// Copy-pasted from qmake/library/ioutil.cpp
-inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
-{
- for (int x = arg.length() - 1; x >= 0; --x) {
- ushort c = arg.unicode()[x].unicode();
- if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
- return true;
- }
- return false;
-}
-
-static QString shellQuoteUnix(const QString &arg)
-{
- // Chars that should be quoted (TM). This includes:
- static const uchar iqm[] = {
- 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
- 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
- }; // 0-32 \'"$`<>|;&(){}*?#!~[]
-
- if (!arg.length())
- return QStringLiteral("\"\"");
-
- QString ret(arg);
- if (hasSpecialChars(ret, iqm)) {
- ret.replace(u'\'', QStringLiteral("'\\''"));
- ret.prepend(u'\'');
- ret.append(u'\'');
- }
- return ret;
-}
-
-static QString shellQuoteWin(const QString &arg)
-{
- // Chars that should be quoted (TM). This includes:
- // - control chars & space
- // - the shell meta chars "&()<>^|
- // - the potential separators ,;=
- static const uchar iqm[] = {
- 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
- };
-
- if (!arg.length())
- return QStringLiteral("\"\"");
-
- QString ret(arg);
- if (hasSpecialChars(ret, iqm)) {
- // Quotes are escaped and their preceding backslashes are doubled.
- // It's impossible to escape anything inside a quoted string on cmd
- // level, so the outer quoting must be "suspended".
- ret.replace(QRegularExpression(QStringLiteral("(\\\\*)\"")), QStringLiteral("\"\\1\\1\\^\"\""));
- // The argument must not end with a \ since this would be interpreted
- // as escaping the quote -- rather put the \ behind the quote: e.g.
- // rather use "foo"\ than "foo\"
- qsizetype i = ret.length();
- while (i > 0 && ret.at(i - 1) == u'\\')
- --i;
- ret.insert(i, u'"');
- ret.prepend(u'"');
- }
- return ret;
-}
-
-static QString shellQuote(const QString &arg)
-{
- if (QDir::separator() == u'\\')
- return shellQuoteWin(arg);
- else
- return shellQuoteUnix(arg);
-}
-
static bool parseOptions()
{
QStringList arguments = QCoreApplication::arguments();
diff --git a/src/tools/shared/shellquote_shared.h b/src/tools/shared/shellquote_shared.h
new file mode 100644
index 0000000000..ff264008e5
--- /dev/null
+++ b/src/tools/shared/shellquote_shared.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SHELLQUOTE_SHARED_H
+#define SHELLQUOTE_SHARED_H
+
+#include <QDir>
+#include <QRegularExpression>
+#include <QString>
+
+// Copy-pasted from qmake/library/ioutil.cpp
+inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
+{
+ for (int x = arg.length() - 1; x >= 0; --x) {
+ ushort c = arg.unicode()[x].unicode();
+ if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
+ return true;
+ }
+ return false;
+}
+
+static QString shellQuoteUnix(const QString &arg)
+{
+ // Chars that should be quoted (TM). This includes:
+ static const uchar iqm[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
+ 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
+ }; // 0-32 \'"$`<>|;&(){}*?#!~[]
+
+ if (!arg.length())
+ return QLatin1String("\"\"");
+
+ QString ret(arg);
+ if (hasSpecialChars(ret, iqm)) {
+ ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
+ ret.prepend(QLatin1Char('\''));
+ ret.append(QLatin1Char('\''));
+ }
+ return ret;
+}
+
+static QString shellQuoteWin(const QString &arg)
+{
+ // Chars that should be quoted (TM). This includes:
+ // - control chars & space
+ // - the shell meta chars "&()<>^|
+ // - the potential separators ,;=
+ static const uchar iqm[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
+ };
+
+ if (!arg.length())
+ return QLatin1String("\"\"");
+
+ QString ret(arg);
+ if (hasSpecialChars(ret, iqm)) {
+ // Quotes are escaped and their preceding backslashes are doubled.
+ // It's impossible to escape anything inside a quoted string on cmd
+ // level, so the outer quoting must be "suspended".
+ ret.replace(QRegularExpression(QLatin1String("(\\\\*)\"")), QLatin1String("\"\\1\\1\\^\"\""));
+ // The argument must not end with a \ since this would be interpreted
+ // as escaping the quote -- rather put the \ behind the quote: e.g.
+ // rather use "foo"\ than "foo\"
+ int i = ret.length();
+ while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
+ --i;
+ ret.insert(i, QLatin1Char('"'));
+ ret.prepend(QLatin1Char('"'));
+ }
+ return ret;
+}
+
+static QString shellQuote(const QString &arg)
+{
+ if (QDir::separator() == QLatin1Char('\\'))
+ return shellQuoteWin(arg);
+ else
+ return shellQuoteUnix(arg);
+}
+
+#endif // SHELLQUOTE_SHARED_H