fix(native): refuse to list architectures of non-Mach-O targets (#1325)
list_architectures ran lipo on every admitted target. For a PE DLL, ELF binary or plist, lipo's refusal surfaced as execution_failure with "Retry once; if it continues, run rea doctor", which neither can fix. Refuse non-Mach-O targets as capability_unavailable before running lipo, as inspect_macho already does. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
56598beb4e
commit
1b73b5ab4b
|
|
@ -283,6 +283,16 @@ class NativeMacOSClient implements AnalysisClient {
|
|||
async #listArchitectures(
|
||||
signal?: AbortSignal,
|
||||
): Promise<Result<NativeObservation, AnalysisError>> {
|
||||
// lipo reads only Mach-O; its refusal of a PE, ELF, or plist target is not
|
||||
// a tool failure that a retry or `rea doctor` could repair.
|
||||
if (this.target.format !== "mach-o")
|
||||
return err(
|
||||
new AnalysisCapabilityUnavailableError(
|
||||
IDENTITY.id,
|
||||
"list_architectures",
|
||||
"Active artifact is not Mach-O.",
|
||||
),
|
||||
);
|
||||
const capture = await this.#run(
|
||||
"list_architectures",
|
||||
"lipo",
|
||||
|
|
|
|||
|
|
@ -694,6 +694,31 @@ describe("native macOS provider failures and parsing", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
...machoTarget("/fixture.dll"),
|
||||
format: "pe" as const,
|
||||
executableRole: "shared-library" as const,
|
||||
managed: false,
|
||||
},
|
||||
{ ...machoTarget("/fixture.elf"), format: "elf" as const },
|
||||
])(
|
||||
"refuses to list architectures of a $format target without running lipo",
|
||||
async (target) => {
|
||||
const runner = new CountingRunner();
|
||||
const result = await new NativeMacOSProvider({}, runner, "darwin")
|
||||
.createClient(target)
|
||||
.execute("list_architectures", {});
|
||||
if (result.ok) throw new Error("Expected a non-Mach-O refusal");
|
||||
expect(result.error._tag).toBe("AnalysisCapabilityUnavailableError");
|
||||
expect(projectAnalysisError(result.error)).toMatchObject({
|
||||
code: "capability_unavailable",
|
||||
details: { reason: "Active artifact is not Mach-O." },
|
||||
});
|
||||
expect(runner.calls).toBe(0);
|
||||
},
|
||||
);
|
||||
|
||||
it("classifies pre-aborted requests before operation or runner discovery", async () => {
|
||||
const controller = new AbortController();
|
||||
controller.abort();
|
||||
|
|
|
|||
Loading…
Reference in New Issue