Skip to content

feat: support passing extra launch arguments to applications via -l option#361

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
18202781743:master
Jun 3, 2026
Merged

feat: support passing extra launch arguments to applications via -l option#361
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743
Copy link
Copy Markdown
Contributor

  1. Add a new command-line option -l/--launch-args to dde-am tool
  2. Implement setExtraArgs and parseLaunchArgs in Launcher class
  3. Use wordexp for proper shell-like argument parsing (supports quotes
    and escaping)
  4. Pass extra arguments through DBus interface to the application
    launcher service
  5. Append extra arguments to command list before executing the
    application
  6. Update help text with an example showing how to pass complex
    arguments with quotes

Log: You can now pass additional arguments to applications when
launching from command line. For example: dde-am org.deepin.dde.control-
center -l '--page="wallpaper"'

Influence:

  1. Test basic extra arguments: dde-am org.deepin.calculator -l 'test.txt'
  2. Test arguments with quotes: dde-am org.deepin.dde.control-center -l '--page="wallpaper"'
  3. Test multiple arguments: dde-am org.deepin.calculator -l '-a -b --option=value'
  4. Test empty arguments: verify no arguments passed when -l is not used
  5. Test argument parsing with shell special characters
  6. Test backward compatibility - existing applications without -l should
    work as before

feat: 支持通过-l选项传递额外启动参数给应用程序

  1. 为dde-am工具添加新的-l/--launch-args命令行选项
  2. 在Launcher类中实现setExtraArgsparseLaunchArgs方法
  3. 使用wordexp进行类shell参数解析(支持引号和转义)
  4. 通过DBus接口将额外参数传递给应用程序启动服务
  5. 在执行应用程序前将额外参数追加到命令列表
  6. 更新帮助文本,展示如何传递带引号的复杂参数示例

Log: 现在可以在命令行启动应用时传递额外参数。例如:dde-am
org.deepin.dde.control-center -l '--page="wallpaper"'

Influence:

  1. 测试基本额外参数:dde-am org.deepin.calculator -l 'test.txt'
  2. 测试带引号的参数:dde-am org.deepin.dde.control-center -l '--page="wallpaper"'
  3. 测试多个参数:dde-am org.deepin.calculator -l '-a -b --option=value'
  4. 测试空参数:不使用-l时验证不传递额外参数
  5. 测试含shell特殊字符的参数解析
  6. 测试向后兼容性 - 不使用-l的现有应用应正常工作

PMS: BUG-295555

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @18202781743, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Comment thread apps/dde-am/src/launcher.cpp Outdated
Comment thread apps/dde-am/src/main.cpp Outdated
Comment thread apps/dde-am/src/main.cpp Outdated
18202781743 added a commit to 18202781743/dde-application-manager that referenced this pull request Jun 3, 2026
Replace the -l/--launch-args option with standard '--' separator for
passing extra arguments to application Exec commands.

Usage: dde-am org.deepin.xxx -- --show -p "wallpaper"

Changes:
- Extract args after '--' from argv directly in main()
- Add setExtraArgs() to Launcher class
- Pass extra args via DBus options map (_extraArgs)
- Server appends extra args to command list before execution
- Remove wordexp dependency from client side

feat(dde-am): 使用 -- 分隔符传递额外启动参数

用标准的 '--' 分隔符替代 -l/--launch-args 选项,
传递额外参数给应用程序的 Exec 命令。

用法: dde-am org.deepin.xxx -- --show -p "wallpaper"

Log: 使用 -- 分隔符替代 -l 选项传递额外启动参数
Issue: Fixes linuxdeepin#361
Influence: dde-am 命令行启动应用时,使用 -- 分隔符后的参数作为
Exec 的额外参数,替代原有的 -l 选项方式。
@18202781743 18202781743 requested a review from BLumia June 3, 2026 02:35
Replace -l/--launch-args with standard '--' separator for passing
extra arguments to application Exec commands.

