Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/dotnet/ManagedStaticProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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}.`,
),
);
Expand Down
37 changes: 37 additions & 0 deletions tests/acceptance/managedCliOutput.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 changes: 15 additions & 0 deletions tests/boundary/mcp/managedMcp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>>;

Expand Down Expand Up @@ -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: {} }),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
},
});
});

Expand Down
Loading