/assign @hanggongmao1
我来修复该字符串解析问题,回归测试和中英文测试说明已准备,将提交关联 PR。


问题确认:属实 ✅(已在 master 37fe471ed 本地复现并验证修复方案)
1. 缺陷根因
json_info.py:383-393 的 _consume_escape 判定反斜杠转义时不感知单引号状态:_consume_command_char(json_info.py:430)的消费者链把 _consume_escape 排在最前,因此单引号内的 \ 也会置 escape_next=True,把紧随其后的结束单引号当作被转义的字面字符吃掉。
而 POSIX shell 语义中单引号内一切字符均为字面(反斜杠无特殊含义),'foo\' 是合法闭合的 foo\。
后果链:结束引号被吃 → in_single_quote 无法复位 → 其后所有字符(含 ; && || | & 分隔符)被 _consume_quoted_char 当引号内字符吞掉 → split_ignoring_quotes 返回单段 → sudo_cmd/su_cmd 只检查该段的 parts[0],后续 sudo/su 命令不会被改写。
2. 本地复现结果(Python 3.12.3,纯字符串处理,未执行任何远端命令)
| 场景 | 原版输出 | 期望输出 |
|---|---|---|
split_ignoring_quotes("printf '%s' 'foo\'; sudo id") |
["printf '%s' 'foo\'; sudo id"](单段,; 丢失) |
["printf '%s' 'foo\\'", ";", "sudo id"] |
sudo_cmd 同命令 |
原样返回,sudo id 未加 -S -p '' |
printf '%s' 'foo\' ; sudo -S -p '' id |
管道符 echo 'a\' | sudo tee /tmp/x |
单段,| 丢失 |
三段,| 正确识别 |
shlex 交叉核对:shlex.split 产出 ['printf', '%s', 'foo\\;', 'sudo', 'id'],POSIX 词法确认 \ 后的单引号是闭合引号,与报告判断一致。
3. 影响面
- 消费链入口唯一:
dispatcher_common.exec_command_with_auth(dispatcher_common.py:199-200)逐级调用sudo_cmd→su_cmd后经client.exec_command(cmd)下发;调用方为 exec_cmd.py:44、exec_realtime_cmd.py:201,覆盖集群链路诊断工具的所有远端命令执行。 - 实际后果:提权改写失效后,
sudo在未分配 tty 的 SSH exec 通道上无法读密码(exec_command_with_auth虽仍向 stdin 写密码,但对未加-S的 sudo 无效),远端提权命令执行失败(NOPASSWD 场景除外)。 - 该转义逻辑自
ef057cfd2(工具首次引入)即如此,非近期回归;仓内escape_next仅json_info.py一处,缺陷范围收敛。
4. 修复评估(本地已验证)
issue 建议的修法正确且为一行改动:_consume_escape 首个条件增加 not state["in_single_quote"],单引号内的 \ 落到 _consume_quoted_char 按字面处理。本地前后对照验证:
- 修复后输出与 issue 期望逐字一致(见上表);
- 回归面不变:引号外转义(
a\;b不分割)、双引号内转义("a\";b"不分割)、</>重定向与&判定、whoami && sudo whoami && whoami、su转换均保持原行为; - 边界说明:修复后
escape_next只在引号外/双引号内置位,转义恰好消费一个字符,不存在跨引号边界泄漏路径。
5. 备注
- 报告者已
/assign并计划提交含 7 个 CPU 测试方法的关联 PR,本分析结论与其报告一致,可作交叉确认。 - 代码位于
experimental/cluster_link_diag/(实验性集群链路诊断工具),不涉及src/架构分层约束。
本回复为 AI 结合源码深度分析生成,将同步对应责任田团队进行二次确认。


