Files
openclaw/src/agents/utils
ly-wang19 a1d1381c2b fix(web-fetch): decode astral HTML entities and stop double-decoding & (#96268)
* fix(web-fetch): decode HTML entities via the shared canonical decoder

web_fetch's hand-rolled decodeEntities used String.fromCharCode (truncating
astral entities like emoji to garbage) and decoded & first (double-decoding
"'" into "'"). Route entity decoding through the shared
decodeHtmlEntityAt in agents/utils/html.ts so web_fetch and the renderer share
one entity contract — the divergence is what produced the bug. A single
left-to-right pass also avoids the double-decode (the "&" is consumed before
its trailing "#39;" is seen as an entity);   is mapped to a space, which
the shared decoder does not cover.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(web-fetch): preserve entity contract in shared HTML entity decoder

Addresses the ClawSweeper review: decodeHtmlEntityAt matched only lowercase
named entities and used a lenient Number.parseInt, so routing web_fetch through
it changed the prior contract — uppercase forms like &AMP; were left escaped,
and a malformed numeric entity like &#39x; was consumed as "'" (parseInt stops
at the first non-digit). Match named entities case-insensitively and require
numeric references to be fully valid digit/hex tokens, restoring web_fetch's
/gi-style named matching and strict numeric handling while keeping the
single-pass shared-decoder boundary. Strictly more correct for the other caller
(syntax-highlight), which only emits well-formed lowercase entities. Adds
regression tests for uppercase named entities and malformed numeric input.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci: retry — cross-os socket-close flake is main-branch, unrelated to web-fetch entity decode

---------

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 13:28:13 -07:00
..