Files
rea/tests/fixtures/uimage.ts
morluto 7bcefead69 test: strengthen and prune audited test coverage (#8573)
* 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
2026-11-02 02:13:32 +08:00

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);
};