fix(tool-payload): enforce UTF-8 byte limits for serialized payloads#102450
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 2:18 AM ET / 06:18 UTC. Summary PR surface: Source +10, Tests +14. Total +24 across 2 files. Reproducibility: yes. Source inspection on current main shows XML parameter limits compare UTF-16 offsets, and the PR's regression case is a concrete multibyte payload that stays under the code-unit cap while exceeding UTF-8 bytes. Review metrics: none identified. Stored data model 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 detailsBest possible solution: Land the narrow byte-count parser fix after real behavior proof and exact-head CI complete; keep any broader stream-scrub byte policy as a separate follow-up if maintainers want no visible oversized XML text. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection on current main shows XML parameter limits compare UTF-16 offsets, and the PR's regression case is a concrete multibyte payload that stays under the code-unit cap while exceeding UTF-8 bytes. Is this the best way to solve the issue? Yes for the executable-promotion boundary. Checking UTF-8 byte length at both XML parameter limit points is the narrowest maintainable parser fix; changing stream buffering policy would be broader and is not required to stop over-limit promotion. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 240ca9dbd7f5. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +10, Tests +14. Total +24 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
|
|
@clawsweeper re-review Added exact-head real parser invocation proof to the PR body. It invokes |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Land-ready maintainer pass complete at exact head Improvements beyond the original patch:
Proof:
Known proof gaps: none for this parser-only change. |
|
Merged via squash.
|
…penclaw#102450) * fix(tool-payload): reject oversized XML payload bytes * fix(tools): enforce serialized payload byte limits --------- Co-authored-by: Peter Steinberger <[email protected]>
…penclaw#102450) * fix(tool-payload): reject oversized XML payload bytes * fix(tools): enforce serialized payload byte limits --------- Co-authored-by: Peter Steinberger <[email protected]> (cherry picked from commit b20b02a)
What Problem This Solves
Fixes an issue where plain-text tool-call repair could accept serialized JSON or XML-style payloads whose UTF-8 size exceeded
maxPayloadByteswhen their text contained multibyte characters. Both parser paths previously relied on UTF-16 code-unit counts at the acceptance boundary.Why This Change Was Made
The parser now applies one UTF-8 byte-length helper to both formats. JSON validates the complete serialized object after its structural scan. XML parameters report each disjoint serialized segment's byte length, allowing cumulative enforcement without repeatedly encoding the entire growing prefix.
This preserves the existing parser grammar and public option while making the documented byte limit accurate for every accepted serialization.
User Impact
Tool-call repair consistently rejects oversized serialized tool arguments for ASCII and multibyte text, preventing over-limit payloads from being promoted into executable tool calls.
Evidence
a7db009db708fb3536c4138335e3e90653b36ad4pnpm test src/plugin-sdk/tool-payload.test.tsOutput:
{ "head": "a7db009db708fb3536c4138335e3e90653b36ad4", "command": "parseStandalonePlainTextToolCallBlocks multibyte XML parameter", "parameterUtf16Length": 53, "parameterUtf8Bytes": 73, "maxPayloadBytes": 64, "parserResult": null }git diff --checkpassed.0.98).