mirror of
https://github.com/morluto/rea
synced 2026-10-27 22:45:19 -04:00
4fc6565b0f
* feat(native): inspect offline ELF layout through pwntools * fix(build): prepare offline ELF verification on clean runners * fix(native): preserve snapshot acquisition cancellation * fix(native): handle sectionless ELF and retain decoder diagnostics * test(native): verify malformed symbol table entry sizes * fix(native): respect inherited limits and unused segment fields * fix(native): preserve packed relocations and decoder launch constraints * fix(native): validate symbol spans and preserve resource failures * fix(native): preserve diagnostic completeness and memory failures * fix(native): guard bridge imports against allocation failures * fix(native): validate relocation symbol and section references * fix(native): retain diagnostics through compounded cleanup failures * fix(native): preserve unresolved relocation section references * fix(native): bound linkage evidence and preserve CPU signal diagnostics * fix(native): preserve file-size resource failure evidence * fix(native): retain opaque linkage names and late cancellation output * test(native): make CPU-limit fixture robust across runners * fix(native): verify resource failure branches before interpreting exits * fix(native): validate declared ELF string references * fix(native): validate section-name table before decoding * fix(native): enforce canonical ELF name-table escapes
89 lines
3.4 KiB
TypeScript
89 lines
3.4 KiB
TypeScript
import type { JsonValue } from "./jsonValue.js";
|
|
import {
|
|
AnalysisError,
|
|
type AnalysisCapturedOutput,
|
|
} from "./analysisErrorBase.js";
|
|
|
|
/** Stable failure classes for target-bound deep-provider selection. */
|
|
export type ProviderSelectionFailureReason =
|
|
| "unknown_provider"
|
|
| "provider_unavailable"
|
|
| "target_unsupported"
|
|
| "ambiguous"
|
|
| "invalid_options";
|
|
|
|
/** One actionable candidate rejection retained in caller diagnostics. */
|
|
export interface ProviderSelectionRejection {
|
|
readonly providerId: string;
|
|
readonly code: string;
|
|
readonly reason: string;
|
|
readonly diagnostics: Readonly<Record<string, JsonValue>>;
|
|
}
|
|
|
|
/** Complete typed context for one failed deep-provider selection. */
|
|
export interface ProviderSelectionErrorOptions {
|
|
readonly capturedOutput?: AnalysisCapturedOutput;
|
|
readonly operation?: string;
|
|
readonly reason: ProviderSelectionFailureReason;
|
|
readonly requestedProviderId: string;
|
|
readonly candidateIds: readonly string[];
|
|
readonly rejections?: readonly ProviderSelectionRejection[];
|
|
}
|
|
|
|
/** No configured provider can satisfy a requested operation or target binding. */
|
|
export class ProviderSelectionError extends AnalysisError {
|
|
readonly _tag = "ProviderSelectionError";
|
|
readonly operation: string;
|
|
readonly reason: ProviderSelectionFailureReason;
|
|
readonly requestedProviderId: string;
|
|
readonly candidateIds: readonly string[];
|
|
readonly rejections: readonly ProviderSelectionRejection[];
|
|
override readonly userMessage: string;
|
|
|
|
constructor(options: ProviderSelectionErrorOptions) {
|
|
const operation = options.operation ?? "open_binary";
|
|
super(
|
|
providerSelectionDiagnostic(options),
|
|
options.capturedOutput === undefined
|
|
? undefined
|
|
: { capturedOutput: options.capturedOutput },
|
|
);
|
|
this.operation = operation;
|
|
this.reason = options.reason;
|
|
this.requestedProviderId = options.requestedProviderId;
|
|
this.candidateIds = [...options.candidateIds];
|
|
this.rejections = [...(options.rejections ?? [])].map((rejection) => ({
|
|
...rejection,
|
|
diagnostics: structuredClone(rejection.diagnostics),
|
|
}));
|
|
this.userMessage = providerSelectionUserMessage(options);
|
|
}
|
|
}
|
|
|
|
const providerSelectionDiagnostic = (
|
|
options: ProviderSelectionErrorOptions,
|
|
): string => {
|
|
const candidates =
|
|
options.candidateIds.length === 0
|
|
? "none"
|
|
: options.candidateIds.join(", ");
|
|
return `Analysis provider selection failed (${options.reason}) for ${options.requestedProviderId}; candidates: ${candidates}`;
|
|
};
|
|
|
|
const providerSelectionUserMessage = (
|
|
options: ProviderSelectionErrorOptions,
|
|
): string => {
|
|
switch (options.reason) {
|
|
case "ambiguous":
|
|
return "Multiple analysis providers support this target. Choose one with provider_id, --provider, or REA_ANALYSIS_PROVIDER.";
|
|
case "unknown_provider":
|
|
return `The requested analysis provider is unknown. Choose one of: ${options.candidateIds.join(", ") || "no configured providers"}.`;
|
|
case "provider_unavailable":
|
|
return "The selected analysis provider is unavailable. Review the reported local diagnostics or run `rea doctor`, then retry.";
|
|
case "target_unsupported":
|
|
return "The selected analysis provider does not support this target. Choose another provider or open a supported extracted binary.";
|
|
case "invalid_options":
|
|
return "The analysis provider selection or open options are invalid. Correct them and try again.";
|
|
}
|
|
};
|