fix: harden tool arg decoding and codeql path

This commit is contained in:
Peter Steinberger
2026-05-26 15:11:34 +01:00
parent ac31e27b49
commit 1ab256cc98
3 changed files with 34 additions and 3 deletions

View File

@@ -27,7 +27,7 @@ paths:
- src/agents/agent-tool-definition-adapter.ts
- src/agents/agent-tools.abort.ts
- src/agents/agent-tools.before-tool-call*.ts
- src/agents/agent-tools.host-edit.ts
- src/agents/agent-tools.read.ts
- src/agents/agent-tools-parameter-schema.ts
- src/agents/embedded-agent-runner/effective-tool-policy.ts
- src/agents/embedded-agent-runner/tool-name-allowlist.ts

View File

@@ -0,0 +1,24 @@
import { describe, expect, it } from "vitest";
import { decodeHtmlEntitiesInObject } from "./tool-call-argument-decoding.js";
describe("decodeHtmlEntitiesInObject", () => {
it("decodes valid HTML entities in nested tool arguments", () => {
expect(
decodeHtmlEntitiesInObject({
query: "Rock & Roll A 'ok'",
}),
).toEqual({
query: "Rock & Roll A 'ok'",
});
});
it("preserves invalid numeric HTML entities", () => {
expect(
decodeHtmlEntitiesInObject({
query: "bad � and �",
}),
).toEqual({
query: "bad � and �",
});
});
});

View File

@@ -6,6 +6,13 @@ import type { MutableAssistantMessageEventStream } from "../stream-compat.js";
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
? String.fromCodePoint(codePoint)
: `&#${radix === 16 ? "x" : ""}${raw};`;
};
return value
.replace(/&amp;/gi, "&")
.replace(/&quot;/gi, '"')
@@ -13,8 +20,8 @@ function decodeHtmlEntities(value: string): string {
.replace(/&apos;/gi, "'")
.replace(/&lt;/gi, "<")
.replace(/&gt;/gi, ">")
.replace(/&#x([0-9a-f]+);/gi, (_, hex) => String.fromCodePoint(Number.parseInt(hex, 16)))
.replace(/&#(\d+);/gi, (_, dec) => String.fromCodePoint(Number.parseInt(dec, 10)));
.replace(/&#x([0-9a-f]+);/gi, (_, hex: string) => decodeNumericEntity(hex, 16))
.replace(/&#(\d+);/gi, (_, dec: string) => decodeNumericEntity(dec, 10));
}
export function decodeHtmlEntitiesInObject(value: unknown): unknown {