@Leewis 感谢此前跟进。补充当前进展:此前认领后的修复已提交为 PR #5925,当前 HEAD 8a0b511f699ad76757d8df951b3daa7b00ede7d3,社区 CI、CLA 汇总保持通过。7 个 CPU 测试方法已通过,覆盖单引号字面反斜杠、五种连接符、sudo/su 转换及原有转义/重定向行为,测试仅做字符串处理,未执行 SSH、sudo、su 或设备操作。
当前尚待正式 experimental 模块检视及批准。烦请协助转交实际评审负责人,并请确认仓库 PR 模板要求的前冒烟阶段对这项工具修复是否适用、现有 CI 对应哪些用例;若还需作者补测,请明确用例和执行方式。issue 保持开放,待 PR 合入后闭环。


@Leewis 感谢此前跟进。补充当前进展:此前认领后的修复已提交为 PR #5925,当前 HEAD
8a0b511f699ad76757d8df951b3daa7b00ede7d3,社区 CI、CLA 汇总保持通过。7 个 CPU 测试方法已通过,覆盖单引号字面反斜杠、五种连接符、sudo/su 转换及原有转义/重定向行为,测试仅做字符串处理,未执行 SSH、sudo、su 或设备操作。当前尚待正式 experimental 模块检视及批准。烦请协助转交实际评审负责人,并请确认仓库 PR 模板要求的前冒烟阶段对这项工具修复是否适用、现有 CI 对应哪些用例;若还需作者补测,请明确用例和执行方式。issue 保持开放,待 PR 合入后闭环。
收到,我这边将同步给对应committer进行检视加分,感谢参与社区贡献;


Describe the current behavior / 问题描述 (Mandatory / 必填)
experimental/cluster_link_diag/dispatcher/json_info.py的_consume_escape在单引号内仍把反斜杠视为转义。合法命令printf '%s' 'foo\'; sudo id中,反斜杠本应是字面字符,后面的单引号结束参数;目前解析器却将结束单引号吃掉,忽略随后真正的;连接符。因此
split_ignoring_quotes错误地只返回一段,sudo_cmd不会给后续sudo id加上调度器的-S -p ''选项。其他连接符及后续su转换同样受到影响。dispatcher_common.exec_command_with_auth通过此转换函数处理待执行命令;本次仅验证该纯字符串处理行为,未实际执行 sudo、su 或 SSH。Environment / 环境信息 (Mandatory / 必填)
HCOMM master
37fe471eda95d8193e59871707e651e7041a872c;CPU / Python 3.9.6 / Paramiko 5.0.0。相同实现此前在 ARM Linux / Python 3.12.13 验证。无需 NPU、主机配置文件或 SSH 连接。Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)
安装调度器已有的 Paramiko 依赖后,在仓库根目录运行:
python3 -B - <<'PYCODE' import sys sys.path.insert(0, 'experimental/cluster_link_diag/dispatcher') import json_info command = "printf '%s' 'foo\\'; sudo id" print(json_info.split_ignoring_quotes(command)) print(json_info.sudo_cmd(command, '')) PYCODEDescribe the expected behavior / 预期结果 (Mandatory / 必填)
单引号内的反斜杠按字面保留,正确识别结束单引号以及后续连接符:
引号之外的转义、双引号内的现有转义处理、引号内分隔符和重定向保持原行为。
Related log / screenshot / 日志 / 截图 (Mandatory / 必填)
原版返回:
新增 7 个 CPU 测试方法覆盖五种连接符子场景、后续 sudo / su 转换、引号内分隔符、外部转义、双引号转义、重定向与不加载配置。原版出现 6 个失败子场景,单行修复后全部通过;标准库 shlex 交叉核对词法分隔。全过程仅处理字符串。
Special notes for this issue/备注 (Optional / 选填)
建议仅当不在单引号中时启用反斜杠转义。已按函数名、single quote / 单引号、backslash / 反斜杠等检索 issue / PR;#927 / PR #5437 修复的是实时执行器 shell=False 的 argv 空格切分,并明确不修改 SSH 转换,因此与本问题不同。