Usage: dde-am org.deepin.xxx -- --show -p "wallpaper"

1. Extract args after '--' from argv directly in main()
2. Add setExtraArgs() to Launcher class
3. Pass extra args via DBus options map (_extraArgs)
4. Server appends extra args to command list before execution
5. Remove wordexp dependency from client side

feat(dde-am): 使用 -- 分隔符替代 -l 选项传递额外启动参数

1. 用标准 '--' 分隔符替代 -l/--launch-args 选项
2. 从 argv 直接提取 '--' 之后的参数,由 shell 负责引号解析
3. 通过 DBus options map 的 _extraArgs 传递给服务端
4. 服务端在执行命令前将额外参数追加到命令列表
5. 更新帮助文本,展示 -- 分隔符用法

Log: 使用 -- 分隔符替代 -l 选项传递额外启动参数
PMS: BUG-295555
Issue: Fixes linuxdeepin#361
Influence: dde-am 命令行启动应用时,使用 -- 分隔符后的参数作为
Exec 的额外参数,替代原有的 -l 选项方式,避免 wordexp 安全风险。
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这是一份针对该 Git Diff 的详细代码审查报告。本次修改的主要目的是为 dde-am(深度应用管理器)增加向被启动应用程序传递额外参数(-- 后的参数)的功能。整体逻辑清晰,但在健壮性、安全性和性能方面有一些可以改进的空间。

1. 语法与逻辑

问题 1:arguments.removeLast() 的潜在逻辑漏洞
main.cpphandleLaunchApp 函数中,通过循环 removeLast() 来移除 QCommandLineParser 解析出的多余位置参数。

if (!extraArgs.isEmpty()) {
    for (int i = 0; i < extraArgs.size() && !arguments.isEmpty(); ++i) {
        arguments.removeLast();
    }
}

风险:这段逻辑建立在一个强假设上:QCommandLineParser 解析出的位置参数末尾,一定恰好是 extraArgs 的内容。如果用户输入格式不规范,或者 Qt 的解析行为在不同版本下有细微差异(例如忽略了 --),可能会导致误删合法的位置参数(如 appId),或者少删了参数导致 appId 后面跟着多余参数。
改进建议:既然已经在 main 函数中通过原生 argv 提取了 extraArgs,建议直接使用 arguments 的第一个元素作为 appId,完全抛弃后续的位置参数,避免这种“对齐删除”的脆弱逻辑。

问题 2:QStringList::append 的隐式深度拷贝
main.cpp 中提取参数时:

extraArgs.append(QString::fromLocal8Bit(argv[i]));

风险:在循环中不断向 QStringList 追加元素,可能会触发多次内存重新分配。虽然参数通常不多,影响不大,但作为最佳实践,应预先分配内存。

2. 代码质量

问题 1:手动遍历 argv 缺乏封装与复用性
main.cpp 中,使用原生 for 循环和 qstrcmp 来寻找 -- 分隔符。

bool foundDashDash = false;
for (int i = 1; i < argc; ++i) {
    if (qstrcmp(argv[i], "--") == 0) { ... }
}

改进建议:这部分逻辑可以提取为一个独立的内联函数或 Lambda,增强代码可读性。另外,QString::fromLocal8Bit 是正确的,因为环境编码可能不是 UTF-8,这点处理得很好,值得肯定。

问题 2:setExtraArgs 的传值方式
launcher.h 中:

void setExtraArgs(const QStringList &args);

改进建议:对于资源占用较大的容器类型如 QStringList,如果不需要保留外部传入对象的引用,建议按值传递并使用 std::move,以利用移动语义避免不必要的深拷贝。

3. 代码性能

问题 1:newCommands.reserve 的容量估算
applicationservice.cpp 中:

const int estimatedSize = 6 + cmds.size() + task.command.size() + extraArgs.size() + (value.isValid() ? 1 : 0);
newCommands.reserve(estimatedSize);

