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:
Muhammad Hamza
2026-10-22 14:50:42 +05:00
committed by GitHub
parent aff5e23ecf
commit 3b2d2863da
4 changed files with 63 additions and 3 deletions
+5 -2
View File
@@ -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}.`,
),
);
+37
View File
@@ -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}.`,
},
});
}
}
},
);
+15
View File
@@ -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.",
},
});
});