From 8205c8f711e76361a99208ad6a77fd0987ccfa68 Mon Sep 17 00:00:00 2001 From: dengbo Date: Wed, 24 Jun 2026 20:37:33 +0800 Subject: [PATCH] fix: improve hook command execution and parsing 1. Change hook command execution from shell `-c` argument to stdin pipe to avoid shell quoting and injection issues 2. Add `extractValue` lambda that trims whitespace and strips surrounding quotes (single or double) from extracted hook command values 3. Apply the new extraction logic to pre-install, post-install, and post-uninstall hook command parsing 4. Include `linglong/common/strings.h` for the `trim` utility function Influence: 1. Test pre-install hooks with double-quoted command values 2. Test post-install hooks with single-quoted command values 3. Test post-uninstall hooks with whitespace-padded command values 4. Verify hook commands with special characters execute correctly via stdin 5. Test hook execution with unquoted command values to ensure backward compatibility 6. Verify that commands containing quotes or shell metacharacters are handled safely --- libs/utils/src/linglong/utils/hooks.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/libs/utils/src/linglong/utils/hooks.cpp b/libs/utils/src/linglong/utils/hooks.cpp index b1eb037d4..e085d226d 100644 --- a/libs/utils/src/linglong/utils/hooks.cpp +++ b/libs/utils/src/linglong/utils/hooks.cpp @@ -9,6 +9,7 @@ #include "cmd.h" #include "configure.h" #include "linglong/common/error.h" +#include "linglong/common/strings.h" #include "linglong/utils/error/error.h" #include "linglong/utils/log/log.h" @@ -46,7 +47,8 @@ utils::error::Result executeHookCommands( cmd.setEnv(name, value); } - auto result = cmd.exec({ "-c", command }); + cmd.toStdin(command); + auto result = cmd.exec({}); if (!result.has_value()) { return LINGLONG_ERR( fmt::format("Hook command '{}' failed: {}.", command, result.error())); @@ -59,6 +61,17 @@ utils::error::Result InstallHookManager::parseInstallHooks() { LINGLONG_TRACE("Parsing install hooks"); + auto extractValue = [](const std::string &line, std::size_t prefixLen) -> std::string { + auto trimmed = linglong::common::strings::trim(std::string_view(line).substr(prefixLen)); + if (trimmed.size() >= 2 + && ((trimmed.front() == '"' && trimmed.back() == '"') + || (trimmed.front() == '\'' && trimmed.back() == '\''))) { + trimmed.remove_prefix(1); + trimmed.remove_suffix(1); + } + return std::string(trimmed); + }; + std::error_code ec; for (const auto &entry : std::filesystem::directory_iterator(LINGLONG_INSTALL_HOOKS_DIR, ec)) { if (ec) { @@ -84,21 +97,21 @@ utils::error::Result InstallHookManager::parseInstallHooks() std::size_t pos = line.find(PRE_INSTALL_ACTION_PREFIX); if (pos != std::string::npos) { preInstallCommands.emplace_back( - line.substr(pos + PRE_INSTALL_ACTION_PREFIX.length())); + extractValue(line, pos + PRE_INSTALL_ACTION_PREFIX.length())); break; } pos = line.find(POST_INSTALL_ACTION_PREFIX); if (pos != std::string::npos) { postInstallCommands.emplace_back( - line.substr(pos + POST_INSTALL_ACTION_PREFIX.length())); + extractValue(line, pos + POST_INSTALL_ACTION_PREFIX.length())); break; } pos = line.find(POST_UNINSTALL_ACTION_PREFIX); if (pos != std::string::npos) { postUninstallCommands.emplace_back( - line.substr(pos + POST_UNINSTALL_ACTION_PREFIX.length())); + extractValue(line, pos + POST_UNINSTALL_ACTION_PREFIX.length())); break; } }