|
| 1 | +import { spawnSync } from "node:child_process"; |
| 2 | +import { resolve } from "node:path"; |
| 3 | +import { pathToFileURL } from "node:url"; |
1 | 4 | import { describe, expect, it } from "vitest"; |
2 | 5 | import { |
3 | 6 | findStartTags, |
@@ -60,6 +63,31 @@ const workGrowth = (scan: (n: number) => void) => |
60 | 63 | scannedChars(() => scan(20_000)) / scannedChars(() => scan(10_000)); |
61 | 64 |
|
62 | 65 | describe("htmlDocument helpers", () => { |
| 66 | + it("strips runtimes from large mixed-case base64 HTML within a bounded heap", () => { |
| 67 | + const moduleUrl = pathToFileURL(resolve(__dirname, "htmlDocument.ts")).href; |
| 68 | + const result = spawnSync( |
| 69 | + process.execPath, |
| 70 | + [ |
| 71 | + "--max-old-space-size=256", |
| 72 | + "--import=tsx", |
| 73 | + "--input-type=module", |
| 74 | + "--eval", |
| 75 | + ` |
| 76 | + import { strict as assert } from "node:assert"; |
| 77 | + import { stripEmbeddedRuntimeScripts } from ${JSON.stringify(moduleUrl)}; |
| 78 | + const media = '<img src="data:image/png;base64,' + 'Aa0/'.repeat(8 * 1024 * 1024) + '">'; |
| 79 | + const runtime = '<SCRIPT src="HYPERFRAME.RUNTIME.IIFE.JS"></SCRIPT>'; |
| 80 | + assert.equal(stripEmbeddedRuntimeScripts(media + runtime), media); |
| 81 | + console.log("large HTML preserved; runtime removed"); |
| 82 | + `, |
| 83 | + ], |
| 84 | + { encoding: "utf8", timeout: 60_000 }, |
| 85 | + ); |
| 86 | + expect(result.error).toBeUndefined(); |
| 87 | + expect(result.status, result.stderr).toBe(0); |
| 88 | + expect(result.stdout).toContain("large HTML preserved; runtime removed"); |
| 89 | + }, 65_000); |
| 90 | + |
63 | 91 | it("keeps a document's <html> attributes when a comment comes before the doctype", () => { |
64 | 92 | const doc = parseHTMLContent( |
65 | 93 | '<!-- hyperframes-registry-item: blk -->\n<!doctype html>\n<html lang="en" data-composition-variables="[]"><body></body></html>', |
@@ -301,6 +329,15 @@ describe("htmlDocument helpers", () => { |
301 | 329 | }); |
302 | 330 |
|
303 | 331 | describe("findStartTags", () => { |
| 332 | + it("preserves Unicode offsets and mixed-case tags across chunk boundaries", () => { |
| 333 | + const prefix = "a".repeat(65_535) + "😀İ"; |
| 334 | + const html = prefix + "<ImG src=x>" + "A".repeat(65_521) + "<IMG src=y>"; |
| 335 | + expect(findStartTags(html, "iMg")).toEqual([65_538, 131_070]); |
| 336 | + expect( |
| 337 | + stripEmbeddedRuntimeScripts(prefix + '<SCRIPT src="HYPERFRAME.RUNTIME.IIFE.JS"></SCRIPT>'), |
| 338 | + ).toBe(prefix); |
| 339 | + }); |
| 340 | + |
304 | 341 | const at = (html: string, name: string) => |
305 | 342 | findStartTags(html, name).map((i) => html.slice(i, html.indexOf(">", i) + 1)); |
306 | 343 |
|
|
0 commit comments