import { describe, expect, it } from "vitest"; import { decodeStructured, encodeStructured, parseDer, parseProtobuf, parseSchema, } from "../../src/core/inspect"; describe("structured binary inspection", () => { it.each(["cbor", "msgpack"] as const)("round-trips %s", (format) => { const encoded = encodeStructured(format, '{"name":"Ada","active":true}'); expect(JSON.parse(decodeStructured(format, encoded))).toEqual({ name: "Ada", active: true, }); }); it("builds a DER tree with exact source ranges", () => { const tree = parseDer( Uint8Array.of(0x30, 0x06, 0x02, 0x01, 0x2a, 0x01, 0x01, 0xff), ); expect(tree[0]).toMatchObject({ label: "SEQUENCE", start: 0, end: 8 }); expect(tree[0]?.children?.[0]).toMatchObject({ label: "INTEGER", value: "42", start: 2, end: 5, }); }); it("decodes protobuf wire fields using a schema", () => { const tree = parseProtobuf( Uint8Array.of(0x08, 0x96, 0x01, 0x12, 0x03, 0x41, 0x64, 0x61), { "1": { name: "id", type: "uint" }, "2": { name: "name", type: "string" }, }, ); expect(tree.map((node) => node.value)).toEqual(["150", "Ada"]); expect(tree[1]).toMatchObject({ start: 3, end: 8 }); }); it("rejects indefinite DER and unsupported protobuf groups", () => { expect(() => parseDer(Uint8Array.of(0x30, 0x80, 0, 0))).toThrow( /indefinite/u, ); expect(() => parseProtobuf(Uint8Array.of(0x0b))).toThrow(/Unsupported/u); }); it.each([ ["non-minimal high tag", Uint8Array.of(0x1f, 0x1e, 0x00)], ["leading-zero high tag", Uint8Array.of(0x1f, 0x80, 0x1f, 0x00)], ["non-canonical boolean", Uint8Array.of(0x01, 0x01, 0x01)], ["empty integer", Uint8Array.of(0x02, 0x00)], ["redundant positive integer", Uint8Array.of(0x02, 0x02, 0x00, 0x7f)], ["redundant negative integer", Uint8Array.of(0x02, 0x02, 0xff, 0x80)], ["non-empty null", Uint8Array.of(0x05, 0x01, 0x00)], ["primitive sequence", Uint8Array.of(0x10, 0x00)], ])("rejects %s DER", (_label, input) => { expect(() => parseDer(input)).toThrow(); }); it("rejects a leading zero in a long-form DER length", () => { expect(() => parseDer( Uint8Array.from([0x04, 0x82, 0x00, 0x80, ...new Uint8Array(128)]), ), ).toThrow(/leading zero/u); }); it("validates schema records and their wire compatibility", () => { expect(() => parseSchema('{"name":{"type":"uint"}}')).toThrow( /field number/u, ); expect(() => parseSchema('{"1":{"type":"made-up"}}')).toThrow( /not supported/u, ); expect(() => parseSchema('{"1":{"type":"uint","fields":{}}}')).toThrow( /requires type message/u, ); expect(() => parseProtobuf(Uint8Array.of(0x0a, 0x01, 0x41), { "1": { type: "uint" }, }), ).toThrow(/expects wire 0/u); }); it("rejects out-of-range protobuf keys and varints", () => { expect(() => parseProtobuf(Uint8Array.of(0x80, 0x80, 0x80, 0x80, 0x10)), ).toThrow(/Unsupported wire key/u); expect(() => parseProtobuf( Uint8Array.of( 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, ), ), ).toThrow(/unsigned 64-bit/u); }); });