// PCH-02-008 regression tests — BinaryReader must bound every read and fail // with the decoder's existing PAYLOAD_TOO_SHORT code on truncated input. import { describe, expect, it } from "vitest"; import { BinaryReader } from "./peachPayload"; describe("PCH-02-008 — BinaryReader bounds checks", () => { it("u8 past end of buffer throws PAYLOAD_TOO_SHORT", () => { const r = new BinaryReader(Uint8Array.of(0xaa), 0); expect(r.u8()).toBe(0xaa); expect(() => r.u8()).toThrow("PAYLOAD_TOO_SHORT"); }); it("u16 with only one byte remaining throws PAYLOAD_TOO_SHORT", () => { const r = new BinaryReader(Uint8Array.of(0x01), 0); expect(() => r.u16()).toThrow("PAYLOAD_TOO_SHORT"); }); it("u32 with three bytes remaining throws PAYLOAD_TOO_SHORT", () => { const r = new BinaryReader(Uint8Array.of(0x01, 0x02, 0x03), 0); expect(() => r.u32()).toThrow("PAYLOAD_TOO_SHORT"); }); it("read(n) past end throws instead of clamping short", () => { const r = new BinaryReader(Uint8Array.of(1, 2, 3, 4), 0); expect(() => r.read(5)).toThrow("PAYLOAD_TOO_SHORT"); }); it("lpString whose declared length overruns the buffer throws", () => { const r = new BinaryReader(Uint8Array.of(200, 0x61, 0x62), 0); expect(() => r.lpString(1)).toThrow("PAYLOAD_TOO_SHORT"); }); it("valid reads at exact buffer boundaries still work (regression)", () => { const buf = new Uint8Array(11); const view = new DataView(buf.buffer); buf[0] = 0x7f; view.setUint16(1, 0xbeef, true); view.setUint32(3, 0xdeadbeef, true); buf.set([0x70, 0x65, 0x61, 0x63], 7); const r = new BinaryReader(buf, 0); expect(r.u8()).toBe(0x7f); expect(r.u16()).toBe(0xbeef); expect(r.u32()).toBe(0xdeadbeef); expect(Array.from(r.read(4))).toEqual([0x70, 0x65, 0x61, 0x63]); expect(() => r.u8()).toThrow("PAYLOAD_TOO_SHORT"); }); it("lpString round-trips a valid length-prefixed string (regression)", () => { const text = new TextEncoder().encode("peach"); const buf = new Uint8Array(1 + text.length); buf[0] = text.length; buf.set(text, 1); const r = new BinaryReader(buf, 0); expect(r.lpString(1)).toBe("peach"); expect(r.cursor).toBe(buf.length); }); it("respects a non-zero start offset and bounds from it", () => { const buf = Uint8Array.of(0xff, 0xff, 0x2a); const r = new BinaryReader(buf, 2); expect(r.u8()).toBe(0x2a); expect(() => r.u8()).toThrow("PAYLOAD_TOO_SHORT"); }); });