mirror of
https://github.com/morluto/rea.git
synced 2026-10-28 10:25:42 +00:00
Host and tool-configuration refusals from the pwntools, EVMole, firmware, mitmproxy, Wakaru, LLDB and xcrun adapters carried no userMessage, so CLI and MCP callers saw the generic "This analysis is unavailable for the current target. Choose another analysis or target." as both message and remediation. Choosing another target cannot satisfy a Linux-only profile or an unset REA_*_COMMAND. The actual requirement appeared only in details.reason. Pass each refusal's reason as its userMessage, as the adapters' other configuration refusals (EVMole limits, JADX, pwndbg) already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
3.2 KiB
TypeScript
102 lines
3.2 KiB
TypeScript
import { chmod, mkdir, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
|
|
import { expect, it as test } from "vitest";
|
|
|
|
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
|
|
import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
|
|
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
import { resolveFirmwareCommand } from "./FirmwareCommand.js";
|
|
|
|
const it = test.skipIf(process.platform !== "linux");
|
|
|
|
test("names the host and tool requirement of an unconfigured engine", async () => {
|
|
const refusal: unknown = await resolveFirmwareCommand(
|
|
{},
|
|
"binwalk",
|
|
"inspect_firmware_regions",
|
|
).catch((cause: unknown) => cause);
|
|
|
|
expect(refusal).toMatchObject({
|
|
_tag: "AnalysisCapabilityUnavailableError",
|
|
});
|
|
if (!(refusal instanceof AnalysisCapabilityUnavailableError))
|
|
throw new Error("Expected a capability refusal");
|
|
expect(projectAnalysisError(refusal)).toMatchObject({
|
|
code: "capability_unavailable",
|
|
message: refusal.reason,
|
|
remediation: { action: refusal.reason },
|
|
});
|
|
expect(refusal.reason).toContain("REA_BINWALK_COMMAND");
|
|
});
|
|
|
|
it("rejects a directory configured as the firmware engine executable", async () => {
|
|
const root = await createTestTempDirectory("rea-firmware-command-");
|
|
const command = join(root, "binwalk");
|
|
const limiter = await executableFixture(root, "prlimit");
|
|
await mkdir(command);
|
|
|
|
await expect(
|
|
resolveFirmwareCommand(
|
|
{
|
|
REA_BINWALK_COMMAND: command,
|
|
REA_FIRMWARE_PRLIMIT_COMMAND: limiter,
|
|
},
|
|
"binwalk",
|
|
"inspect_firmware_regions",
|
|
),
|
|
).rejects.toMatchObject({
|
|
_tag: "AnalysisCapabilityUnavailableError",
|
|
reason: expect.stringContaining(command),
|
|
});
|
|
});
|
|
|
|
it("classifies an unusable firmware engine as an unavailable capability", async () => {
|
|
const root = await createTestTempDirectory("rea-firmware-command-");
|
|
const command = join(root, "binwalk");
|
|
const limiter = await executableFixture(root, "prlimit");
|
|
await writeFile(command, "not executable", { mode: 0o600 });
|
|
|
|
await expect(
|
|
resolveFirmwareCommand(
|
|
{
|
|
REA_BINWALK_COMMAND: command,
|
|
REA_FIRMWARE_PRLIMIT_COMMAND: limiter,
|
|
},
|
|
"binwalk",
|
|
"inspect_firmware_regions",
|
|
),
|
|
).rejects.toMatchObject({
|
|
_tag: "AnalysisCapabilityUnavailableError",
|
|
reason: expect.stringContaining(command),
|
|
});
|
|
});
|
|
|
|
it("rejects a directory configured as the resource limiter executable", async () => {
|
|
const root = await createTestTempDirectory("rea-firmware-limiter-");
|
|
const command = await executableFixture(root, "binwalk");
|
|
const limiter = join(root, "prlimit");
|
|
await mkdir(limiter);
|
|
|
|
await expect(
|
|
resolveFirmwareCommand(
|
|
{
|
|
REA_BINWALK_COMMAND: command,
|
|
REA_FIRMWARE_PRLIMIT_COMMAND: limiter,
|
|
},
|
|
"binwalk",
|
|
"inspect_firmware_regions",
|
|
),
|
|
).rejects.toMatchObject({
|
|
_tag: "AnalysisCapabilityUnavailableError",
|
|
reason: expect.stringContaining(limiter),
|
|
});
|
|
});
|
|
|
|
const executableFixture = async (root: string, name: string) => {
|
|
const path = join(root, name);
|
|
await writeFile(path, "#!/bin/sh\n");
|
|
await chmod(path, 0o700);
|
|
return path;
|
|
};
|