mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 18:52:48 +00:00
Fixes #9792 Squashed from #9793 and rebased onto main. Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
117 lines
4.2 KiB
TypeScript
117 lines
4.2 KiB
TypeScript
import { createHash } from "node:crypto";
|
|
import { writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { expect, it } from "vitest";
|
|
import { GoBinaryService } from "../../src/application/go/GoBinaryService.js";
|
|
import { RustBinaryService } from "../../src/application/rust/RustBinaryService.js";
|
|
import { elf } from "../../src/domain/binaryTarget.fixture.js";
|
|
import { GoBinaryProvider } from "../../src/go/GoBinaryProvider.js";
|
|
import { RustBinaryProvider } from "../../src/rust/RustBinaryProvider.js";
|
|
import { AnalysisOutputError } from "../../src/domain/analysisErrorCore.js";
|
|
import type { MachoSliceArchitecture } from "../../src/domain/apple/machoTargetSelection.js";
|
|
import { createGoBinaryFixture } from "../fixtures/go/image.js";
|
|
import { createRustImage } from "../fixtures/rust/image.js";
|
|
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
|
|
import {
|
|
CPU_ARM64,
|
|
CPU_X86_64,
|
|
universalMacho,
|
|
} from "../fixtures/universalMacho.js";
|
|
|
|
it.each([
|
|
[1, 1, 20, "ppc", "powerpc"],
|
|
[1, 2, 20, "ppc", "powerpc"],
|
|
[1, 1, 3, "386", "x86"],
|
|
[2, 1, 62, "amd64", "x86_64"],
|
|
[2, 2, 21, "ppc64", null],
|
|
] as const)(
|
|
"preserves ELF class%d byte-order%d machine%d in Go and Rust subjects",
|
|
async (bits, endian, machine, local, canonical) => {
|
|
const root = await createTestTempDirectory("rea-metadata-subject-");
|
|
const path = join(root, "header.elf");
|
|
const bytes = elf(bits, endian, machine);
|
|
await writeFile(path, bytes);
|
|
for (const service of [
|
|
new GoBinaryService(new GoBinaryProvider()),
|
|
new RustBinaryService(new RustBinaryProvider()),
|
|
]) {
|
|
const result = await service.inspect({ path });
|
|
if (!result.ok) throw result.error;
|
|
expect(result.value.subject).toMatchObject({
|
|
architecture: canonical,
|
|
digest: { sha256: createHash("sha256").update(bytes).digest("hex") },
|
|
});
|
|
expect(result.value.normalized_result).toMatchObject({
|
|
architecture: local,
|
|
bits: bits === 1 ? 32 : 64,
|
|
byte_order: endian === 1 ? "little" : "big",
|
|
});
|
|
}
|
|
},
|
|
);
|
|
|
|
it("refuses a Go or Rust report whose slice does not answer the requested architecture", async () => {
|
|
const root = await createTestTempDirectory("rea-metadata-slice-");
|
|
const write = async (name: string, bytes: Buffer) => {
|
|
const path = join(root, name);
|
|
await writeFile(path, bytes);
|
|
return path;
|
|
};
|
|
const universal = (thin: Buffer) =>
|
|
universalMacho([
|
|
{ bytes: thin, cpuType: CPU_X86_64, cpuSubtype: 3 },
|
|
{ bytes: thin, cpuType: CPU_ARM64, cpuSubtype: 0 },
|
|
{ bytes: thin, cpuType: CPU_ARM64, cpuSubtype: 0x80000002 },
|
|
]).bytes;
|
|
const go = new GoBinaryProvider();
|
|
const rust = new RustBinaryProvider();
|
|
const targets = [
|
|
{
|
|
path: await write(
|
|
"universal-go",
|
|
universal(createGoBinaryFixture({ format: "macho" }).bytes),
|
|
),
|
|
service: (read: MachoSliceArchitecture) =>
|
|
new GoBinaryService({
|
|
identity: go.identity,
|
|
close: () => go.close(),
|
|
inspect: (input, options) =>
|
|
go.inspect({ ...input, architecture: read }, options),
|
|
}),
|
|
},
|
|
{
|
|
path: await write(
|
|
"universal-rust",
|
|
universal(createRustImage({ format: "macho", includeRustc: true })),
|
|
),
|
|
service: (read: MachoSliceArchitecture) =>
|
|
new RustBinaryService({
|
|
identity: rust.identity,
|
|
close: () => rust.close(),
|
|
inspect: (input, options) =>
|
|
rust.inspect({ ...input, architecture: read }, options),
|
|
}),
|
|
},
|
|
];
|
|
// A reader that returns another slice than the request names is refused:
|
|
// the arm64 slice for arm64e, or a slice of another CPU family.
|
|
for (const { path, service } of targets) {
|
|
for (const [requested, read, accepted] of [
|
|
["arm64e", "arm64e", true],
|
|
["arm64e", "arm64", false],
|
|
["x86_64", "arm64", false],
|
|
] as const) {
|
|
const result = await service(read).inspect({
|
|
path,
|
|
architecture: requested,
|
|
});
|
|
expect(
|
|
result.ok ? true : result.error,
|
|
`${path} ${requested} read as ${read}`,
|
|
).toEqual(accepted ? true : expect.any(AnalysisOutputError));
|
|
}
|
|
}
|
|
await go.close();
|
|
await rust.close();
|
|
});
|