fix(file-transfer): preserve UTF-16 pairs in bounded stderr tails#104098
fix(file-transfer): preserve UTF-16 pairs in bounded stderr tails#104098Pick-cat wants to merge 0 commit into
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 10, 2026, 11:11 PM ET / July 11, 2026, 03:11 UTC. Summary PR surface: Source +2. Total +2 across 2 files. Reproducibility: yes. A deterministic current-main Node probe reproduces a retained tail beginning with lone U+DE00 when an emoji straddles the 4096-code-unit cutoff. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Next step before merge
Security Review detailsBest possible solution: Keep the existing stderr limits and route both duplicated file-transfer accumulators through the canonical UTF-16-safe helper, with exact-head checks gating merge. Do we have a high-confidence way to reproduce the issue? Yes. A deterministic current-main Node probe reproduces a retained tail beginning with lone U+DE00 when an emoji straddles the 4096-code-unit cutoff. Is this the best way to solve the issue? Yes. Reusing the tested public UTF-16 helper in exactly the two duplicated owners is the narrowest maintainable fix and preserves existing limits and subprocess behavior. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against feae1faf0643. Label changesLabel justifications:
Evidence reviewedPR surface: Source +2. Total +2 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
0ac96fc to
4541969
Compare
|
冲突已解决,但 rebase 后发现此 PR 的修复已经被
两个调用方文件 ( 此 PR 可以关闭,因为修复已经在 main 上了。 |
What Problem This Solves
Fixes an issue where
appendBoundedTextTail(used to capture tar stderr output indir-fetch-tool.tsandnode-invoke-policy.ts) produces strings that start with a lone low surrogate when an emoji or other non-BMP character straddles the tail boundary. The.slice(-maxChars)call cuts at a UTF-16 code unit boundary, and when the cut point lands exactly on a LOW surrogate paired with a HIGH surrogate just before it, the result begins with a dangling\uDE00-style byte that corrupts downstream display and logging.Why This Change Was Made
The fix replaces
.slice(-maxChars)withsliceUtf16Safe(next, -maxChars)— the same canonical helper from@openclaw/normalization-core/utf16-slicealready used across the codebase for UTF-16-safe truncation. Both files share an identical copy ofappendBoundedTextTail; both are fixed in the same change to keep their behavior consistent.User Impact
Tar operation error output (stderr) displayed in agent tool results no longer risks starting with a corrupted surrogate byte when the output contains emoji characters near the 4096-char tail window. No user-visible impact for ASCII-only stderr.
Real behavior proof
Behavior addressed:
appendBoundedTextTailproduces lone surrogates when emoji straddles the tail boundary.Real environment tested: Node.js v22.22.0, x64, linux
Evidence after fix:
Negative control (pre-fix behavior reproduced):
Summary:
Evidence
pnpm test extensions/file-transfer/src/tools/dir-fetch-tool.test.ts— 8/8 tests passnode proof-file-transfer-utf16-tail.mjs— 19/19 assertions pass (6 positive cases + 1 negative control)gh search prsfor these files with UTF-16/surrogate keywords