mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
fix(managed): refuse non-PE inputs as unsupported targets (#6287)
The managed static provider refused a readable non-PE executable with AnalysisCapabilityUnavailableError, the same type as its unimplemented operation guard. inspect-managed-artifact, inspect-managed-members and inspect-managed-native-boundaries therefore reported capability_unavailable / unsupported_provider and omitted the selected path. Return AnalysisUnsupportedTargetError with the operation, path and observed format instead. Unimplemented operations keep the capability error. Fixes #6076
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
AnalysisCancelledError,
|
||||
AnalysisCapabilityUnavailableError,
|
||||
AnalysisInputError,
|
||||
AnalysisUnsupportedTargetError,
|
||||
} from "../domain/analysisErrorCore.js";
|
||||
import { EvidenceIntegrityError } from "../domain/evidenceErrors.js";
|
||||
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
||||
@@ -85,11 +86,13 @@ class ManagedStaticClient implements AnalysisClient {
|
||||
"Operation is not implemented by the managed static provider.",
|
||||
),
|
||||
);
|
||||
// A non-PE target is outside this operation's formats, not a missing
|
||||
// provider capability; the unimplemented-operation refusal above is.
|
||||
if (this.target.format !== "pe")
|
||||
return err(
|
||||
new AnalysisCapabilityUnavailableError(
|
||||
MANAGED_STATIC_PROVIDER.id,
|
||||
new AnalysisUnsupportedTargetError(
|
||||
operation,
|
||||
this.target.path,
|
||||
`Managed static triage requires a PE target; observed ${this.target.format}.`,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { join } from "node:path";
|
||||
|
||||
import { expect } from "vitest";
|
||||
|
||||
import { elf, thinMach } from "../../src/domain/binaryTarget.fixture.js";
|
||||
import { buildManagedPeFixture } from "../../src/dotnet/ManagedPe.fixture.js";
|
||||
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../support/cli/cliFixture.js";
|
||||
@@ -418,3 +419,39 @@ cliTest(
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"managed CLI refuses non-PE executables as unsupported targets",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-managed-non-pe-");
|
||||
for (const [name, bytes, format] of [
|
||||
["native.elf", elf(2, 1, 0x3e), "elf"],
|
||||
["native.macho", thinMach(0xfeedfacf, 0x01000007), "mach-o"],
|
||||
] as const) {
|
||||
const path = join(root, name);
|
||||
await writeFile(path, bytes);
|
||||
for (const command of [
|
||||
"inspect-managed-artifact",
|
||||
"inspect-managed-members",
|
||||
"inspect-managed-native-boundaries",
|
||||
]) {
|
||||
const result = await cli.run({ arguments: [command, path, "--json"] });
|
||||
expect(result.exitCode).not.toBe(0);
|
||||
expect(result.json).toMatchObject({
|
||||
code: "unsupported_target",
|
||||
category: "unsupported_target",
|
||||
retryable: false,
|
||||
remediation: {
|
||||
action:
|
||||
"Select a target supported by this operation or choose an operation supporting the reported target format.",
|
||||
},
|
||||
details: {
|
||||
operation: command.replaceAll("-", "_"),
|
||||
path,
|
||||
reason: `Managed static triage requires a PE target; observed ${format}.`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -20,6 +20,7 @@ import { toolContract } from "../../../src/contracts/toolContracts.js";
|
||||
import { ManagedStaticProvider } from "../../../src/dotnet/ManagedStaticProvider.js";
|
||||
import { createServer } from "../../../src/server/createServer.js";
|
||||
import { buildManagedPeFixture } from "../../../src/dotnet/ManagedPe.fixture.js";
|
||||
import { elf } from "../../../src/domain/binaryTarget.fixture.js";
|
||||
|
||||
type ManagedOutputAssertion = Awaited<ReturnType<typeof createOutputAssertion>>;
|
||||
|
||||
@@ -89,6 +90,20 @@ it("runs every managed static inspection independently of an active native targe
|
||||
arguments: { path: join(directory, "missing.dll") },
|
||||
});
|
||||
expect(invalidSelection.isError).toBe(true);
|
||||
const nativePath = join(directory, "native.elf");
|
||||
await writeFile(nativePath, elf(2, 1, 0x3e));
|
||||
expect(
|
||||
parseMcpToolError(
|
||||
await client.callTool({
|
||||
name: "inspect_managed_artifact",
|
||||
arguments: { path: nativePath },
|
||||
}),
|
||||
).error,
|
||||
).toMatchObject({
|
||||
code: "unsupported_target",
|
||||
category: "unsupported_target",
|
||||
details: { operation: "inspect_managed_artifact", path: nativePath },
|
||||
});
|
||||
const members = structured(
|
||||
await client.callTool({ name: "inspect_managed_members", arguments: {} }),
|
||||
);
|
||||
|
||||
@@ -275,7 +275,12 @@ describe("managed static provider path boundary", () => {
|
||||
nativeClient.execute("inspect_managed_artifact", {}),
|
||||
).resolves.toMatchObject({
|
||||
ok: false,
|
||||
error: { _tag: "AnalysisCapabilityUnavailableError" },
|
||||
error: {
|
||||
_tag: "AnalysisUnsupportedTargetError",
|
||||
operation: "inspect_managed_artifact",
|
||||
path: parsed.value.path,
|
||||
reason: "Managed static triage requires a PE target; observed elf.",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user