[bug] Native folder dialog truncates paths at characters whose UTF-16 low byte is 0x00 ("05agent开发" → "05agent") #488
chouyi-tech
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Status: 用户报告;已静态定位根因并本地修复验证(实机复验待确认)
现象
在 Windows 的 dsh Web GUI 中切换 / 创建 workspace,点击原生文件夹选择对话框(Select Workspace Directory)选中目录后,路径中的部分汉字被截断,导致 workspace 创建失败:
F:\01_workplace\05agent开发,报错路径中**「开发」被整体截断**——从「开」(U+5F00)开始及其后的所有字符丢失。环境
deepseek-ai/deepseek-harness47f943859bef60e4160492346772ded9b24f765a(Merge pull request #2519 from deepseek-harness/feat/npm-public)pnpm dsh web(tsx 源码模式;目录选择 worker 同样走源码分支import.meta.url.endsWith('.ts'),见win32-dialog-host.ts:27-30)workspace-invalid-path错误代码路径
客户端包装:
packages/client/runtime/src/client/workspaces/service.ts:212路径字符串读取:
packages/host/directory-picker-native/src/win32-dialog-bindings.ts:37-44,调用点在:159(IShellItem::GetDisplayName(SIGDN_FILESYSPATH)的返回值):根因分析
readUtf16用单字节判 NUL 来定位 UTF-16LE 字符串的结束位置,这对 ASCII 成立,但对任意"码位低字节为 0"的字符会提前截断:a,U+0061)的低字节非 0(61 00),只有真正的字符串终止符00 00会命中偶数字节偏移处的 0x00,因此单字节检查在纯 ASCII 下是正确的。U+XX00的字符,其 UTF-16LE 字节序为00 XX——偶数字节偏移处恰好是 0x00,被误判为字符串结束。00 5F。路径F:\01_workplace\05agent开发中,「开」从第 14 字节开始,扫描在bytes[14] === 0处停止,结果toString('utf16le', 0, 14)="F:\01_workplace\05agent"——与用户报错完全一致。字节级复现(node 模拟,路径
F:\01_workplace\05agent开发):受影响字符范围:所有低字节为 0 的码位,包含大量常用 CJK 汉字(如「一」U+4E00、「开」U+5F00)、部分谚文音节等。因此:
影响面:全仓库 grep 确认仅此一处存在该扫描模式(
bytes[end] !== 0循环仅出现于win32-dialog-bindings.ts:40);koffi 自身的str16处理不受影响。修复隔离、风险低。安全 / 正确性影响(目录混淆):若截断后的前缀路径存在,realpath 校验会通过,workspace 将被创建在用户未选中的目录上,agent 随后在错误目录中读写、执行——属于路径混淆(path confusion)。两种场景对比:
F:\01_workplace\05agent不存在 → 创建失败,表现为功能缺陷(拒绝服务级);F:\docs\开单系统,截断为F:\docs(存在)→ realpath 通过,workspace 静默创建在F:\docs,agent 在错误的目录上工作,危害更大且无任何告警。期望行为
F:\01_workplace\05agent开发),不能丢失任何字符。00 00),而非单个字节。建议
修复
readUtf16的终止符检查(已验证可修复截断):补充单元测试:覆盖含低字节 0 字符的路径(
05agent开发、「一」开头、纯 CJK、谚文等),以及纯 ASCII、纯 CJK(无 00 低字节)、空串、超长路径(32768 字节koffi.view上限边界)等用例;建议同时覆盖源码分支与 builtworker.cjs分支。后续可考虑抽查仓库其它手工读取 Win32 字符串的路径(本次 grep 未发现同类模式),防同类问题扩散。
未确认项
win32-dialog-bindings.ts),但用户实机复验结果待确认(本报告撰写时尚未收到复验反馈)。vitest)验证补丁对既有用例的影响(改动仅限终止符判定,语义上只放宽了扫描,不改变纯 ASCII 行为)。worker.cjs)产物由同一源码编译,推断同样受影响;未对 built 产物实测。All reactions