mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 20:32:25 +03:00
fix(providers): strip Vertex doc script blocks whose end tag carries junk (#13936)
The Vertex model-docs HTML is converted to plain text before the table parser reads context-window and token-limit numbers out of the cells. The script/style removal pass required the end tag to be `</script\s*>`, but the HTML spec closes the element on `</script\t\n foo>` too. Such a block survived the pass; the generic `<[^>]+>` strip below then removed both tags and kept the script BODY, so text that only ever existed inside a script became cell text the number parser trusts. Accept any end tag that starts with `</script`/`</style` followed by a tag-name boundary, matching what a browser does. CodeQL js/bad-tag-filter, alert #1007.
This commit is contained in:
committed by
GitHub
parent
f89e188a9f
commit
3d5baf13f4
1
changelog.d/fixes/vertex-docs-script-end-tag.md
Normal file
1
changelog.d/fixes/vertex-docs-script-end-tag.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(providers):** strip `<script>`/`<style>` blocks from the Vertex model-docs HTML even when the end tag carries junk before the `>` (`</script foo>`, which the HTML spec still treats as a close). The old regexp required `</script\s*>`, so such a block survived; the generic tag-stripping pass then removed both tags and kept the script BODY, letting its text reach the table cells the context-window/token-limit parser reads (CodeQL `js/bad-tag-filter`, alert #1007).
|
||||
@@ -147,7 +147,11 @@ function decodeHtmlEntities(value: string): string {
|
||||
function htmlFragmentToText(fragment: string): string {
|
||||
return decodeHtmlEntities(
|
||||
fragment
|
||||
.replace(/<(?:script|style)\b[^>]*>[\s\S]*?<\/(?:script|style)\s*>/gi, " ")
|
||||
// The end tag accepts junk before the `>` — `</script\t\n bar>` closes the element per the
|
||||
// HTML spec. Matching only `\s*>` left such a block unremoved here; the generic `<[^>]+>`
|
||||
// pass below then stripped both tags and kept the script BODY, so whatever it contained
|
||||
// landed in the cell text the number parser reads (CodeQL js/bad-tag-filter, alert #1007).
|
||||
.replace(/<(?:script|style)\b[^>]*>[\s\S]*?<\/(?:script|style)\b[^>]*>/gi, " ")
|
||||
.replace(/<(?:br|hr)\b[^>]*\/?\s*>/gi, " ")
|
||||
.replace(/<[^>]+>/g, " ")
|
||||
)
|
||||
|
||||
@@ -163,3 +163,21 @@ test("Vertex normalization persists context separately while legacy providers re
|
||||
]);
|
||||
assert.equal(normalizeDiscoveredModels([metadata], "openrouter")[0]?.inputTokenLimit, 1048576);
|
||||
});
|
||||
|
||||
test("#1007: a spec-legal `</script foo>` end tag does not leak script text into a parsed cell", () => {
|
||||
// CodeQL js/bad-tag-filter: the script/style stripper matched only `</script>` with optional
|
||||
// whitespace, but HTML also accepts junk before the `>` — `</script\t\n bar>` closes the element.
|
||||
// The generic `<[^>]+>` pass then removes both tags, so what survives is the script BODY, which
|
||||
// lands in the cell text the number parser reads. Docs pages come from docs.cloud.google.com and
|
||||
// are parsed to TEXT (never rendered), so the impact is a poisoned limit, not injection.
|
||||
const html = modelDocsHtml(`
|
||||
<tr><th>Model ID</th><td>gemini-3.7-flash</td></tr>
|
||||
<tr><th>Token limits</th><td>Context window</td><td><script>999,999,999</script\t\n bar></td></tr>
|
||||
`);
|
||||
|
||||
assert.equal(
|
||||
parseVertexModelDocsHtml(html, "gemini-3.7-flash"),
|
||||
null,
|
||||
"a number that exists only inside a script body must not become the model's context window"
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user