Files
rea/src/domain/analysisView/analysisView.ts
T
Kaoru0822andClaude Opus 5.5 6b68fb642a fix(ci): remove unused exports that fail deep static checks (#8095)
* fix(ci): remove unused exports that fail deep static checks

Knip on main reports three analysis-view hub re-exports, two type
re-exports, an unused artifact-format guard and an alias constant. Drop
the dead re-exports and guard, and give the debugger control-reply budget
its own literal: it is a separate budget from the caller command-output
default, as its comment already states.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(config): read the Rizin control budget from its own constant

The Rizin control-reply admission limit still took its value from the
caller command-output default, while GDB used DEBUGGER_CONTROL_REPLY_BYTES.
Read the dedicated constant in both so the control budget has one owner.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 02:25:43 -07:00

475 lines
19 KiB
TypeScript

import { NATIVE_OBSERVATION_OPERATIONS } from "../native/nativeObservation.js";
import { projectNativeObservationView } from "./nativeObservationView.js";
import { projectDevicetreeView } from "./devicetreeView.js";
import { projectApkSignatureView } from "./apkSignatureView.js";
import { byteEntropySchema } from "../native/byteEntropy.js";
import { projectErlangBeamView } from "./erlangBeamView.js";
import { projectPythonPycView } from "./pythonPycView.js";
import { projectNativeExportsView } from "./nativeExportsView.js";
import { projectByteEntropyView } from "./byteEntropyView.js";
import {
parseAnalysisViewResult,
analysisViewResultInputError,
} from "./analysisViewParent.js";
import { projectJavaScriptRoutesView } from "./javascriptRoutesView.js";
import { projectWebBundleView } from "./webBundleView.js";
import { projectSourceToBundleView } from "./sourceToBundleView.js";
import { projectGpuCodeObjectsView } from "./gpuCodeObjectsView.js";
import { projectModelArtifactView } from "./modelArtifactView.js";
import { projectCommandObservationView } from "./commandObservationView.js";
import { projectFridaSessionStatusView } from "./fridaSessionStatusView.js";
import { projectGoBinaryView } from "./goBinaryView.js";
import { projectRustBinaryView } from "./rustBinaryView.js";
import { projectNativeFunctionMatchingView } from "./nativeFunctionMatchingView.js";
import { projectNativeInventoryView } from "./nativeInventoryView.js";
import { NATIVE_INVENTORY_OPERATIONS } from "../native/nativeInventory.js";
import { z } from "zod";
import { projectBrowserScenarioView } from "./browserScenarioView.js";
import { projectNativeLoadImageView } from "./nativeLoadImageView.js";
import { projectDesktopApplicationView } from "./desktopApplicationView.js";
import { AnalysisUnsupportedTargetError } from "../analysisErrorCore.js";
import {
INSPECT_ANALYSIS_VIEW_OPERATION,
analysisViewInputError,
} from "./analysisViewErrors.js";
import { digestCanonicalValue } from "../canonicalDigest.js";
import { digestSchema } from "../digests.js";
import { err, ok, type Result } from "../result.js";
import type { AnalysisError } from "../analysisErrorBase.js";
import { safeParseOwnedBinaryLayout } from "../native/binaryLayout.js";
import { functionDossierSchema } from "../native/functionDossier.js";
import {
parseOwnedJavaScriptApplicationAnalysisSteps,
type JavaScriptApplicationAnalysisResult,
} from "../javascript/javascriptApplicationAnalysis.js";
import { projectBinaryLayoutView } from "./binaryLayoutView.js";
import { projectJavaScriptApplicationView } from "./javascriptApplicationView.js";
import {
createApiSurfaceAccumulator,
projectWebNetworkApiSurfaceView,
} from "./webNetworkApiSurfaceView.js";
import { projectNativeFunctionView } from "./nativeFunctionView.js";
import { projectEvmInterfaceView } from "./evmInterfaceView.js";
import { projectArtifactInventoryView } from "./artifactInventoryView.js";
import { projectManagedArtifactView } from "./managedArtifactView.js";
import { projectManagedMemberView } from "./managedMemberView.js";
import { projectWasmArtifactView } from "./wasmArtifactView.js";
import { projectMachoView } from "./machoView.js";
import { projectInterfaceBuilderView } from "./interfaceBuilderView.js";
import { projectWebNetworkCaptureView } from "./webNetworkCaptureView.js";
import type { WebNetworkApiSurfaceAccumulator } from "./WebNetworkApiSurfaceAccumulator.js";
import type { EnvironmentManifestAccumulator } from "./EnvironmentManifestAccumulator.js";
import type { EnvironmentStateAccumulator } from "./EnvironmentStateAccumulator.js";
import { admitAnalysisViewData } from "./analysisViewDataAdmission.js";
import {
createEnvironmentManifestAccumulator,
projectEnvironmentManifestView,
} from "./environmentManifestView.js";
import {
createEnvironmentStateAccumulator,
projectEnvironmentStateView,
} from "./environmentStateView.js";
import { projectEnvironmentCoverageView } from "./environmentCoverageView.js";
import { projectPcapCaptureView } from "./pcapCaptureView.js";
import { projectAndroidPackageView } from "./androidPackageView.js";
import { projectAndroidSymbolSummary } from "./androidSymbolView.js";
import { projectAndroidJniView } from "./androidJniView.js";
import { projectDartAotView } from "./dartAotView.js";
import { projectIl2cppMetadataView } from "./il2cppMetadataView.js";
import type { AnalysisViewParent } from "./analysisViewParent.js";
import type { GroupingViewKind } from "./analysisViewShape.js";
import {
analysisViewRequestSchema,
inspectAnalysisViewInputSchema,
type AnalysisViewRequest,
type InspectAnalysisViewInput,
} from "./analysisViewRequest.js";
import {
nativeObservationSummaryViewResultSchemas,
byteEntropySummaryViewResultSchema,
nativeExportsSummaryViewResultSchema,
devicetreeSummaryViewResultSchema,
erlangBeamSummaryViewResultSchema,
erlangBeamTableViewResultSchema,
pythonPycSummaryViewResultSchema,
pythonPycCodeObjectsViewResultSchema,
gdbCommandSummaryViewResultSchema,
objdumpSummaryViewResultSchema,
fridaSessionStatusSummaryViewResultSchema,
goBinarySummaryViewResultSchema,
rustBinarySummaryViewResultSchema,
rustBinaryPageViewResultSchema,
binaryLayoutSummaryViewResultSchema,
javascriptApplicationSummaryViewResultSchema,
artifactInventorySummaryViewResultSchema,
desktopApplicationSummaryViewResultSchema,
wasmArtifactSummaryViewResultSchema,
machoSummaryViewResultSchema,
interfaceBuilderSummaryViewResultSchema,
evmInterfaceSummaryViewResultSchema,
managedArtifactSummaryViewResultSchema,
managedMemberSummaryViewResultSchema,
webNetworkCaptureSummaryViewResultSchema,
browserScenarioSummaryViewResultSchema,
androidPackageSummaryViewResultSchema,
androidJniSummaryViewResultSchema,
androidJniPageViewResultSchema,
androidClassSummaryViewResultSchema,
androidMethodSummaryViewResultSchema,
androidManifestViewResultSchema,
androidComponentsViewResultSchema,
androidComponentSummaryViewResultSchema,
pcapCaptureSummaryViewResultSchema,
dartAotSummaryViewResultSchema,
javaScriptRoutesViewResultSchema,
webBundleSummaryViewResultSchema,
webBundlePageViewResultSchema,
gpuCodeObjectsSummaryViewResultSchema,
gpuCodeObjectsPageViewResultSchema,
apkSignatureSummaryViewResultSchema,
apkSignaturePageViewResultSchema,
modelArtifactSummaryViewResultSchema,
modelArtifactPageViewResultSchema,
il2cppMetadataSummaryViewResultSchema,
nativeInventorySummaryViewResultSchema,
nativeLoadImageSummaryViewResultSchema,
nativeFunctionMatchingSummaryViewResultSchema,
nativeFunctionSummaryViewResultSchema,
sourceToBundleSummaryViewResultSchema,
sourceToBundlePageViewResultSchema,
analysisViewResultSchema,
type AnalysisViewResult,
type UnsignedAnalysisView,
} from "./analysisViewResult.js";
export {
analysisViewRequestSchema,
inspectAnalysisViewInputSchema,
type AnalysisViewRequest,
type InspectAnalysisViewInput,
type AnalysisViewParent,
};
export {
nativeObservationSummaryViewResultSchemas,
byteEntropySummaryViewResultSchema,
nativeExportsSummaryViewResultSchema,
devicetreeSummaryViewResultSchema,
erlangBeamSummaryViewResultSchema,
erlangBeamTableViewResultSchema,
pythonPycSummaryViewResultSchema,
pythonPycCodeObjectsViewResultSchema,
gdbCommandSummaryViewResultSchema,
objdumpSummaryViewResultSchema,
fridaSessionStatusSummaryViewResultSchema,
goBinarySummaryViewResultSchema,
rustBinarySummaryViewResultSchema,
rustBinaryPageViewResultSchema,
binaryLayoutSummaryViewResultSchema,
javascriptApplicationSummaryViewResultSchema,
artifactInventorySummaryViewResultSchema,
desktopApplicationSummaryViewResultSchema,
wasmArtifactSummaryViewResultSchema,
machoSummaryViewResultSchema,
interfaceBuilderSummaryViewResultSchema,
evmInterfaceSummaryViewResultSchema,
managedArtifactSummaryViewResultSchema,
managedMemberSummaryViewResultSchema,
webNetworkCaptureSummaryViewResultSchema,
browserScenarioSummaryViewResultSchema,
androidPackageSummaryViewResultSchema,
androidJniSummaryViewResultSchema,
androidJniPageViewResultSchema,
androidClassSummaryViewResultSchema,
androidMethodSummaryViewResultSchema,
androidManifestViewResultSchema,
androidComponentsViewResultSchema,
androidComponentSummaryViewResultSchema,
pcapCaptureSummaryViewResultSchema,
dartAotSummaryViewResultSchema,
javaScriptRoutesViewResultSchema,
webBundleSummaryViewResultSchema,
webBundlePageViewResultSchema,
gpuCodeObjectsSummaryViewResultSchema,
gpuCodeObjectsPageViewResultSchema,
apkSignatureSummaryViewResultSchema,
apkSignaturePageViewResultSchema,
modelArtifactSummaryViewResultSchema,
modelArtifactPageViewResultSchema,
il2cppMetadataSummaryViewResultSchema,
nativeInventorySummaryViewResultSchema,
nativeLoadImageSummaryViewResultSchema,
nativeFunctionMatchingSummaryViewResultSchema,
nativeFunctionSummaryViewResultSchema,
sourceToBundleSummaryViewResultSchema,
sourceToBundlePageViewResultSchema,
analysisViewResultSchema,
type AnalysisViewResult,
type UnsignedAnalysisView,
};
/** Attach the content digest that must change when projected bytes change. */
export const sealAnalysisView = (
projection: UnsignedAnalysisView,
): AnalysisViewResult =>
analysisViewResultSchema.parse({
...projection,
view_digest: digestCanonicalValue(projection, "Analysis view"),
});
const parentDigest = (evidenceId: string): string => evidenceId.slice(3);
const parseJavaScriptParent = (
input: unknown,
): Result<JavaScriptApplicationAnalysisResult, AnalysisError> => {
try {
// The format owner authenticates imported results completely before reuse;
// mutable or merely frozen inputs still receive canonical validation.
const steps = parseOwnedJavaScriptApplicationAnalysisSteps(input);
let step = steps.next();
while (!step.done) step = steps.next();
return ok(step.value);
} catch (cause: unknown) {
if (!(cause instanceof z.ZodError)) throw cause;
return err(analysisViewResultInputError(input, cause));
}
};
const unsupportedParent = (
parent: AnalysisViewParent,
): AnalysisUnsupportedTargetError =>
new AnalysisUnsupportedTargetError(
INSPECT_ANALYSIS_VIEW_OPERATION,
parentArtifactPath(parent),
`Parent Evidence operation ${JSON.stringify(parent.operation)} does not support analysis views. Use completed Evidence from a supported parent operation with a compatible view. For a summary receipt, use its normalized_result.parent_evidence_id rather than the receipt's own evidence_id.`,
);
const parentArtifactPath = (parent: AnalysisViewParent): string => {
if (
typeof parent.normalizedResult === "object" &&
parent.normalizedResult !== null &&
"artifact" in parent.normalizedResult &&
typeof parent.normalizedResult.artifact === "object" &&
parent.normalizedResult.artifact !== null &&
"path" in parent.normalizedResult.artifact &&
typeof parent.normalizedResult.artifact.path === "string"
)
return parent.normalizedResult.artifact.path;
if (
typeof parent.normalizedResult === "object" &&
parent.normalizedResult !== null &&
"input_path" in parent.normalizedResult &&
typeof parent.normalizedResult.input_path === "string"
)
return parent.normalizedResult.input_path;
return parent.evidenceId;
};
/** Check a projector result against the result union before sealing it. */
const sealProjected = (
projected: Result<UnsignedAnalysisView, AnalysisError>,
): Result<AnalysisViewResult, AnalysisError> =>
projected.ok ? ok(sealAnalysisView(projected.value)) : projected;
/** Named source owners for views that need no extra decoder or accumulator. */
type RetainedViewProjector = (
parent: AnalysisViewParent,
view: AnalysisViewRequest,
) => Result<UnsignedAnalysisView, AnalysisError>;
/** Register a projector whose inferred result must be in the result union. */
const retain = (
operation: string,
project: RetainedViewProjector,
): readonly [string, RetainedViewProjector] => [operation, project];
const retainedViewProjectors = new Map<string, RetainedViewProjector>([
...NATIVE_OBSERVATION_OPERATIONS.map((operation) =>
retain(operation, projectNativeObservationView),
),
retain("inspect_erlang_beam", projectErlangBeamView),
retain("inspect_devicetree", projectDevicetreeView),
retain("inspect_native_exports", projectNativeExportsView),
retain("inspect_native_load_image", projectNativeLoadImageView),
retain("inspect_python_pyc", projectPythonPycView),
retain("frida_session_status", projectFridaSessionStatusView),
retain("gdb_console", projectCommandObservationView),
retain("inspect_with_objdump", projectCommandObservationView),
retain("inspect_go_binary", projectGoBinaryView),
retain("inspect_rust_binary", projectRustBinaryView),
...NATIVE_INVENTORY_OPERATIONS.map((operation) =>
retain(operation, projectNativeInventoryView),
),
retain("inspect_desktop_application", projectDesktopApplicationView),
retain("inspect_wasm_artifact", projectWasmArtifactView),
retain("inspect_macho", projectMachoView),
retain("decode_interface_builder", projectInterfaceBuilderView),
retain("inspect_evm_interface", projectEvmInterfaceView),
retain("inspect_managed_artifact", projectManagedArtifactView),
retain("inspect_managed_members", projectManagedMemberView),
retain("inspect_android_package", projectAndroidPackageView),
retain("inspect_android_class", projectAndroidSymbolSummary),
retain("inspect_android_method", projectAndroidSymbolSummary),
retain("inspect_android_jni_bindings", projectAndroidJniView),
retain("capture_browser_scenario", projectBrowserScenarioView),
retain("inspect_dart_aot", projectDartAotView),
retain("inspect_il2cpp_metadata", projectIl2cppMetadataView),
retain("inspect_apk_signature", projectApkSignatureView),
retain("inspect_model_artifact", projectModelArtifactView),
retain("inspect_gpu_code_objects", projectGpuCodeObjectsView),
retain("match_native_functions", projectNativeFunctionMatchingView),
retain("compare_source_to_bundle", projectSourceToBundleView),
retain("inspect_artifact", projectArtifactInventoryView),
retain("inventory_artifact", projectArtifactInventoryView),
retain("analyze_web_bundle", projectWebBundleView),
]);
/** Budgets retained across source admission and the selected grouping projection. */
export interface AnalysisViewAccumulators {
readonly apiSurface?: WebNetworkApiSurfaceAccumulator | undefined;
readonly manifest?: EnvironmentManifestAccumulator | undefined;
readonly state?: EnvironmentStateAccumulator | undefined;
}
/** Prepare one view's source admission and projection under the same owned budget. */
export const prepareAnalysisViewProjection = (
view: AnalysisViewRequest,
): {
admitInlineEvidence(value: unknown): Result<void, AnalysisError>;
project(
parent: AnalysisViewParent,
): Result<AnalysisViewResult, AnalysisError>;
} => {
const accumulators: AnalysisViewAccumulators = {
apiSurface:
view.kind === "api-surface"
? createApiSurfaceAccumulator(view)
: undefined,
manifest:
view.kind === "environment-manifest"
? createEnvironmentManifestAccumulator(view)
: undefined,
state:
view.kind === "environment-state" || view.kind === "environment-coverage"
? createEnvironmentStateAccumulator(view)
: undefined,
};
const accumulator =
accumulators.apiSurface ?? accumulators.manifest ?? accumulators.state;
return {
admitInlineEvidence: (value) =>
accumulator === undefined
? admitAnalysisViewData(value, true)
: accumulator.admitInlineEvidence(value),
project: (parent) => projectAnalysisView(parent, view, accumulators),
};
};
type GroupingViewRequest = Extract<
AnalysisViewRequest,
{ kind: GroupingViewKind }
>;
const isGroupingView = (
view: AnalysisViewRequest,
): view is GroupingViewRequest =>
view.kind === "api-surface" ||
view.kind === "environment-manifest" ||
view.kind === "environment-state" ||
view.kind === "environment-coverage";
/** Views that group a capture's records, each under the budget its caller created. */
const projectGroupingView = (
parent: AnalysisViewParent,
view: GroupingViewRequest,
accumulators: AnalysisViewAccumulators,
) => {
if (view.kind === "api-surface")
return projectWebNetworkApiSurfaceView(
parent,
view,
accumulators.apiSurface,
);
if (view.kind === "environment-manifest")
return projectEnvironmentManifestView(parent, view, accumulators.manifest);
if (view.kind === "environment-coverage")
return projectEnvironmentCoverageView(parent, view, accumulators.state);
return projectEnvironmentStateView(parent, view, accumulators.state);
};
/** Project one selected view from authenticated parent analysis Evidence. */
export const projectAnalysisView = (
parent: AnalysisViewParent,
view: AnalysisViewRequest,
accumulators: AnalysisViewAccumulators = {},
): Result<AnalysisViewResult, AnalysisError> => {
const digest = parentDigest(parent.evidenceId);
if (!digestSchema.safeParse(digest).success)
return err(
analysisViewInputError([
{
path: ["source"],
reason: "invalid_format",
message: "Parent Evidence ID is not a digest-backed identifier.",
},
]),
);
if (view.kind === "javascript-routes") {
const projected = projectJavaScriptRoutesView(parent, view);
return sealProjected(projected);
}
if (view.kind === "web-bundle") {
const projected = projectWebBundleView(parent, view);
return sealProjected(projected);
}
if (isGroupingView(view)) {
const grouped = projectGroupingView(parent, view, accumulators);
return sealProjected(grouped);
}
if (parent.operation === "inspect_web_network_capture") {
const projected = projectWebNetworkCaptureView(parent, view);
return sealProjected(projected);
}
if (parent.operation === "inspect_pcap_capture") {
const projected = projectPcapCaptureView(parent, view);
return sealProjected(projected);
}
if (parent.operation === "inspect_byte_entropy") {
const report = parseAnalysisViewResult(byteEntropySchema, parent);
if (!report.ok) return report;
const projected = projectByteEntropyView(parent, report.value, view);
return sealProjected(projected);
}
if (parent.operation === "inspect_binary_layout") {
const layout = parseAnalysisViewResult(
{ safeParse: safeParseOwnedBinaryLayout },
parent,
);
if (!layout.ok) return layout;
const projected = projectBinaryLayoutView(parent, layout.value, view);
return sealProjected(projected);
}
if (parent.operation === "analyze_javascript_application") {
const analysis = parseJavaScriptParent(parent.normalizedResult);
if (!analysis.ok) return analysis;
const projected = projectJavaScriptApplicationView(
parent,
analysis.value,
view,
);
return sealProjected(projected);
}
if (parent.operation === "analyze_function") {
const native = parseAnalysisViewResult(functionDossierSchema, parent);
if (!native.ok) return native;
const projected = projectNativeFunctionView(parent, native.value, view);
return sealProjected(projected);
}
const project = retainedViewProjectors.get(parent.operation);
if (project !== undefined) {
const projected = project(parent, view);
return sealProjected(projected);
}
return err(unsupportedParent(parent));
};