123456789import { describe, expect, it } from "vitest";10import { BinaryReader } from "./peachPayload";1112describe("PCH-02-008 — BinaryReader bounds checks", () => {13 it("u8 past end of buffer throws PAYLOAD_TOO_SHORT", () => {14 const r = new BinaryReader(Uint8Array.of(0xaa), 0);15 expect(r.u8()).toBe(0xaa);16 expect(() => r.u8()).toThrow("PAYLOAD_TOO_SHORT");17 });1819 it("u16 with only one byte remaining throws PAYLOAD_TOO_SHORT", () => {20 const r = new BinaryReader(Uint8Array.of(0x01), 0);21 expect(() => r.u16()).toThrow("PAYLOAD_TOO_SHORT");22 });2324 it("u32 with three bytes remaining throws PAYLOAD_TOO_SHORT", () => {25 const r = new BinaryReader(Uint8Array.of(0x01, 0x02, 0x03), 0);26 expect(() => r.u32()).toThrow("PAYLOAD_TOO_SHORT");27 });2829 it("read(n) past end throws instead of clamping short", () => {30 const r = new BinaryReader(Uint8Array.of(1, 2, 3, 4), 0);31 expect(() => r.read(5)).toThrow("PAYLOAD_TOO_SHORT");32 });3334 it("lpString whose declared length overruns the buffer throws", () => {35 36 const r = new BinaryReader(Uint8Array.of(200, 0x61, 0x62), 0);37 expect(() => r.lpString(1)).toThrow("PAYLOAD_TOO_SHORT");38 });3940 it("valid reads at exact buffer boundaries still work (regression)", () => {41 const buf = new Uint8Array(11);42 const view = new DataView(buf.buffer);43 buf[0] = 0x7f;44 view.setUint16(1, 0xbeef, true);45 view.setUint32(3, 0xdeadbeef, true);46 buf.set([0x70, 0x65, 0x61, 0x63], 7); 4748 const r = new BinaryReader(buf, 0);49 expect(r.u8()).toBe(0x7f);50 expect(r.u16()).toBe(0xbeef);51 expect(r.u32()).toBe(0xdeadbeef);52 expect(Array.from(r.read(4))).toEqual([0x70, 0x65, 0x61, 0x63]);53 54 expect(() => r.u8()).toThrow("PAYLOAD_TOO_SHORT");55 });5657 it("lpString round-trips a valid length-prefixed string (regression)", () => {58 const text = new TextEncoder().encode("peach");59 const buf = new Uint8Array(1 + text.length);60 buf[0] = text.length;61 buf.set(text, 1);6263 const r = new BinaryReader(buf, 0);64 expect(r.lpString(1)).toBe("peach");65 expect(r.cursor).toBe(buf.length);66 });6768 it("respects a non-zero start offset and bounds from it", () => {69 const buf = Uint8Array.of(0xff, 0xff, 0x2a);70 const r = new BinaryReader(buf, 2);71 expect(r.u8()).toBe(0x2a);72 expect(() => r.u8()).toThrow("PAYLOAD_TOO_SHORT");73 });74});