123456789import { describe, expect, test, vi } from "vitest";10import { decodePeachScript, isPeachScript } from "./peachScript";11import { IMPORT_LIMITS } from "../shared/import-limits";1213141516const MAX_CP = Math.floor(IMPORT_LIMITS.MAX_JSON_BYTES / 3);17const ALLOWANCE = 64 * 1024;18const MAX_RAW = MAX_CP + ALLOWANCE;19const GLYPH = String.fromCodePoint(0xe041);2021describe("PB-26-208 bounded PeachScript parser", () => {22 test("whitespace-only input over ceiling + allowance fails as too large without Array.from", () => {23 const fromSpy = vi.spyOn(Array, "from");24 try {25 expect(() => decodePeachScript(" ".repeat(MAX_RAW + 1))).toThrow(26 "PEACHSCRIPT_TOO_LARGE",27 );28 expect(29 fromSpy.mock.calls.some(30 (args) => typeof args[0] === "string" && args[0].length > MAX_RAW,31 ),32 "decode must not Array.from an over-ceiling input",33 ).toBe(false);34 } finally {35 fromSpy.mockRestore();36 }37 });3839 test("valid script at the encoded ceiling decodes; one more glyph fails", () => {40 const atCeiling = GLYPH.repeat(MAX_CP);41 expect(decodePeachScript(atCeiling).length).toBe(MAX_CP);42 expect(() => decodePeachScript(`${atCeiling}${GLYPH}`)).toThrow(43 "PEACHSCRIPT_TOO_LARGE",44 );45 });4647 test("whitespace allowance boundary: allowance passes, allowance + 1 fails", () => {48 expect(decodePeachScript(" ".repeat(ALLOWANCE) + GLYPH).length).toBe(1);49 expect(() => decodePeachScript(" ".repeat(ALLOWANCE + 1) + GLYPH)).toThrow(50 "PEACHSCRIPT_TOO_LARGE",51 );52 });5354 test("lone surrogates and astral characters throw without partial output", () => {55 expect(() => decodePeachScript(`${GLYPH}\ud800${GLYPH}`)).toThrow(56 "INVALID_PEACHSCRIPT_CHARACTER",57 );58 expect(() => decodePeachScript("\udc00")).toThrow(59 "INVALID_PEACHSCRIPT_CHARACTER",60 );61 expect(() => decodePeachScript(`${GLYPH}\u{1D2E0}`)).toThrow(62 "INVALID_PEACHSCRIPT_CHARACTER",63 );64 });6566 test("isPeachScript shares the bound: oversized input is simply invalid", () => {67 expect(isPeachScript(" ".repeat(MAX_RAW + 1))).toBe(false);68 expect(isPeachScript(GLYPH.repeat(MAX_CP + 1))).toBe(false);69 expect(isPeachScript(` ${GLYPH}\n`)).toBe(true);70 });71});