mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 13:26:04 -06:00
fix(agents): prevent malformed HTML entities from breaking tool calls (#99564)
* Reject surrogate HTML entities in tool args Co-Authored-By: Claude <noreply@anthropic.com> * docs(changelog): note tool argument entity fix --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -19,6 +19,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Fixes
|
||||
|
||||
- **Source build portability:** keep tsdown configuration self-contained so builds do not depend on resolving the tsdown package from unrun's temporary module directory.
|
||||
- **Agent tool-call decoding:** preserve surrogate-range numeric HTML entities as literal text while still decoding valid supplementary-plane values, preventing malformed model output from injecting lone UTF-16 surrogates into tool arguments. (#99564) Thanks @mikasa0818.
|
||||
- **Gateway event dispatch:** catch and log lazy subscriber setup and handler failures instead of leaking unhandled promise rejections. (#100401) Thanks @cxbAsDev.
|
||||
- **Diffs rendering:** render viewer and image output from one SSR preload, preserve language-pack highlighting through hydration, normalize language hints case-insensitively, skip identical before/after inputs with an explicit `changed` result, report truthful file-render and input errors, cache hash-pinned viewer runtimes, and prefer canonical file settings over stale aliases. (#100487)
|
||||
- **Remote browser reliability:** bound persistent Playwright tab enumeration by the existing remote CDP timeout budget and retire timed-out connection attempts so late completions cannot restore a stuck connection. (#80147, #58968) Thanks @HemantSudarshan and @KeaneYan.
|
||||
|
||||
@@ -11,11 +11,13 @@ describe("decodeHtmlEntitiesInObject", () => {
|
||||
expect(
|
||||
decodeHtmlEntitiesInObject({
|
||||
query: "Rock & Roll A 'ok' 'hex'",
|
||||
emoji: "ok 😀",
|
||||
args: ["--flag="value"", "<input>"],
|
||||
nested: { deep: "a & b" },
|
||||
}),
|
||||
).toEqual({
|
||||
query: "Rock & Roll A 'ok' 'hex'",
|
||||
emoji: "ok 😀",
|
||||
args: ['--flag="value"', "<input>"],
|
||||
nested: { deep: "a & b" },
|
||||
});
|
||||
@@ -32,10 +34,10 @@ describe("decodeHtmlEntitiesInObject", () => {
|
||||
it("preserves invalid numeric HTML entities", () => {
|
||||
expect(
|
||||
decodeHtmlEntitiesInObject({
|
||||
query: "bad � and �",
|
||||
query: "bad � and � and � and �",
|
||||
}),
|
||||
).toEqual({
|
||||
query: "bad � and �",
|
||||
query: "bad � and � and � and �",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,12 @@ const HTML_ENTITY_RE = /&(?:amp|lt|gt|quot|apos|#39|#x[0-9a-f]+|#\d+);/i;
|
||||
function decodeHtmlEntities(value: string): string {
|
||||
const decodeNumericEntity = (raw: string, radix: 10 | 16): string => {
|
||||
const codePoint = Number.parseInt(raw, radix);
|
||||
return Number.isFinite(codePoint) && codePoint >= 0 && codePoint <= 0x10ffff
|
||||
const isValidCodePoint =
|
||||
Number.isInteger(codePoint) &&
|
||||
codePoint >= 0 &&
|
||||
codePoint <= 0x10ffff &&
|
||||
(codePoint < 0xd800 || codePoint > 0xdfff);
|
||||
return isValidCodePoint
|
||||
? String.fromCodePoint(codePoint)
|
||||
: `&#${radix === 16 ? "x" : ""}${raw};`;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user