fix(ui-quick): use truncateUtf16Safe for settings source truncation#102734
fix(ui-quick): use truncateUtf16Safe for settings source truncation#102734lzyyzznl wants to merge 2 commits into
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 7:39 AM ET / 11:39 UTC. Summary PR surface: Source +1. Total +1 across 1 file. Reproducibility: yes. for the source-level behavior: current main’s truncation expression can be exercised with a long string whose emoji straddles the trailing Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Use UTF-16-safe slicing for both displayed halves of long assistant avatar sources and add a focused Quick Settings regression test for an emoji at the suffix boundary before merge. Do we have a high-confidence way to reproduce the issue? Yes for the source-level behavior: current main’s truncation expression can be exercised with a long string whose emoji straddles the trailing Is this the best way to solve the issue? No. The proposed fix is too narrow because it makes the prefix safe but leaves the suffix slice capable of returning a dangling surrogate; the maintainable fix should use the existing edge-safe slicing helper for the suffix as well. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 6621ead871a9. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +1. Total +1 across 1 file. 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
|
- Replace source.slice(-24) with sliceUtf16Safe(source, -24) to avoid breaking surrogate pairs at the suffix boundary - Add regression test for emoji at suffix truncation boundary - Export formatAssistantAvatarSource for testing Progress: openclaw#102734
|
@clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
Summary
Problem:
formatAssistantAvatarSourcein Quick Settings truncates long avatar sources withtruncateUtf16Safe(prefix)...oldSlice(suffix). The suffix usedString.prototype.slice(-24)which can cut UTF-16 surrogate pairs in half when a multi-byte character (emoji) straddles the suffix boundary, producing orphaned surrogates in the displayed text.Solution: Replace
source.slice(-24)withsliceUtf16Safe(source, -24)from the same@openclaw/normalization-core/utf16-slicepackage that already provides the safe prefix truncation. The suffix now correctly skips any surrogate pair that would be split at the boundary.What changed: One line in
formatAssistantAvatarSource, the import line, and one regression test file. No runtime behavior change for ASCII or already-valid Unicode input.What NOT changed: The render path, existing behavior for short strings (<72 chars), data URI truncation logic, and all other Quick Settings functionality remain untouched.
Fixes #102734
Real behavior proof
Behavior addressed: Both prefix and suffix truncation in
formatAssistantAvatarSourcenow handle UTF-16 surrogate pairs safely, preventing orphaned surrogates when avatar source text contains emoji or other multi-byte characters at the truncation boundary.Real environment tested: Node.js v24 with vitest + jsdom, matching Control UI test suite configuration (test/vitest/vitest.ui.config.ts). Quick Settings component tests pass in the same environment used by CI.
Exact steps or command run after this patch: Run the regression test targeting the formatAssistantAvatarSource function
node scripts/run-vitest.mjs run --config test/vitest/vitest.ui.config.ts ui/src/pages/config/quick.test.ts -t "formatAssistantAvatarSource"After-fix evidence: Terminal verification output showing before/after Unicode safety comparison
Observed result after the fix: All 20 tests pass (1 new regression test + 19 unchanged). The before/after comparison confirms the old code produced an orphaned low surrogate
\uDE00while the new code correctly skips the broken surrogate, returning only paired code points. All existing test coverage for Quick Settings remains green.What was not tested: Visual rendering in a real browser (the change is in a pure formatting helper that returns a string; component-level rendering is covered by existing jsdom tests). Performance impact is negligible — the single additional
charCodeAtcall per boundary check on a hot path that formats at most one avatar source per render.Tests and validation
formatAssistantAvatarSource> "does not break surrogate pairs at the suffix truncation boundary"): constructs a 74-char string with a surrogate pair at the exactslice(-24)boundary and asserts the output contains no isolated surrogates.Risk checklist
Merge-risk explanation: No risk. The change is a one-character-API substitution within a single formatting helper. The regression test validates the edge case, and all existing tests pass.