mirror of
https://github.com/morluto/rea
synced 2026-10-27 22:45:19 -04:00
fix(ghidra): admit installation metadata through owned bounded reads
Reject special files without blocking, cap the properties payload at 1 MiB before allocation, and verify descriptor extent and the selected name. Preserve Latin-1 data, selected symlinks, physical filesystem facts, completed observations and exact failed-close ownership. Reuse the stable bounded reader for profile artifacts and consolidate Ghidra file failure projection. Distinguish missing-at-open from disappearance or read failure, and attribute typed prerequisite failures at the consuming operation. Validation: 384 focused tests across 14 files, 42 seed/extension controls, 32 final metadata/profile/CLI controls, check:fast and docs:check. Controlled macOS file/process fixtures; no real Ghidra/JVM or Windows/Linux lifecycle verification. Bounded FIFO reproduction: baseline direct and public doctor required external cleanup around 2.2s; candidate returned independently around 0.4/0.57s, all fixture groups verified empty. Warm normal doctor baseline/candidate: elapsed 1.211/1.230s, CPU 1.239/1.247s, sampled family RSS 524/524MB, reply tokens 3116/3116. No performance improvement claimed; true cold and whole-agent costs unmeasured. Refs #4672
This commit is contained in:
@@ -4,7 +4,12 @@ import {
|
||||
createAnalysisExecution,
|
||||
type AnalysisClient,
|
||||
} from "../AnalysisProvider.js";
|
||||
import { AnalysisCancelledError } from "../../domain/analysisErrorCore.js";
|
||||
import {
|
||||
AnalysisCancelledError,
|
||||
AnalysisAccessDeniedError,
|
||||
AnalysisArtifactChangedError,
|
||||
AnalysisResourceConstraintError,
|
||||
} from "../../domain/analysisErrorCore.js";
|
||||
import { ProviderAdapterError } from "../../domain/providerAdapterError.js";
|
||||
import { ProviderCleanupError } from "../../domain/providerCleanupError.js";
|
||||
import { projectAnalysisError } from "../../domain/analysisErrorProjection.js";
|
||||
@@ -12,6 +17,51 @@ import { resolvedAnalysisError } from "../../domain/analysisErrorBase.js";
|
||||
import { err, ok } from "../../domain/result.js";
|
||||
|
||||
const identity = { id: "controlled", name: "Controlled client", version: "1" };
|
||||
|
||||
it.each([
|
||||
new AnalysisAccessDeniedError(
|
||||
"ghidra:installation",
|
||||
"/selected/properties",
|
||||
"EACCES",
|
||||
),
|
||||
new AnalysisArtifactChangedError(
|
||||
"ghidra:installation",
|
||||
"/selected/properties",
|
||||
"selected name changed",
|
||||
),
|
||||
new AnalysisResourceConstraintError(
|
||||
"ghidra:installation",
|
||||
"file-size",
|
||||
"metadata budget",
|
||||
{ maximum_bytes: 1024 },
|
||||
{ retryable: false },
|
||||
),
|
||||
])(
|
||||
"attributes prerequisite $_tag to the requested operation without changing its facts",
|
||||
async (physical) => {
|
||||
const client = new DeferredAnalysisClient(async () => {
|
||||
throw physical;
|
||||
}, identity.id);
|
||||
try {
|
||||
const result = await client.execute("analyze_function", {});
|
||||
if (result.ok) throw new Error("Expected prerequisite failure");
|
||||
expect(result.error).toMatchObject({
|
||||
_tag: physical._tag,
|
||||
operation: "analyze_function",
|
||||
});
|
||||
expect(result.error.cause).toBe(physical);
|
||||
if (physical instanceof AnalysisResourceConstraintError)
|
||||
expect(result.error).toMatchObject({
|
||||
resource: "file-size",
|
||||
reportedLimits: { maximum_bytes: 1024 },
|
||||
retryable: false,
|
||||
});
|
||||
else expect(result.error).toMatchObject({ path: "/selected/properties" });
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
const gate = <T = void>() => {
|
||||
let resolve!: (value: T) => void;
|
||||
const promise = new Promise<T>((finish) => {
|
||||
|
||||
Reference in New Issue
Block a user