fix: unescape exec before pass this arg to wordexp
Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
parent
5597ba5c44
commit
f796535233
@ -9,6 +9,7 @@
|
|||||||
#include "propertiesForwarder.h"
|
#include "propertiesForwarder.h"
|
||||||
#include "dbus/instanceadaptor.h"
|
#include "dbus/instanceadaptor.h"
|
||||||
#include "launchoptions.h"
|
#include "launchoptions.h"
|
||||||
|
#include "desktopentry.h"
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@ -197,7 +198,8 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
|||||||
sendErrorReply(QDBusError::Failed, msg);
|
sendErrorReply(QDBusError::Failed, msg);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
execStr = toString(Actions.value());
|
|
||||||
|
execStr = Actions.value().toString();
|
||||||
if (execStr.isEmpty()) {
|
if (execStr.isEmpty()) {
|
||||||
QString msg{"maybe entry actions's format is invalid, abort launch."};
|
QString msg{"maybe entry actions's format is invalid, abort launch."};
|
||||||
qWarning() << msg;
|
qWarning() << msg;
|
||||||
@ -733,13 +735,21 @@ void ApplicationService::resetEntry(DesktopEntry *newEntry) noexcept
|
|||||||
emit scaleFactorChanged();
|
emit scaleFactorChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringList &fields)
|
QStringList ApplicationService::unescapeExecArgs(const QString &str) noexcept
|
||||||
{
|
{
|
||||||
LaunchTask task;
|
auto unescapedStr = unescape(str, true);
|
||||||
auto deleter = [](wordexp_t *word) { wordfree(word); };
|
if (unescapedStr.isEmpty()) {
|
||||||
|
qWarning() << "unescape Exec failed.";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto deleter = [](wordexp_t *word) {
|
||||||
|
wordfree(word);
|
||||||
|
delete word;
|
||||||
|
};
|
||||||
std::unique_ptr<wordexp_t, decltype(deleter)> words{new (std::nothrow) wordexp_t{0, nullptr, 0}, deleter};
|
std::unique_ptr<wordexp_t, decltype(deleter)> words{new (std::nothrow) wordexp_t{0, nullptr, 0}, deleter};
|
||||||
|
|
||||||
if (auto ret = wordexp(str.toLocal8Bit().constData(), words.get(), WRDE_SHOWERR); ret != 0) {
|
if (auto ret = wordexp(unescapedStr.toLocal8Bit(), words.get(), WRDE_SHOWERR); ret != 0) {
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
QString errMessage;
|
QString errMessage;
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
@ -771,6 +781,14 @@ LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringLis
|
|||||||
for (int i = 0; i < words->we_wordc; ++i) {
|
for (int i = 0; i < words->we_wordc; ++i) {
|
||||||
execList.emplace_back(words->we_wordv[i]);
|
execList.emplace_back(words->we_wordv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return execList;
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringList &fields) noexcept
|
||||||
|
{
|
||||||
|
LaunchTask task;
|
||||||
|
auto execList = unescapeExecArgs(str);
|
||||||
task.LaunchBin = execList.first();
|
task.LaunchBin = execList.first();
|
||||||
|
|
||||||
QRegularExpression re{"%[fFuUickdDnNvm]"};
|
QRegularExpression re{"%[fFuUickdDnNvm]"};
|
||||||
|
@ -5,25 +5,25 @@
|
|||||||
#ifndef APPLICATIONSERVICE_H
|
#ifndef APPLICATIONSERVICE_H
|
||||||
#define APPLICATIONSERVICE_H
|
#define APPLICATIONSERVICE_H
|
||||||
|
|
||||||
#include <QObject>
|
#include "applicationmanager1service.h"
|
||||||
#include <QDBusObjectPath>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QString>
|
|
||||||
#include <QDBusUnixFileDescriptor>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QUuid>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QDBusContext>
|
|
||||||
#include <QFile>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
#include "applicationmanagerstorage.h"
|
#include "applicationmanagerstorage.h"
|
||||||
#include "dbus/applicationmanager1service.h"
|
#include "dbus/applicationmanager1service.h"
|
||||||
#include "dbus/instanceservice.h"
|
#include "dbus/instanceservice.h"
|
||||||
#include "global.h"
|
|
||||||
#include "desktopentry.h"
|
|
||||||
#include "dbus/jobmanager1service.h"
|
#include "dbus/jobmanager1service.h"
|
||||||
#include "applicationmanager1service.h"
|
#include "desktopentry.h"
|
||||||
|
#include "global.h"
|
||||||
|
#include <QDBusContext>
|
||||||
|
#include <QDBusObjectPath>
|
||||||
|
#include <QDBusUnixFileDescriptor>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
QString getDeepinWineScaleFactor(const QString &appId) noexcept;
|
QString getDeepinWineScaleFactor(const QString &appId) noexcept;
|
||||||
double getScaleFactor() noexcept;
|
double getScaleFactor() noexcept;
|
||||||
@ -70,8 +70,8 @@ public:
|
|||||||
[[nodiscard]] bool terminal() const noexcept;
|
[[nodiscard]] bool terminal() const noexcept;
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// This property should implement with fuse guarded $XDG_CONFIG_HOME/autostart/.
|
// This property should implement with fuse guarded
|
||||||
// Current implementation has some problems,
|
// $XDG_CONFIG_HOME/autostart/. Current implementation has some problems,
|
||||||
Q_PROPERTY(bool AutoStart READ isAutoStart WRITE setAutoStart NOTIFY autostartChanged)
|
Q_PROPERTY(bool AutoStart READ isAutoStart WRITE setAutoStart NOTIFY autostartChanged)
|
||||||
[[nodiscard]] bool isAutoStart() const noexcept;
|
[[nodiscard]] bool isAutoStart() const noexcept;
|
||||||
void setAutoStart(bool autostart) noexcept;
|
void setAutoStart(bool autostart) noexcept;
|
||||||
@ -119,6 +119,9 @@ public:
|
|||||||
void resetEntry(DesktopEntry *newEntry) noexcept;
|
void resetEntry(DesktopEntry *newEntry) noexcept;
|
||||||
void detachAllInstance() noexcept;
|
void detachAllInstance() noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] LaunchTask unescapeExec(const QString &str, const QStringList &fields) noexcept;
|
||||||
|
[[nodiscard]] static QStringList unescapeExecArgs(const QString &str) noexcept;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onGlobalScaleFactorChanged() noexcept;
|
void onGlobalScaleFactorChanged() noexcept;
|
||||||
|
|
||||||
@ -165,7 +168,6 @@ private:
|
|||||||
DesktopFile m_desktopSource;
|
DesktopFile m_desktopSource;
|
||||||
QSharedPointer<DesktopEntry> m_entry{nullptr};
|
QSharedPointer<DesktopEntry> m_entry{nullptr};
|
||||||
QMap<QDBusObjectPath, QSharedPointer<InstanceService>> m_Instances;
|
QMap<QDBusObjectPath, QSharedPointer<InstanceService>> m_Instances;
|
||||||
[[nodiscard]] LaunchTask unescapeExec(const QString &str, const QStringList &fields);
|
|
||||||
[[nodiscard]] QVariant findEntryValue(const QString &group,
|
[[nodiscard]] QVariant findEntryValue(const QString &group,
|
||||||
const QString &valueKey,
|
const QString &valueKey,
|
||||||
EntryValueType type,
|
EntryValueType type,
|
||||||
|
@ -236,7 +236,7 @@ std::optional<DesktopEntry::Value> DesktopEntry::value(const QString &groupKey,
|
|||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString unescape(const QString &str) noexcept
|
QString unescape(const QString &str, bool shellMode) noexcept
|
||||||
{
|
{
|
||||||
QString unescapedStr;
|
QString unescapedStr;
|
||||||
for (qsizetype i = 0; i < str.size(); ++i) {
|
for (qsizetype i = 0; i < str.size(); ++i) {
|
||||||
@ -270,10 +270,13 @@ QString unescape(const QString &str) noexcept
|
|||||||
unescapedStr.append(';');
|
unescapedStr.append(';');
|
||||||
++i;
|
++i;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's': {
|
||||||
|
if (shellMode) { // for wordexp
|
||||||
|
unescapedStr.append('\\');
|
||||||
|
}
|
||||||
unescapedStr.append(' ');
|
unescapedStr.append(' ');
|
||||||
++i;
|
++i;
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +299,7 @@ QString toString(const DesktopEntry::Value &value) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto unescapedStr = unescape(str);
|
auto unescapedStr = unescape(str);
|
||||||
|
|
||||||
if (hasNonAsciiAndControlCharacters(unescapedStr)) {
|
if (hasNonAsciiAndControlCharacters(unescapedStr)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ bool operator==(const DesktopFile &lhs, const DesktopFile &rhs);
|
|||||||
|
|
||||||
bool operator!=(const DesktopFile &lhs, const DesktopFile &rhs);
|
bool operator!=(const DesktopFile &lhs, const DesktopFile &rhs);
|
||||||
|
|
||||||
QString unescape(const QString &str) noexcept;
|
QString unescape(const QString &str, bool shellMode = false) noexcept;
|
||||||
|
|
||||||
QString toLocaleString(const QStringMap &localeMap, const QLocale &locale) noexcept;
|
QString toLocaleString(const QStringMap &localeMap, const QLocale &locale) noexcept;
|
||||||
|
|
||||||
|
47
tests/ut_escapeexec.cpp
Normal file
47
tests/ut_escapeexec.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "dbus/applicationservice.h"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
TEST(UnescapeExec, blankSpace)
|
||||||
|
{
|
||||||
|
QList<std::pair<QString, QList<QString>>> testCases{
|
||||||
|
{
|
||||||
|
R"(/usr/bin/hello\sworld --arg1=val1 -h --str="rrr ggg bbb")",
|
||||||
|
{
|
||||||
|
"/usr/bin/hello world",
|
||||||
|
"--arg1=val1",
|
||||||
|
"-h",
|
||||||
|
"--str=rrr ggg bbb",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
R"("/usr/bin/hello world" a b -- "c d")",
|
||||||
|
{
|
||||||
|
"/usr/bin/hello world",
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"--",
|
||||||
|
"c d",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
R"("/usr/bin/hello\t\nworld" a b -- c d)",
|
||||||
|
{
|
||||||
|
"/usr/bin/hello\t\nworld",
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"--",
|
||||||
|
"c",
|
||||||
|
"d",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &testCase : testCases) {
|
||||||
|
EXPECT_EQ(ApplicationService::unescapeExecArgs(testCase.first), testCase.second);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user