评价:这是一个很好的性能优化点,作者考虑到了新增的 extraArgs 可能带来的内存重分配开销,并正确更新了 reserve 的估算值,这非常棒。

问题 2:newCommands << std::move(extraArgs);
在追加额外参数时使用了 std::move,避免了拷贝,性能处理得当。

4. 代码安全

⚠️ 严重问题:命令注入风险
applicationservice.cpp 中,extraArgs 被直接追加到了 newCommands 中,并最终通过 QProcess 执行:

newCommands << std::move(extraArgs);
// ...
QProcess process;
// ...
process.start(bin, newCommands);

风险分析extraArgs 来源于客户端(命令行或 DBus 调用者)。如果 dde-am 是以高权限(如 root 或特定系统用户)运行的服务,而低权限用户可以通过 DBus 触发此 Launch 方法,那么恶意用户可以注入诸如 ; rm -rf / 或利用 shell 解释器的其他特性进行提权攻击。
安全确认:由于代码最终使用的是 QProcess::start(const QString &program, const QStringList &arguments),这个重载函数是安全的,它不会通过 shell 解释器(如 /bin/sh -c)执行命令,而是直接使用 execvp,因此参数会被原样传递,不受 shell 注入影响。
遗留风险:如果后续有人将这里的 QProcess 改为 QProcess::start(const QString &command)(单参数重载,会走 shell),则会立刻引发严重的命令注入漏洞。建议在代码旁加注释警示。


改进后的代码建议

1. launcher.h - 优化传值方式

// 按值传递,并在实现中使用 std::move
void setExtraArgs(QStringList args);

2. launcher.cpp - 配合头文件修改

void Launcher::setExtraArgs(QStringList args)
{
    m_extraArgs = std::move(args); // 利用移动语义
}

3. main.cpp - 优化参数提取与清理逻辑

int main(int argc, char *argv[])
{
    const QCoreApplication app{argc, argv};

    QStringList extraArgs;
    {
        bool foundDashDash = false;
        // 预先估算参数数量,减少内存分配
        int dashDashIndex = -1;
        for (int i = 1; i < argc; ++i) {
            if (qstrcmp(argv[i], "--") == 0) {
                foundDashDash = true;
                dashDashIndex = i;
                continue;
            }
            if (foundDashDash) {
                extraArgs.push_back(QString::fromLocal8Bit(argv[i]));
            }
        }
    }

    // ... (中间省略) ...

    return handleLaunchApp(parser, envOption, actionOption, launchedByUserOption, autostartOption, launchTypeOption, extraArgs);
}

int handleLaunchApp(const QCommandLineParser &parser,
                    const QCommandLineOption &envOption,
                    const QCommandLineOption &actionOption,
                    const QCommandLineOption &launchedByUserOption,
                    const QCommandLineOption &autostartOption,
                    const QCommandLineOption &launchTypeOption,
                    const QStringList &extraArgs)
{
    // ...
    auto arguments = parser.positionalArguments();
    
    // 改进:不再使用危险的 removeLast 对齐逻辑
    // 因为我们已经通过 argv 提取了 extraArgs,这里只需要取第一个位置参数作为 appId/inputArg 即可
    QString inputArg;
    if (!arguments.isEmpty()) {
        inputArg = arguments.takeFirst();
    } else {
        // 错误处理:缺少 appId
        // ...
    }
    // ...
}

4. applicationservice.cpp - 增加安全注释

// SECURITY NOTE: extraArgs must be passed as separate arguments to QProcess::start(command, args)
// DO NOT concatenate them into a single string and use QProcess::start(command), 
// as that would introduce shell injection vulnerabilities.
newCommands << std::move(extraArgs);

QProcess process;
const auto &bin = getApplicationLauncherBinary();
qDebug().noquote() << "Launcher path:" << bin << ", Run with commands:" << newCommands;

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia

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

@18202781743
Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Jun 3, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit fcdcc91 into linuxdeepin:master Jun 3, 2026
15 of 17 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