* test: strengthen and prune audited test coverage * test: require delivered DeepSeek skill instructions * test: keep schema fixture types private * test: verify Gemini receives skill instructions * test: bind Qwen skill evidence to its tool result * test: report NativeAOT verifier checks precisely * fix: verify Ghidra cleanup paths reliably * fix: verify Command Code skill activation * test: tighten cleanup and fixture checks * test: verify packet capture evidence is recorded * fix: report HTTP3 capture provenance accurately * test: preserve resource coverage through MCP * test: prune repeated assertions and retain cancellation identity * fix: validate client verifier fixture paths * test: skip Copilot verifier cases on Windows * test: keep verifier setup target relative
71 lines
2.7 KiB
TypeScript
71 lines
2.7 KiB
TypeScript
import { crc32 } from "node:zlib";
|
|
|
|
// U-Boot legacy image header layout, independent of the REA reader.
|
|
const UIMAGE_HEADER_SIZE = 64;
|
|
const UIMAGE_MAGIC = 0x27051956;
|
|
const UIMAGE_NAME_LENGTH = 32;
|
|
|
|
export interface UImageFixtureOptions {
|
|
readonly arch?: number;
|
|
readonly os?: number;
|
|
readonly type?: number;
|
|
readonly compression?: number;
|
|
readonly loadAddress?: number;
|
|
readonly entryPoint?: number;
|
|
readonly timestamp?: number;
|
|
readonly name?: string;
|
|
/** Raw stored payload bytes; for multi images pass the size table + parts. */
|
|
readonly payload?: Buffer;
|
|
/** Corrupt the header CRC after computing it (keeps a valid magic). */
|
|
readonly corruptHeaderCrc?: boolean;
|
|
/** Corrupt the data CRC after computing it. */
|
|
readonly corruptDataCrc?: boolean;
|
|
}
|
|
|
|
/** Build a synthetic legacy uImage with correctly computed CRCs. */
|
|
export const buildUImage = (options: UImageFixtureOptions = {}): Buffer => {
|
|
const payload = options.payload ?? Buffer.from("uimage-payload");
|
|
const header = Buffer.alloc(UIMAGE_HEADER_SIZE);
|
|
header.writeUInt32BE(UIMAGE_MAGIC, 0);
|
|
header.writeUInt32BE(options.timestamp ?? 1700000000, 8);
|
|
header.writeUInt32BE(payload.length, 12);
|
|
header.writeUInt32BE(options.loadAddress ?? 0x8000, 16);
|
|
header.writeUInt32BE(options.entryPoint ?? 0x8000, 20);
|
|
// Data CRC first: corrupting it must keep the header CRC valid, so the
|
|
// header CRC is computed over the final header bytes below.
|
|
const dataCrc =
|
|
(crc32(payload) >>> 0) ^ (options.corruptDataCrc === true ? 0xff : 0);
|
|
header.writeUInt32BE(dataCrc >>> 0, 24);
|
|
header[28] = options.os ?? 5;
|
|
header[29] = options.arch ?? 2;
|
|
header[30] = options.type ?? 2;
|
|
header[31] = options.compression ?? 0;
|
|
const name = Buffer.from(options.name ?? "test-kernel", "utf8");
|
|
name.copy(header, 32, 0, Math.min(name.length, UIMAGE_NAME_LENGTH));
|
|
const headerCrc = crc32(header) >>> 0;
|
|
header.writeUInt32BE(
|
|
options.corruptHeaderCrc === true ? (headerCrc ^ 0xff) >>> 0 : headerCrc,
|
|
4,
|
|
);
|
|
return Buffer.concat([header, payload]);
|
|
};
|
|
|
|
/** Size table + parts layout for a multi-file image payload. */
|
|
export const buildMultiPayload = (parts: readonly Buffer[]): Buffer => {
|
|
const table = Buffer.alloc((parts.length + 1) * 4);
|
|
parts.forEach((part, index) => {
|
|
table.writeUInt32BE(part.length, index * 4);
|
|
});
|
|
const stored: Buffer[] = [table];
|
|
parts.forEach((part, index) => {
|
|
if (part.length === 0)
|
|
throw new Error(
|
|
"A zero size terminates the uImage table; it cannot describe a component",
|
|
);
|
|
stored.push(part);
|
|
if (index + 1 < parts.length)
|
|
stored.push(Buffer.alloc((4 - (part.length % 4)) % 4));
|
|
});
|
|
return Buffer.concat(stored);
|
|
};
|