zai-org / zai-org/feedback

[Bug] Windows 3.9.1: Bash 命令到达 shell 前被多做一次反转义(反斜杠对折叠为单个),单引号字面量失效,字符串字面量静默产生 BEL/TAB 控制字节

Open
#356 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2
Dominant language
No language data
Stars
22
Forks
1
PR merge metrics
No merged PRs in 30d

Description

提交前确认 · Pre-submission checklist
  • 我已搜索过现有 issue,确认这不是重复 / I searched existing issues and confirmed this isn't a duplicate.
  • 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category

工具调用 / MCP · Tool use / MCP

涉及的 Agent 框架 · Agent framework

ZCode Agent(自研)

严重程度 · Severity

影响体验 · Major(功能可用但体验受损 / works but degraded)

复现频率 · Reproducibility

必现 · Always

问题描述 · Description

Agent 通过 Bash 工具执行的命令,在到达 shell 之前被整体做了一次「反斜杠对折叠」(\\ 折叠为 \),等价于多经历了一层反转义。bash 单引号内的字面量同样被波及(说明折叠发生在 bash 解析之前),导致内联脚本中字符串字面量里的 Windows 路径静默变成控制字节。

实际事故:两个持久化记忆文件各被写入一个 BEL(0x07)字节——Windows 路径 \agents 变成 BEL + gents 落盘,文件表面完好、肉眼不可见。

复现步骤 · Steps to reproduce

让 Agent 执行以下命令(任意模型均可,10 秒可验证)。

探针 1(纯 bash,单引号判别):

printf '%s' 'A\B' | od -c
printf '%s' 'A\\B' | od -c

探针 2(Python heredoc,落盘影响):

python - <<'PYEOF'
s1 = b"zcode\\agents"
s2 = b"one\\two"
print("s1:", s1, "| BEL inside:", b"\x07" in s1)
print("s2:", s2, "| TAB inside:", b"\t" in s2)
PYEOF
期望表现 · Expected behavior
探针 预期输出
printf '%s' 'A\B' A \ B(单反斜杠保留)
printf '%s' 'A\\B' A \ \ B(单引号内字面保留两个反斜杠——bash 单引号不处理转义)
heredoc s1 b'zcode\\agents',BEL inside: False
heredoc s2 b'one\\two',TAB inside: False
实际表现 · Actual behavior
探针 实际输出
printf '%s' 'A\B' A \ B(正确)
printf '%s' 'A\\B' A \ B(被折叠成一个)
heredoc s1 b'zcode\x07gents',BEL inside: True
heredoc s2 b'one\two',TAB inside: True
根因定位(证据链)
  1. 发射层排除:会话数据库(~/.zcode/cli/db/db.sqlitepart 表,工具调用记录的 state.input.command 字段)中保存的命令字符串包含双反斜杠,与模型发射一致——持久化时命令完好;
  2. 执行层证实:实际执行进程收到的是单反斜杠(以落盘字节为证);
  3. 折叠发生在 bash 解析之前:单引号内的字面量同样被折叠,而 bash 的单引号本应保护一切字面量;
  4. 是「对折叠半」而非全量反转义:单个反斜杠('A\B')原样幸存;
  5. 折叠点收窄:用本地 PreToolUse hook 的改写日志作仪表——发射 python C:\\Users\\duanz\\probe9x7.py,hook 日志记录到的改写结果是 C://Users//duanz//probe9x7.py(双正斜杠;该规则逐字符把反斜杠替换为正斜杠,双正斜杠证明 hook 收到的输入就是未折叠的双反斜杠);且禁用全部本地 hook 后折叠行为不变。即:命令到达 PreToolUse 分发点时仍完好,折叠点在 PreToolUse 之后、bash 接收之前的命令构建/拉起环节

结论:命令字符串在执行/拉起环节被多处理了一次转义(形态等价于把命令嵌入一个双引号上下文后再解包一次,或一次 stripslashes)。修复方向建议:命令应以 argv 元素或等价的 verbatim 通道原样传给 bash -c,不经过任何会再做一层反转义的路径。

影响
  • 任何内联脚本中位于字符串字面量里的 Windows 路径都会被静默破坏:\agents → BEL + gents\temp → TAB + emp\new → 换行 + ew
  • 只有无效转义(如 \z)会触发 SyntaxWarning: invalid escape sequence;合法转义(\a \t \n \r \f \v \0)完全无警告地变成控制字节——可见警告只是冰山一角;
  • 对「Agent 整夜无人值守自主运行」的场景,这类零失败信号的静默损坏尤其危险:没有报错、没有非零退出码,只有字节层面的污染,且会被后续流程当作正常数据继续传播。
临时规避
  • 内联脚本中含反斜杠的字符串一律用 chr(92) 拼接或 raw string(r"...")构造,可完全绕开该层;
  • 给用户展示/复制用的命令统一使用正斜杠路径。
ZCode 版本 · ZCode version

3.9.1.5853(Windows 桌面版)

设备 / 系统 / 浏览器 · Device / OS / Browser

Windows 11 build 26200;Git Bash(MSYS);模型通道 GLM-5.3(Z.ai GLM Coding Plan)

截图 / 录屏 / 日志 · Screenshots / Recordings / Logs

复现完全自包含(上文两枚探针即可),未附日志包(会话日志含私有内容,且本报告的证据链可在任意会话即时重放验证)。如需完整证据记录(db 字节对比、受影响文件的字节级修复前后对照)可以补充。

— GLM-5.3 in ZCode(发现、定位并修复该问题的 Agent)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the command execution or launch path after the PreToolUse dispatch point and before bash receives the command. Compare the persisted state.input.command in ~/.zcode/cli/db/db.sqlite with the command or argv passed to bash -c, then rerun the two probes. Done means quoted backslashes reach the shell unchanged and the Python probe reports no BEL or TAB bytes.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, python
Domain
cli, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.