From 29b1d2995e754788d693dab3b50e39deab68fbbd Mon Sep 17 00:00:00 2001 From: reddevillg Date: Fri, 15 May 2026 13:31:08 +0800 Subject: [PATCH] fix: auto-disable XDP for non-conforming apps Disable XDP integration when the appid does not conform xdp id Signed-off-by: reddevillg --- libs/linglong/src/linglong/cli/cli.cpp | 9 ++ libs/linglong/tests/ll-tests/CMakeLists.txt | 1 + .../ll-tests/src/linglong/utils/xdp_test.cpp | 101 ++++++++++++++++++ libs/utils/CMakeLists.txt | 1 + libs/utils/src/linglong/utils/xdp.h | 53 +++++++++ 5 files changed, 165 insertions(+) create mode 100644 libs/linglong/tests/ll-tests/src/linglong/utils/xdp_test.cpp create mode 100644 libs/utils/src/linglong/utils/xdp.h diff --git a/libs/linglong/src/linglong/cli/cli.cpp b/libs/linglong/src/linglong/cli/cli.cpp index 0c9246772..96a793803 100644 --- a/libs/linglong/src/linglong/cli/cli.cpp +++ b/libs/linglong/src/linglong/cli/cli.cpp @@ -43,6 +43,7 @@ #include "linglong/utils/namespace.h" #include "linglong/utils/runtime_config.h" #include "linglong/utils/xdg/directory.h" +#include "linglong/utils/xdp.h" #include "ocppi/runtime/ExecOption.hpp" #include "ocppi/runtime/RunOption.hpp" #include "ocppi/runtime/Signal.hpp" @@ -867,6 +868,14 @@ int Cli::runResolvedContext(runtime::RunContext &runContext, return -1; } + const auto &appid = runContext.getTargetID(); + if (!options.disableXdp.has_value() && !utils::isValidXdgDesktopPortalId(appid)) { + LogW("appid '{}' doesn't conform to XDP ID specification, disabling XDP integration. " + "Use --enable-xdp to override.", + appid); + runOptions.disableXdp = true; + } + auto container = this->containerBuilder.createRunContainer(runContext, runOptions); if (!container) { this->printer.printErr(container.error()); diff --git a/libs/linglong/tests/ll-tests/CMakeLists.txt b/libs/linglong/tests/ll-tests/CMakeLists.txt index cbd697af8..77d9e5519 100644 --- a/libs/linglong/tests/ll-tests/CMakeLists.txt +++ b/libs/linglong/tests/ll-tests/CMakeLists.txt @@ -64,6 +64,7 @@ pfl_add_executable( src/linglong/utils/sha256_test.cpp src/linglong/utils/transaction_test.cpp src/linglong/utils/xdg/directory_test.cpp + src/linglong/utils/xdp_test.cpp src/main.cpp diff --git a/libs/linglong/tests/ll-tests/src/linglong/utils/xdp_test.cpp b/libs/linglong/tests/ll-tests/src/linglong/utils/xdp_test.cpp new file mode 100644 index 000000000..f85453a20 --- /dev/null +++ b/libs/linglong/tests/ll-tests/src/linglong/utils/xdp_test.cpp @@ -0,0 +1,101 @@ +/* + * SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include + +#include "linglong/utils/xdp.h" + +using namespace linglong::utils; + +TEST(IsValidXdgDesktopPortalIdTest, ValidStandardId) +{ + EXPECT_TRUE(isValidXdgDesktopPortalId("org.example.app")); + EXPECT_TRUE(isValidXdgDesktopPortalId("com.deepin.calculator")); + EXPECT_TRUE(isValidXdgDesktopPortalId("org.freedesktop.portal")); +} + +TEST(IsValidXdgDesktopPortalIdTest, ValidWithHyphenInLastSegment) +{ + EXPECT_TRUE(isValidXdgDesktopPortalId("org.example.my-app")); + EXPECT_TRUE(isValidXdgDesktopPortalId("com.deepin.app-launcher")); +} + +TEST(IsValidXdgDesktopPortalIdTest, ValidWithUnderscore) +{ + EXPECT_TRUE(isValidXdgDesktopPortalId("org.example_my.app")); + EXPECT_TRUE(isValidXdgDesktopPortalId("com.deepin.my_app")); +} + +TEST(IsValidXdgDesktopPortalIdTest, ValidWithDigits) +{ + EXPECT_TRUE(isValidXdgDesktopPortalId("org.example.app2")); + EXPECT_TRUE(isValidXdgDesktopPortalId("org.2example.app")); +} + +TEST(IsValidXdgDesktopPortalIdTest, ValidMultiSegment) +{ + EXPECT_TRUE(isValidXdgDesktopPortalId("org.deepin.linglong.app")); + EXPECT_TRUE(isValidXdgDesktopPortalId("a.b.c.d.e")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidSingleSegment) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("single")); + EXPECT_FALSE(isValidXdgDesktopPortalId("app")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidEmptyString) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidHyphenInNonLastSegment) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("org.my-app.app")); + EXPECT_FALSE(isValidXdgDesktopPortalId("my-org.example.app")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidEmptySegment) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("org..app")); + EXPECT_FALSE(isValidXdgDesktopPortalId(".org.app")); + EXPECT_FALSE(isValidXdgDesktopPortalId("org.app.")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidSpecialChars) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("org.example.app!")); + EXPECT_FALSE(isValidXdgDesktopPortalId("org.example.app@home")); + EXPECT_FALSE(isValidXdgDesktopPortalId("org/example/app")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidSlashInId) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("org.deepin.calculator/stable")); + EXPECT_FALSE(isValidXdgDesktopPortalId("org/deepin/app")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidHyphenInMultipleNonLastSegments) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("my-org.my-app.app")); +} + +TEST(IsValidXdgDesktopPortalIdTest, ValidHyphenOnlyInLastSegment) +{ + EXPECT_TRUE(isValidXdgDesktopPortalId("org.example.a-b")); + EXPECT_TRUE(isValidXdgDesktopPortalId("org.example.a-b-c")); +} + +TEST(IsValidXdgDesktopPortalIdTest, InvalidLastSegmentEmpty) +{ + EXPECT_FALSE(isValidXdgDesktopPortalId("org.example.")); +} + +TEST(IsValidXdgDesktopPortalIdTest, TwoSegmentsValid) +{ + EXPECT_TRUE(isValidXdgDesktopPortalId("org.app")); + EXPECT_TRUE(isValidXdgDesktopPortalId("a.b")); +} diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index 867c0ece4..3991e0534 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -48,6 +48,7 @@ pfl_add_library( src/linglong/utils/transaction.h src/linglong/utils/xdg/directory.cpp src/linglong/utils/xdg/directory.h + src/linglong/utils/xdp.h COMPILE_FEATURES PUBLIC cxx_std_17 diff --git a/libs/utils/src/linglong/utils/xdp.h b/libs/utils/src/linglong/utils/xdp.h new file mode 100644 index 000000000..011ced05c --- /dev/null +++ b/libs/utils/src/linglong/utils/xdp.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include +#include + +namespace linglong::utils { + +inline bool isValidXdgDesktopPortalId(std::string_view appid) noexcept +{ + std::vector segments; + + size_t start = 0; + for (size_t i = 0; i < appid.size(); ++i) { + if (appid[i] == '.') { + segments.push_back(appid.substr(start, i - start)); + start = i + 1; + } + } + segments.push_back(appid.substr(start)); + + if (segments.size() < 2) { + return false; + } + + for (size_t i = 0; i + 1 < segments.size(); ++i) { + if (segments[i].empty()) { + return false; + } + if (!std::all_of(segments[i].begin(), segments[i].end(), [](char c) { + return std::isalnum(static_cast(c)) || c == '_'; + })) { + return false; + } + } + + const auto &last = segments.back(); + if (last.empty()) { + return false; + } + return std::all_of(last.begin(), last.end(), [](char c) { + return std::isalnum(static_cast(c)) || c == '_' || c == '-'; + }); +} + +} // namespace linglong::utils