mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
* fix(native): preserve Mach-O target selection in macOS tools * fix(native): retain exact Mach-O slice signature coverage * fix(native): admit x86_64 LIB64 signature selectors * test(native): match signature checks to actual slices * fix(native): recognize vtool refusals on private Mach-O aliases Match vtool's container refusal to the operand the command received so a parenthesized universal path keeps completed facts and the refusal limitation. Expect codesign -a only when the target format is universal. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import { expect, it } from "vitest";
|
|
|
|
import { AnalysisOutputError } from "../domain/analysisErrorCore.js";
|
|
import { err, ok } from "../domain/result.js";
|
|
import {
|
|
NativeFixtureRunner,
|
|
nativeMachoTarget,
|
|
} from "../../tests/fixtures/nativeCommands.js";
|
|
import {
|
|
inspectNativeMacho,
|
|
VTOOL_CONTAINER_REFUSAL_LIMITATION,
|
|
} from "./NativeMachoInspection.js";
|
|
import {
|
|
inspectionReader,
|
|
unreadEncryption,
|
|
} from "./NativeMachoInspection.fixture.js";
|
|
|
|
const inspect = async (options: {
|
|
readonly diagnostic: string;
|
|
readonly format?: "fat" | "thin";
|
|
readonly stdout?: string;
|
|
readonly signal?: string | null;
|
|
}) => {
|
|
const path = "/fixture/universal";
|
|
const runner = new NativeFixtureRunner(
|
|
options.format === "thin"
|
|
? { lipo: `Non-fat file: ${path} is architecture: arm64\n` }
|
|
: {},
|
|
);
|
|
return inspectNativeMacho({
|
|
readCommandNames: inspectionReader(),
|
|
readEncryption: unreadEncryption,
|
|
target: nativeMachoTarget(path),
|
|
run: async (tool, args, _signal, acceptNonZeroIf) => {
|
|
const result = await runner.run(tool, args);
|
|
if (!result.ok || tool !== "vtool") return result;
|
|
const refused = {
|
|
...result.value,
|
|
stdout: options.stdout ?? "",
|
|
stdoutBytes: Buffer.byteLength(options.stdout ?? ""),
|
|
stderr: options.diagnostic,
|
|
stderrBytes: Buffer.byteLength(options.diagnostic),
|
|
exitCode: 1,
|
|
signal: options.signal ?? null,
|
|
};
|
|
return acceptNonZeroIf?.(refused)
|
|
? ok(refused)
|
|
: err(new AnalysisOutputError("inspect_macho", "vtool failed"));
|
|
},
|
|
invocation: (value) => ({
|
|
tool: value.tool,
|
|
command: [value.executable, ...value.arguments],
|
|
tool_version: value.toolVersion,
|
|
version_reason: value.versionReason,
|
|
executable_sha256: value.executableSha256,
|
|
exit: { code: value.exitCode, signal: value.signal },
|
|
stdout_bytes: value.stdoutBytes,
|
|
stderr_bytes: value.stderrBytes,
|
|
}),
|
|
});
|
|
};
|
|
|
|
const refusal = "/usr/bin/vtool error: /fixture/universal file is not mach-o\n";
|
|
|
|
it("retains required facts and failed vtool provenance for its universal-container refusal", async () => {
|
|
const result = await inspect({ diagnostic: refusal });
|
|
if (!result.ok) throw result.error;
|
|
expect(result.value.limitations).toContain(
|
|
VTOOL_CONTAINER_REFUSAL_LIMITATION,
|
|
);
|
|
expect(result.value.result).toMatchObject({
|
|
format: "mach-o-universal",
|
|
selected_architecture: { name: "arm64" },
|
|
build_metadata: {
|
|
items: [{ platform: "MACOS", minimum_os: "13.0", sdk: "14.2" }],
|
|
},
|
|
dependencies: {
|
|
items: [{ path: "/usr/lib/libSystem.B.dylib", kind: "LC_LOAD_DYLIB" }],
|
|
},
|
|
imports: {
|
|
items: expect.arrayContaining([
|
|
expect.objectContaining({ name: "__Block_copy" }),
|
|
]),
|
|
},
|
|
exports: {
|
|
items: expect.arrayContaining([
|
|
expect.objectContaining({ name: "_main" }),
|
|
]),
|
|
},
|
|
uuid: "01234567-89AB-CDEF-0123-456789ABCDEF",
|
|
provenance: expect.arrayContaining([
|
|
expect.objectContaining({
|
|
tool: "vtool",
|
|
exit: { code: 1, signal: null },
|
|
}),
|
|
]),
|
|
});
|
|
});
|
|
|
|
it.each([
|
|
{ diagnostic: refusal, format: "thin" as const },
|
|
{ diagnostic: `${refusal}another error\n` },
|
|
{ diagnostic: "/usr/bin/vtool error: /other file is not mach-o\n" },
|
|
{ diagnostic: refusal, stdout: "unexpected output" },
|
|
{ diagnostic: refusal, signal: "SIGTERM" },
|
|
])("does not suppress other vtool failures: $diagnostic", async (options) => {
|
|
const result = await inspect(options);
|
|
expect(result).toMatchObject({
|
|
ok: false,
|
|
error: { reason: "vtool failed" },
|
|
});
|
|
});
|