From ff5f2062c31a4082dfa5916079dec30166875193 Mon Sep 17 00:00:00 2001 From: ComixHe Date: Mon, 6 Nov 2023 11:30:54 +0800 Subject: [PATCH] fix: add necessary check before take execArgs Signed-off-by: ComixHe --- src/dbus/applicationservice.cpp | 31 +++++++++++++++++++++-------- src/dbus/applicationservice.h | 2 +- src/dbus/jobmanager1service.h | 1 + src/dbus/processguesser1service.cpp | 8 +++++++- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/dbus/applicationservice.cpp b/src/dbus/applicationservice.cpp index 6afae44..e74f56b 100644 --- a/src/dbus/applicationservice.cpp +++ b/src/dbus/applicationservice.cpp @@ -213,8 +213,13 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL optionsMap.insert("_hooks", hooks); } auto cmds = generateCommand(optionsMap); + auto task = unescapeExec(execStr, fields); + if (!task) { + sendErrorReply(QDBusError::InternalError, "Invalid Command."); + return {}; + } - auto [bin, execCmds, res] = unescapeExec(execStr, fields); + auto [bin, execCmds, res] = std::move(task); if (bin.isEmpty()) { qCritical() << "error command is detected, abort."; sendErrorReply(QDBusError::Failed); @@ -735,12 +740,12 @@ void ApplicationService::resetEntry(DesktopEntry *newEntry) noexcept emit scaleFactorChanged(); } -QStringList ApplicationService::unescapeExecArgs(const QString &str) noexcept +std::optional ApplicationService::unescapeExecArgs(const QString &str) noexcept { auto unescapedStr = unescape(str, true); if (unescapedStr.isEmpty()) { qWarning() << "unescape Exec failed."; - return {}; + return std::nullopt; } auto deleter = [](wordexp_t *word) { @@ -755,8 +760,7 @@ QStringList ApplicationService::unescapeExecArgs(const QString &str) noexcept switch (ret) { case WRDE_BADCHAR: errMessage = "BADCHAR"; - qWarning() << "wordexp error: " << errMessage; - return {}; + break; case WRDE_BADVAL: errMessage = "BADVAL"; break; @@ -773,7 +777,7 @@ QStringList ApplicationService::unescapeExecArgs(const QString &str) noexcept errMessage = "unknown"; } qWarning() << "wordexp error: " << errMessage; - return {}; + return std::nullopt; } } @@ -788,9 +792,20 @@ QStringList ApplicationService::unescapeExecArgs(const QString &str) noexcept LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringList &fields) noexcept { LaunchTask task; - auto execList = unescapeExecArgs(str); - task.LaunchBin = execList.first(); + auto opt = unescapeExecArgs(str); + if (!opt.has_value()) { + qWarning() << "unescapeExecArgs failed."; + return {}; + } + + auto execList = std::move(opt).value(); + if (execList.isEmpty()) { + qWarning() << "exec format is invalid."; + return {}; + } + + task.LaunchBin = execList.first(); QRegularExpression re{"%[fFuUickdDnNvm]"}; auto matcher = re.match(str); if (!matcher.hasMatch()) { diff --git a/src/dbus/applicationservice.h b/src/dbus/applicationservice.h index 3e09581..eea15a7 100644 --- a/src/dbus/applicationservice.h +++ b/src/dbus/applicationservice.h @@ -124,7 +124,7 @@ public: const QLocale &locale = getUserLocale()) const noexcept; [[nodiscard]] LaunchTask unescapeExec(const QString &str, const QStringList &fields) noexcept; - [[nodiscard]] static QStringList unescapeExecArgs(const QString &str) noexcept; + [[nodiscard]] static std::optional unescapeExecArgs(const QString &str) noexcept; private Q_SLOTS: void onGlobalScaleFactorChanged() noexcept; diff --git a/src/dbus/jobmanager1service.h b/src/dbus/jobmanager1service.h index ff559bf..d972064 100644 --- a/src/dbus/jobmanager1service.h +++ b/src/dbus/jobmanager1service.h @@ -28,6 +28,7 @@ struct LaunchTask LaunchTask(LaunchTask &&) = default; LaunchTask &operator=(const LaunchTask &) = default; LaunchTask &operator=(LaunchTask &&) = default; + explicit operator bool() const { return !LaunchBin.isEmpty() and !command.isEmpty(); } QString LaunchBin; QStringList command; QVariantList Resources; diff --git a/src/dbus/processguesser1service.cpp b/src/dbus/processguesser1service.cpp index af0006e..8c0f487 100644 --- a/src/dbus/processguesser1service.cpp +++ b/src/dbus/processguesser1service.cpp @@ -74,7 +74,13 @@ QString ProcessGuesser1Service::GuessApplicationId(const QDBusUnixFileDescriptor continue; } - auto execList = ApplicationService::unescapeExecArgs(exec); + auto opt = ApplicationService::unescapeExecArgs(exec); + if (!opt) { + sendErrorReply(QDBusError::InternalError); + return {}; + } + + auto execList = std::move(opt).value(); if (execList.isEmpty()) { sendErrorReply(QDBusError::InternalError); return {};