Skip to content

refactor(utils): use Qt API for command lookup#858

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:release/eaglefrom
tianming-1996:security/baseutils-command-lookup
Jun 3, 2026
Merged

refactor(utils): use Qt API for command lookup#858
deepin-bot[bot] merged 1 commit into
linuxdeepin:release/eaglefrom
tianming-1996:security/baseutils-command-lookup

Conversation

@tianming-1996

Copy link
Copy Markdown

Use QStandardPaths to check executable availability.

使用QStandardPaths检查可执行命令是否存在。

Log: 使用Qt接口替代外部which命令查询
Task:https://pms.uniontech.com/task-view-390623.html Influence: 仅影响dman命令存在性检查逻辑,F1帮助快捷键行为保持不变。

Use QStandardPaths to check executable availability.

使用QStandardPaths检查可执行命令是否存在。

Log: 使用Qt接口替代外部which命令查询
Task:https://pms.uniontech.com/task-view-390623.html
Influence: 仅影响dman命令存在性检查逻辑,F1帮助快捷键行为保持不变。
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: tianming-1996

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的Git Diff,这次修改对 isCommandExist 函数进行了重构,用 QStandardPaths::findExecutable 替换了原本通过 QProcess 调用系统命令 which 的实现。

总体来说,这是一次非常优秀的重构。以下是针对各个维度的详细审查意见:

1. 语法逻辑 (✅ 优秀)

  • 修改前:通过启动外部进程 which 来查找命令,依赖进程的退出码来判断。逻辑上存在平台兼容性问题(Windows下没有原生的which命令,通常需要用where)。
  • 修改后:使用Qt内置的 QStandardPaths::findExecutable。该函数在底层会自动跨平台处理(Linux/macOS 查找 PATH,Windows 查找 PATH 及常用应用目录),逻辑更加健壮且符合Qt编程规范。isEmpty() 的取反逻辑也完全正确。

2. 代码质量 (✅ 显著提升)

  • 可读性与维护性:原本4行代码缩减为1行,消除了模板字符串 QStringLiteral 和列表构造的冗余代码,意图更加直观。
  • 资源管理:移除了 QProcess 对象的创建,不再需要分配进程相关的系统资源,对象生命周期管理更简单。
  • 无副作用:原实现中 proc.waitForFinished(1000) 如果超时,进程可能会被遗留。新实现纯粹是本地文件系统检索,没有任何异步或遗留进程的风险。

3. 代码性能 (✅ 大幅优化)

  • 开销降低:原实现每次调用都要创建一个 QProcess,这涉及到系统调用(fork + exec 或 Windows的 CreateProcess),开销极大。
  • 耗时可控:原实现设定了 1000ms 的超时时间。如果系统负载高或PATH极长,which 命令可能会卡顿甚至触发超时导致误判。findExecutable 仅在本地遍历文件系统目录,速度极快且耗时完全可控,没有阻塞等待外部进程的隐患。

4. 代码安全 (✅ 消除安全隐患)

  • 命令注入风险:虽然原代码使用 QStringList() 传参,比拼接字符串稍微安全,但如果 command 参数包含特殊字符,仍可能引发不可预期的行为。
  • 环境变量篡改:依赖 which 命令容易受到恶意环境变量(如被篡改的 $PATH 指向恶意目录)的影响。QStandardPaths::findExecutable 同样读取环境变量,但它只做路径匹配,不会执行任何外部脚本,切断了命令执行的攻击面。

💡 进阶改进建议

虽然当前修改已经很好,但为了让代码达到工业级标准,我建议在性能安全性上做进一步的微调:

1. 性能优化:传递 const QString&
当前函数签名是 bool BaseUtils::isCommandExist(QString command),每次调用都会产生一次 QString 的深拷贝。对于可能频繁调用的工具函数,建议改为常量引用。

2. 安全性增强:校验输入合法性
QStandardPaths::findExecutable 如果传入包含路径分隔符(如 ./malicious../bin/cmd)的字符串,它会直接检查该相对/绝对路径是否存在并返回,这可能导致潜在的相对路径执行风险。如果你只想检查系统 PATH 中的命令,应当拦截包含路径分隔符的输入。

改进后的代码示例:

// 在头文件中修改声明
bool BaseUtils::isCommandExist(const QString& command);

// 在 cpp 文件中修改实现
bool BaseUtils::isCommandExist(const QString& command)
{
    // 安全校验:如果传入的命令包含路径分隔符,直接返回 false,
    // 强制只允许搜索系统 PATH 中的纯命令名,避免相对路径带来的安全隐患。
    if (command.contains(QChar('/')) || command.contains(QChar('\\'))) {
        return false; 
    }
    
    return !QStandardPaths::findExecutable(command).isEmpty();
}

总结:你的核心重构思路完全正确,极大地提升了代码质量。如果采纳上述关于常量引用和路径分隔符校验的建议,代码将更加完美!

@tianming-1996

Copy link
Copy Markdown
Author

/merge

@deepin-bot deepin-bot Bot merged commit cab7e58 into linuxdeepin:release/eagle Jun 3, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants