rea-agents 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -18
- package/bridge/android/ReaJadxBridge.java +14 -5
- package/bridge/ghidra/ReaGhidraBridge.java +205 -51
- package/bridge/hopper_bridge.py +314 -127
- package/bridge/mitmproxy/capture.py +0 -2
- package/bridge/native/rea_lldb_tracer.py +630 -94
- package/bridge/process/ProcessRunTokenReader.swift +39 -5
- package/bridge/pwntools/recorded_crash_impl.py +4 -0
- package/dist/android/JadxConfiguration.js +274 -31
- package/dist/android/JadxMcpTransport.js +18 -2
- package/dist/android/JadxProtocol.js +6 -0
- package/dist/android/JadxProvider.js +76 -37
- package/dist/android/JadxSession.js +23 -4
- package/dist/application/AnalysisContextQueries.js +8 -35
- package/dist/application/AnalysisDocument.js +32 -0
- package/dist/application/AppBundleExecutable.js +67 -21
- package/dist/application/BinaryTargetResolver.js +5 -3
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +2 -18
- package/dist/application/CallPathTracing.js +19 -3
- package/dist/application/CapabilityInventory.js +48 -11
- package/dist/application/ClientConfigurationDocument.js +917 -8
- package/dist/application/ClientRegistrationIdentity.js +26 -5
- package/dist/application/ClientRegistrationStatus.js +29 -14
- package/dist/application/DirectAnalysis.js +56 -51
- package/dist/application/DirectAnalysisCleanup.js +72 -0
- package/dist/application/DirectAnalysisStatus.js +4 -5
- package/dist/application/Doctor.js +19 -21
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/DoctorScope.js +25 -13
- package/dist/application/EnhancedLiteralTracing.js +22 -25
- package/dist/application/EnhancedTools.js +64 -17
- package/dist/application/EvidenceBundleFiles.js +30 -13
- package/dist/application/FunctionAnalysisEvidence.js +2 -3
- package/dist/application/InventoryProjectionEvidence.js +4 -3
- package/dist/application/InvestigationProviders.js +11 -2
- package/dist/application/JsonFiles.js +83 -28
- package/dist/application/LinuxHopper.js +9 -6
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/ProcedureAddressResolution.js +11 -0
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionCoverageService.js +7 -4
- package/dist/application/ReconstructionObligationCandidates.js +1 -1
- package/dist/application/ReconstructionObligationLedgerService.js +4 -3
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/Setup.js +21 -17
- package/dist/application/SetupClientConfiguration.js +10 -15
- package/dist/application/SetupHost.js +21 -29
- package/dist/application/SetupPlan.js +11 -9
- package/dist/application/SupportedClients.js +34 -1
- package/dist/application/Uninstall.js +82 -29
- package/dist/application/Update.js +18 -3
- package/dist/application/UpdateMaintenance.js +7 -5
- package/dist/application/UpdateRuntime.js +57 -36
- package/dist/application/WebModuleTraceService.js +4 -2
- package/dist/application/WebNetworkCaptureService.js +4 -2
- package/dist/application/WebRuntimeService.js +5 -3
- package/dist/application/WebScriptExportService.js +32 -6
- package/dist/application/WebSourceLocationService.js +4 -2
- package/dist/application/WorkflowEvidence.js +105 -0
- package/dist/application/XrefsAddressResolution.js +45 -0
- package/dist/application/analysisView/AnalysisViewService.js +76 -0
- package/dist/application/binary/AnalysisClientCleanup.js +30 -5
- package/dist/application/binary/AnalysisProviderEvaluation.js +22 -7
- package/dist/application/binary/AnalysisProviderRegistry.js +4 -6
- package/dist/application/binary/AnalysisSnapshotCache.js +13 -14
- package/dist/application/binary/BinarySession.js +161 -93
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +4 -4
- package/dist/application/binary/BinarySessionRecords.js +26 -4
- package/dist/application/binary/BinarySessionStatus.js +18 -7
- package/dist/application/binary/CompositeProvider.js +16 -17
- package/dist/application/binary/LazyAnalysisProvider.js +8 -5
- package/dist/application/binary/SessionProviderRouter.js +27 -135
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
- package/dist/application/evm/EvmInterfaceService.js +4 -2
- package/dist/application/homebrew.js +48 -0
- package/dist/application/investigation/EvidenceLedger.js +21 -7
- package/dist/application/investigation/InvestigationRecords.js +8 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
- package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +21 -4
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
- package/dist/application/javascript/JavaScriptApplicationService.js +27 -15
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +10 -7
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +44 -10
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +49 -19
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +56 -8
- package/dist/application/javascript/JavaScriptModuleRelationships.js +38 -9
- package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +6 -4
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +64 -19
- package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
- package/dist/application/managed/ManagedMemberComparisonService.js +9 -5
- package/dist/application/managed/ManagedNativeVerificationService.js +6 -4
- package/dist/application/managed/ManagedReconstructionService.js +4 -3
- package/dist/application/process/ProcessCli.js +25 -17
- package/dist/application/process/ProcessEvidence.js +4 -4
- package/dist/application/workflowInputError.js +18 -0
- package/dist/artifacts/ArtifactProvider.js +48 -13
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +106 -15
- package/dist/artifacts/NativeDmgArtifactReader.js +73 -21
- package/dist/artifacts/SafeOutputTree.js +16 -2
- package/dist/artifacts/ZipArtifactReader.js +11 -4
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +26 -5
- package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +55 -23
- package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
- package/dist/artifacts/apple/NibArchive.js +81 -14
- package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
- package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
- package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +79 -68
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +59 -38
- package/dist/artifacts/inventory/scanReader.js +5 -9
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +2 -3
- package/dist/browser/CdpCaptureCompleteness.js +2 -0
- package/dist/browser/CdpCaptureEventHandlers.js +78 -15
- package/dist/browser/CdpCaptureEventTypes.js +5 -1
- package/dist/browser/CdpCaptureEvents.js +25 -1
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpConnection.js +30 -11
- package/dist/browser/CdpElectronProvider.js +0 -2
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +2 -3
- package/dist/browser/CdpOptionalCommand.js +2 -3
- package/dist/browser/CdpPageCapture.js +23 -1
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
- package/dist/browser/PlaywrightElectronActiveActions.js +34 -79
- package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +133 -130
- package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
- package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +39 -22
- package/dist/browser/WebSourceMapFetcher.js +426 -72
- package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
- package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
- package/dist/browser/history/CaptureFailures.js +41 -1
- package/dist/browser/history/CaptureRelease.js +5 -0
- package/dist/browser/history/HarCaptureAdapter.js +3 -3
- package/dist/browser/history/HarJson.js +3 -2
- package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
- package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
- package/dist/catalogIdentity.js +0 -1
- package/dist/cli/analysisSelector.js +23 -0
- package/dist/cli/analysisViewCommands.js +36 -0
- package/dist/cli/applicationCommands.js +2 -3
- package/dist/cli/artifactCommands.js +11 -12
- package/dist/cli/coreAnalysisCommands.js +3 -3
- package/dist/cli/coreBinaryCommands.js +100 -37
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +10 -9
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/javascriptApplicationAnalysis.js +7 -3
- package/dist/cli/jsonOutput.js +4 -99
- package/dist/cli/managedCommands.js +7 -8
- package/dist/cli/nativeCallCommands.js +3 -5
- package/dist/cli/omittableDefaults.js +50 -0
- package/dist/cli/processCommands.js +3 -2
- package/dist/cli/setupCommands.js +16 -15
- package/dist/cli/utilityCommands.js +9 -9
- package/dist/cli/webRuntimeCommands.js +8 -8
- package/dist/cli.js +18 -9
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -1
- package/dist/cliJsonInput.js +24 -5
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -13
- package/dist/composition/electronScenario.js +1 -1
- package/dist/composition/optionalObservationProviders.js +12 -7
- package/dist/config/environment.js +10 -0
- package/dist/config/ghidraStartupTimeout.js +12 -0
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpResponseBudget.js +30 -0
- package/dist/config/parseConfig.js +8 -3
- package/dist/config/parsers.js +19 -22
- package/dist/contracts/analysisViewToolContracts.js +56 -0
- package/dist/contracts/applicationToolContracts.js +5 -4
- package/dist/contracts/artifactComparisonExample.js +2 -2
- package/dist/contracts/artifactToolContracts.js +1 -1
- package/dist/contracts/browserScenarioToolContracts.js +1 -1
- package/dist/contracts/browserToolContracts.js +19 -15
- package/dist/contracts/enhancedInputs.js +7 -5
- package/dist/contracts/enhancedToolContracts.js +7 -6
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/hopperMemoryContracts.js +2 -5
- package/dist/contracts/inputSchemaPresentation.js +90 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +2 -2
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +7 -14
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
- package/dist/contracts/native/nativeToolContracts.js +5 -3
- package/dist/contracts/officialToolContracts.js +16 -16
- package/dist/contracts/promptContracts.js +5 -5
- package/dist/contracts/providerSelection.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +3 -7
- package/dist/contracts/sessionStatusContract.js +2 -4
- package/dist/contracts/sessionToolContracts.js +18 -8
- package/dist/contracts/sessionToolSchemas.js +3 -19
- package/dist/contracts/toolContractExamples.js +0 -1
- package/dist/contracts/toolContractHelpers.js +4 -1
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -1
- package/dist/contracts/toolOutputSchemaGroups.js +160 -115
- package/dist/contracts/toolOutputSchemaPrimitives.js +28 -20
- package/dist/contracts/toolSchemaMetadata.js +41 -33
- package/dist/contracts/webNetworkCaptureToolContracts.js +2 -2
- package/dist/contracts/webRuntimeToolContracts.js +1 -1
- package/dist/contracts/webScriptToolContracts.js +1 -1
- package/dist/doctorRuntime.js +7 -5
- package/dist/domain/analysisErrorBase.js +8 -3
- package/dist/domain/analysisErrorCore.js +6 -1
- package/dist/domain/analysisErrorPresentation.js +90 -20
- package/dist/domain/analysisErrorProjection.js +130 -32
- package/dist/domain/analysisSnapshot.js +29 -31
- package/dist/domain/analysisView/analysisView.js +243 -0
- package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
- package/dist/domain/analysisView/binaryLayoutView.js +159 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
- package/dist/domain/android/androidAnalysis.js +2 -4
- package/dist/domain/android/androidApplication.js +18 -10
- package/dist/domain/apple/appleApplication.js +42 -15
- package/dist/domain/apple/dyldEnvironment.js +73 -0
- package/dist/domain/apple/dylibResolution.js +130 -12
- package/dist/domain/apple/dylibResolutionFindings.js +9 -7
- package/dist/domain/apple/interfaceBuilderGraph.js +25 -14
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
- package/dist/domain/apple/keyedArchive.js +35 -3
- package/dist/domain/apple/machoContainer.js +54 -0
- package/dist/domain/apple/plistNumbers.js +76 -0
- package/dist/domain/artifactComparison.js +15 -6
- package/dist/domain/artifactGraph.js +16 -3
- package/dist/domain/artifactIdentity.js +29 -0
- package/dist/domain/artifactInventoryEvidence.js +28 -40
- package/dist/domain/artifactOperationError.js +3 -3
- package/dist/domain/artifactPartialObservation.js +1 -0
- package/dist/domain/artifactPathSyntax.js +49 -0
- package/dist/domain/binaryTarget.js +39 -13
- package/dist/domain/bridgeCandidateProjection.js +71 -0
- package/dist/domain/browserCaptureComparison.js +13 -49
- package/dist/domain/browserCompleteness.js +1 -0
- package/dist/domain/browserNetworkEvidence.js +10 -4
- package/dist/domain/browserObservation.js +0 -1
- package/dist/domain/browserObservationError.js +24 -5
- package/dist/domain/browserObservationSchemas.js +14 -3
- package/dist/domain/browserScenario.js +0 -1
- package/dist/domain/browserScenarioCapture.js +1 -2
- package/dist/domain/browserScenarioDiff.js +0 -2
- package/dist/domain/browserScenarioDiffEvidence.js +0 -12
- package/dist/domain/browserScenarioDiffValues.js +2 -2
- package/dist/domain/browserScenarioValues.js +5 -10
- package/dist/domain/bundleComparison.js +3 -2
- package/dist/domain/callPath.js +8 -9
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/canonicalJsonDigestSteps.js +133 -0
- package/dist/domain/canonicalOrdering.js +9 -5
- package/dist/domain/changedBehavior.js +9 -9
- package/dist/domain/comparisonSourceEvidence.js +40 -0
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +13 -1
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/evidence.js +65 -36
- package/dist/domain/evidenceBundle.js +47 -8
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/evidenceErrors.js +12 -1
- package/dist/domain/explicitSensitiveFailure.js +17 -1
- package/dist/domain/firmware/firmwareAnalysis.js +6 -7
- package/dist/domain/functionComparison.js +4 -5
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +23 -34
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +2 -37
- package/dist/domain/hopperErrors.js +23 -2
- package/dist/domain/hopperValues.js +51 -8
- package/dist/domain/immutableJson.js +114 -0
- package/dist/domain/inputIssueProjection.js +3 -0
- package/dist/domain/javascript/electronActiveObservation.js +47 -64
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +39 -3
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
- package/dist/domain/javascript/javascriptAstValues.js +20 -0
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
- package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
- package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
- package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
- package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascript/javascriptRecovery.js +3 -8
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +106 -5
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +23 -6
- package/dist/domain/javascript/javascriptSemanticGraph.js +98 -43
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +18 -21
- package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
- package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +126 -61
- package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
- package/dist/domain/javascript/javascriptSourceParser.js +6 -2
- package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +16 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -17
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
- package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
- package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
- package/dist/domain/jsonSerialization.js +109 -0
- package/dist/domain/jsonValue.js +90 -6
- package/dist/domain/localPath.js +6 -0
- package/dist/domain/managed/managedApplicationGraph.js +10 -10
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedInspectionEvidence.js +16 -0
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
- package/dist/domain/managed/managedNativeVerification.js +3 -11
- package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
- package/dist/domain/native/binaryLayout.js +2 -3
- package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
- package/dist/domain/native/nativeApiBoundary.js +1 -1
- package/dist/domain/native/nativeCallObservation.js +37 -13
- package/dist/domain/native/nativeCallPartialObservation.js +33 -0
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +21 -16
- package/dist/domain/process/processCaptureCoverage.js +67 -0
- package/dist/domain/process/processCaptureExample.js +2 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +81 -13
- package/dist/domain/process/processComparison.js +79 -26
- package/dist/domain/process/processObservation.js +10 -2
- package/dist/domain/process/processScenario.js +35 -12
- package/dist/domain/process/processTraceComparison.js +0 -2
- package/dist/domain/process/processTraceDimensionProjection.js +1 -1
- package/dist/domain/process/processTraceEvaluation.js +15 -11
- package/dist/domain/process/processTraceSpecification.js +3 -4
- package/dist/domain/propertyListKeys.js +1 -1
- package/dist/domain/propertyListXmlText.js +19 -0
- package/dist/domain/providerAdapterError.js +3 -1
- package/dist/domain/providerOperationHealth.js +54 -0
- package/dist/domain/reconstructionCoverage.js +5 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionVerification.js +9 -46
- package/dist/domain/reconstructionVerificationSchemas.js +4 -3
- package/dist/domain/referenceSourceGraph.js +20 -21
- package/dist/domain/staticRuntimeCorrelation.js +8 -45
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +61 -0
- package/dist/domain/symbolAnalysis.js +66 -18
- package/dist/domain/webBundleAnalysis.js +20 -8
- package/dist/domain/webBundleAnalyzerInspection.js +13 -8
- package/dist/domain/webBundleAnalyzerResult.js +41 -2
- package/dist/domain/webCaptureDiff.js +0 -1
- package/dist/domain/webCaptureDiffSchemas.js +6 -3
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webRuntime.js +19 -7
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/domain/webSourceLocation.js +1 -0
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberRows.js +75 -62
- package/dist/dotnet/ManagedMetadataInventory.js +16 -22
- package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
- package/dist/dotnet/ManagedReaderFailure.js +16 -0
- package/dist/dotnet/ManagedStaticProvider.js +3 -5
- package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
- package/dist/evaluation/AgentEvaluationReport.js +28 -0
- package/dist/evaluation/CodexAgentEval.js +12 -8
- package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
- package/dist/evm/EvmoleInterfaceProvider.js +2 -1
- package/dist/firmware/FirmwareCommand.js +9 -5
- package/dist/firmware/FirmwareFiles.js +1 -1
- package/dist/firmware/FirmwareProvider.js +4 -4
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +7 -5
- package/dist/ghidra/GhidraClient.js +126 -34
- package/dist/ghidra/GhidraClientStartup.js +0 -2
- package/dist/ghidra/GhidraDiagnostics.js +7 -7
- package/dist/ghidra/GhidraDoctor.js +6 -5
- package/dist/ghidra/GhidraFunctionValues.js +13 -12
- package/dist/ghidra/GhidraInstallation.js +58 -33
- package/dist/ghidra/GhidraInventoryValues.js +14 -4
- package/dist/ghidra/GhidraJavaLaunch.js +66 -0
- package/dist/ghidra/GhidraLauncher.js +47 -22
- package/dist/ghidra/GhidraProvider.js +6 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +20 -2
- package/dist/ghidra/GhidraProviderClient.js +36 -15
- package/dist/ghidra/GhidraSessionError.js +13 -7
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
- package/dist/ghidra/GhidraTransport.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
- package/dist/hopper/BridgeLauncher.js +65 -56
- package/dist/hopper/HopperAnalysisProfile.js +65 -12
- package/dist/hopper/HopperCleanup.js +63 -22
- package/dist/hopper/HopperClient.js +288 -59
- package/dist/hopper/HopperFileOffset.js +237 -0
- package/dist/hopper/HopperMachOImage.js +197 -0
- package/dist/hopper/HopperOperationStage.js +6 -0
- package/dist/hopper/HopperProvider.js +71 -19
- package/dist/hopper/HopperProviderCapabilities.js +19 -1
- package/dist/hopper/HopperRegexSearch.js +134 -0
- package/dist/hopper/HopperRegexWorker.js +27 -0
- package/dist/hopper/HopperRequestQueue.js +68 -19
- package/dist/hopper/HopperTargetLease.js +133 -49
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
- package/dist/ida/IdaConfiguration.js +8 -3
- package/dist/ida/IdaInput.js +1 -7
- package/dist/ida/IdaMcpConnection.js +8 -4
- package/dist/ida/IdaOperationRunner.js +3 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +20 -18
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
- package/dist/inspector/V8InspectorCaptureProjection.js +9 -4
- package/dist/inspector/V8InspectorProvider.js +82 -36
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
- package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
- package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
- package/dist/main/shutdown.js +11 -3
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +22 -2
- package/dist/main.js +11 -18
- package/dist/mcpDoctor.js +62 -2
- package/dist/native/AppleDispatchCoverage.js +47 -6
- package/dist/native/AppleDispatchDecodeFacts.js +6 -0
- package/dist/native/AppleDispatchMetadata.js +6 -3
- package/dist/native/AppleMachoFixups.js +48 -24
- package/dist/native/AppleMachoSelection.js +48 -22
- package/dist/native/AppleObjcCategories.js +6 -2
- package/dist/native/AppleObjcDispatchFacets.js +5 -2
- package/dist/native/AppleObjcProperties.js +2 -1
- package/dist/native/AppleSwiftDispatchFacets.js +27 -21
- package/dist/native/AppleSwiftVtables.js +21 -15
- package/dist/native/CommandRunner.js +87 -88
- package/dist/native/LldbCallTracer.js +372 -103
- package/dist/native/LldbRetainedObservations.js +178 -0
- package/dist/native/NativeCallObservation.js +62 -3
- package/dist/native/NativeMacOSProvider.js +122 -31
- package/dist/native/NativeUiHelperRuntime.js +11 -2
- package/dist/native/NativeUiObservation.js +2 -2
- package/dist/native/SignatureTargetBinding.js +155 -0
- package/dist/native/parsers/lipo.js +71 -1
- package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
- package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
- package/dist/process/DarwinProcessRunTokenReader.js +23 -10
- package/dist/process/ExecFileOutput.js +108 -6
- package/dist/process/OwnedCommand.js +7 -2
- package/dist/process/PrivateRuntimeRoot.js +10 -5
- package/dist/process/ProcessOwnership.js +204 -57
- package/dist/process/ProcessOwnershipObservation.js +60 -9
- package/dist/process/ProviderProcess.js +39 -10
- package/dist/process/capture/FilesystemSnapshot.js +50 -13
- package/dist/process/capture/ProcessCaptureError.js +15 -2
- package/dist/process/capture/ProcessCaptureLifecycle.js +235 -81
- package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
- package/dist/process/capture/ProcessHarness.js +21 -25
- package/dist/process/capture/ProcessNormalization.js +20 -2
- package/dist/process/capture/ProcessSampling.js +25 -2
- package/dist/process/capture/TerminalRenderer.js +14 -0
- package/dist/process/snapshotEnvironment.js +14 -0
- package/dist/server/EvidenceMcpServer.js +157 -0
- package/dist/server/createServer.js +61 -41
- package/dist/server/mcpClientMetadata.js +12 -5
- package/dist/server/promptCompletion.js +3 -8
- package/dist/server/registerAnalysisViewTool.js +15 -0
- package/dist/server/registerAndroidTools.js +2 -5
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +4 -5
- package/dist/server/registerApplicationTools/coverage.js +1 -2
- package/dist/server/registerApplicationTools/helpers.js +1 -4
- package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
- package/dist/server/registerApplicationTools/traceFeature.js +4 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +13 -10
- package/dist/server/registerBinaryDiagnosticsTools.js +2 -5
- package/dist/server/registerBrowserScenarioTool.js +3 -6
- package/dist/server/registerBrowserTools.js +13 -18
- package/dist/server/registerBundleComparisonTool.js +5 -7
- package/dist/server/registerCloseLifecycleTool.js +9 -20
- package/dist/server/registerElectronTools.js +10 -15
- package/dist/server/registerEnhancedTools.js +36 -77
- package/dist/server/registerEvidenceTools.js +3 -6
- package/dist/server/registerEvmTools.js +2 -5
- package/dist/server/registerFirmwareTools.js +2 -5
- package/dist/server/registerFunctionComparisonTool.js +15 -12
- package/dist/server/registerInvestigationTools.js +16 -17
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -5
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -8
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -8
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -7
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -9
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -9
- package/dist/server/registerOfficialTools.js +4 -21
- package/dist/server/registerProcessComparisonTool.js +74 -48
- package/dist/server/registerRecordedCrashTools.js +2 -5
- package/dist/server/registerSessionRecordTools.js +19 -24
- package/dist/server/registerSessionStatusTool.js +19 -6
- package/dist/server/registerSessionTools.js +20 -18
- package/dist/server/registerWebModuleTool.js +2 -5
- package/dist/server/registerWebNetworkCaptureTool.js +2 -5
- package/dist/server/registerWebRuntimeTools.js +4 -9
- package/dist/server/registerWebScriptTool.js +2 -5
- package/dist/server/registerWebSourceLocationTool.js +2 -5
- package/dist/server/runDerivedOperation.js +15 -3
- package/dist/server/sessionAvailabilityPolicy.js +0 -1
- package/dist/server/toolRegistrationOptions.js +2 -2
- package/dist/server/toolResult.js +75 -51
- package/dist/server/toolResultEncoding.js +34 -0
- package/dist/windows/WindowsNativeLoader.js +1 -0
- package/dist/windows/WindowsOwnedProcess.js +60 -15
- package/dist/windows/WindowsPrivateRuntime.js +7 -8
- package/install.sh +1 -1
- package/native/windows/README.md +3 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +44 -30
- package/scripts/electron-active-hook-boundaries.cjs +18 -20
- package/scripts/electron-active-hook.cjs +241 -37
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +12 -3
- package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +20 -3
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/config.js +0 -1
- package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
- package/dist/contracts/process/processCaptureExample.js +0 -2
- package/dist/contracts/toolOutputSchemas.js +0 -2
- package/dist/ghidra/GhidraDefaults.js +0 -2
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
|
|
1
2
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
2
3
|
import { inspectBundleKeyedArchive } from "./apple/KeyedArchiveReader.js";
|
|
3
4
|
import { traceDylibResolution } from "./apple/DylibResolutionReader.js";
|
|
@@ -7,7 +8,7 @@ import { extractArtifact } from "./extraction/ArtifactExtraction.js";
|
|
|
7
8
|
import { analyzeInterfaceBuilderBundle } from "./apple/InterfaceBuilderAnalysis.js";
|
|
8
9
|
import { analyzeAppleAssetCatalogs } from "./apple/AppleAssetCatalogAnalysis.js";
|
|
9
10
|
import { ARTIFACT_ANALYSIS_OPERATIONS, artifactInventoryInputSchema, artifactExtractionExecutionSchema, } from "../contracts/artifactToolContracts.js";
|
|
10
|
-
import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
|
|
11
|
+
import { AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisUnsupportedTargetError, } from "../domain/analysisErrorCore.js";
|
|
11
12
|
import { ArtifactOperationError } from "../domain/artifactOperationError.js";
|
|
12
13
|
import {} from "../domain/analysisErrorBase.js";
|
|
13
14
|
import { interfaceBuilderLimitsSchema } from "../domain/apple/interfaceBuilderGraph.js";
|
|
@@ -20,8 +21,12 @@ import { resolveArtifactIntegrityPolicy } from "./inventory/policy.js";
|
|
|
20
21
|
/** Read-only inventory and exclusively owned extraction provider. */
|
|
21
22
|
export class ArtifactProvider {
|
|
22
23
|
#capabilities;
|
|
23
|
-
|
|
24
|
+
#platform;
|
|
25
|
+
environment;
|
|
26
|
+
constructor(environment, platform = process.platform) {
|
|
27
|
+
this.environment = snapshotEnvironment(environment, platform);
|
|
24
28
|
this.#capabilities = artifactCapabilities(platform);
|
|
29
|
+
this.#platform = platform;
|
|
25
30
|
}
|
|
26
31
|
identity() {
|
|
27
32
|
return IDENTITY;
|
|
@@ -30,13 +35,17 @@ export class ArtifactProvider {
|
|
|
30
35
|
return this.#capabilities;
|
|
31
36
|
}
|
|
32
37
|
createClient(target) {
|
|
33
|
-
return new ArtifactClient(target);
|
|
38
|
+
return new ArtifactClient(target, this.environment, this.#platform);
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
41
|
class ArtifactClient {
|
|
37
42
|
target;
|
|
38
|
-
|
|
43
|
+
environment;
|
|
44
|
+
platform;
|
|
45
|
+
constructor(target, environment, platform) {
|
|
39
46
|
this.target = target;
|
|
47
|
+
this.environment = environment;
|
|
48
|
+
this.platform = platform;
|
|
40
49
|
}
|
|
41
50
|
async execute(operation, parameters, options) {
|
|
42
51
|
if (operation === "health")
|
|
@@ -52,7 +61,7 @@ class ArtifactClient {
|
|
|
52
61
|
if (this.target.kind !== "executable" ||
|
|
53
62
|
this.target.sourcePath === undefined ||
|
|
54
63
|
!this.target.sourcePath.toLowerCase().endsWith(".app"))
|
|
55
|
-
throw
|
|
64
|
+
throw this.unsupportedTarget(operation, "decode_interface_builder requires an active .app bundle target");
|
|
56
65
|
const limits = interfaceBuilderLimitsSchema.parse(parameters);
|
|
57
66
|
const result = await analyzeInterfaceBuilderBundle({
|
|
58
67
|
bundlePath: this.target.sourcePath,
|
|
@@ -74,19 +83,27 @@ class ArtifactClient {
|
|
|
74
83
|
parameters.path !== undefined &&
|
|
75
84
|
parameters.path !== "." &&
|
|
76
85
|
parameters.path !== basename(this.target.path))
|
|
77
|
-
throw new
|
|
86
|
+
throw new AnalysisInputError(operation, undefined, [
|
|
87
|
+
{
|
|
88
|
+
path: ["path"],
|
|
89
|
+
reason: "invalid_value",
|
|
90
|
+
message: "For an active plist, path must select that archive (omit path or use its basename).",
|
|
91
|
+
expected: basename(this.target.path),
|
|
92
|
+
},
|
|
93
|
+
]);
|
|
78
94
|
const bundlePath = standalone
|
|
79
95
|
? dirname(this.target.path)
|
|
80
96
|
: this.target.sourcePath;
|
|
81
97
|
if (bundlePath === undefined ||
|
|
82
98
|
(!standalone && !bundlePath.toLowerCase().endsWith(".app")))
|
|
83
|
-
throw
|
|
99
|
+
throw this.unsupportedTarget(operation, "inspect_keyed_archive requires an active plist or .app bundle");
|
|
84
100
|
const result = await inspectBundleKeyedArchive({
|
|
85
101
|
bundlePath,
|
|
86
102
|
targetSha256: this.target.sha256,
|
|
87
103
|
parameters: standalone
|
|
88
104
|
? { ...parameters, path: basename(this.target.path) }
|
|
89
105
|
: parameters,
|
|
106
|
+
platform: this.platform,
|
|
90
107
|
...(options?.signal === undefined ? {} : { signal: options.signal }),
|
|
91
108
|
});
|
|
92
109
|
if (standalone && result.archive_sha256 !== this.target.sha256)
|
|
@@ -107,6 +124,7 @@ class ArtifactClient {
|
|
|
107
124
|
inputPath: this.target.sourcePath ?? this.target.path,
|
|
108
125
|
inputFormat: this.target.format,
|
|
109
126
|
outputRoot: parsed.output_root,
|
|
127
|
+
environment: this.environment,
|
|
110
128
|
}, options?.signal);
|
|
111
129
|
return ok(createAnalysisExecution(result, IDENTITY, {
|
|
112
130
|
rawResult: null,
|
|
@@ -131,19 +149,24 @@ class ArtifactClient {
|
|
|
131
149
|
}));
|
|
132
150
|
}
|
|
133
151
|
catch (cause) {
|
|
134
|
-
return err(
|
|
152
|
+
return err(translateArtifactFailure(operation, cause));
|
|
135
153
|
}
|
|
136
154
|
}
|
|
137
155
|
close() {
|
|
138
|
-
return Promise.resolve();
|
|
156
|
+
return Promise.resolve(ok(null));
|
|
157
|
+
}
|
|
158
|
+
/** The active target's kind is outside this operation's supported targets. */
|
|
159
|
+
unsupportedTarget(operation, reason) {
|
|
160
|
+
return new AnalysisUnsupportedTargetError(operation, this.target.sourcePath ?? this.target.path, reason);
|
|
139
161
|
}
|
|
140
162
|
async inspectAssetCatalog(parameters, options) {
|
|
141
163
|
const bundlePath = this.target.sourcePath;
|
|
142
164
|
if (this.target.kind !== "executable" ||
|
|
143
165
|
bundlePath === undefined ||
|
|
144
166
|
!bundlePath.toLowerCase().endsWith(".app"))
|
|
145
|
-
throw
|
|
167
|
+
throw this.unsupportedTarget("inspect_asset_catalog", "inspect_asset_catalog requires an active .app bundle target");
|
|
146
168
|
const result = await analyzeAppleAssetCatalogs({
|
|
169
|
+
environment: this.environment,
|
|
147
170
|
bundlePath,
|
|
148
171
|
targetSha256: this.target.sha256,
|
|
149
172
|
page: parameters,
|
|
@@ -159,7 +182,7 @@ class ArtifactClient {
|
|
|
159
182
|
}
|
|
160
183
|
async traceDylibResolution(parameters, options) {
|
|
161
184
|
if (this.target.kind !== "executable" || this.target.format !== "mach-o")
|
|
162
|
-
throw
|
|
185
|
+
throw this.unsupportedTarget("trace_dylib_resolution", "trace_dylib_resolution requires an active Mach-O or .app bundle target");
|
|
163
186
|
// Only a target opened from an app bundle directory carries its Info.plist;
|
|
164
187
|
// a regular file whose name ends in .app is a standalone image.
|
|
165
188
|
const bundle = this.target.bundleInfoPlist === undefined
|
|
@@ -222,6 +245,7 @@ class ArtifactClient {
|
|
|
222
245
|
}
|
|
223
246
|
inventory(parsed, options) {
|
|
224
247
|
return inventoryArtifact(this.target.sourcePath ?? this.target.path, {
|
|
248
|
+
environment: this.environment,
|
|
225
249
|
...(options?.signal === undefined ? {} : { signal: options.signal }),
|
|
226
250
|
integrity: resolveArtifactIntegrityPolicy({
|
|
227
251
|
mode: parsed.integrity_policy,
|
|
@@ -230,9 +254,20 @@ class ArtifactClient {
|
|
|
230
254
|
}
|
|
231
255
|
}
|
|
232
256
|
const isArtifactOperation = (operation) => ARTIFACT_ANALYSIS_OPERATIONS.includes(operation);
|
|
233
|
-
|
|
257
|
+
/** Translate one artifact boundary failure while retaining cleanup evidence. */
|
|
258
|
+
export const translateArtifactFailure = (operation, cause) => {
|
|
234
259
|
if (cause instanceof ArtifactReaderFailure)
|
|
235
|
-
return new ArtifactOperationError(operation, cause.reason, cause.details, cause.message
|
|
260
|
+
return new ArtifactOperationError(operation, cause.reason, cause.details, cause.message, {
|
|
261
|
+
...(cause.cleanup === undefined ? {} : { cleanup: cause.cleanup }),
|
|
262
|
+
...(cause.partialObservation === undefined
|
|
263
|
+
? {}
|
|
264
|
+
: { partialObservation: cause.partialObservation }),
|
|
265
|
+
});
|
|
266
|
+
// Caller-selection and unsupported-target failures are already typed; keep
|
|
267
|
+
// their correction details instead of reducing them to an I/O failure.
|
|
268
|
+
if (cause instanceof AnalysisInputError ||
|
|
269
|
+
cause instanceof AnalysisUnsupportedTargetError)
|
|
270
|
+
return cause;
|
|
236
271
|
return new ArtifactOperationError(operation, "io");
|
|
237
272
|
};
|
|
238
273
|
const subjectFor = (path, manifest) => ({
|
|
@@ -2,10 +2,41 @@
|
|
|
2
2
|
export class ArtifactReaderFailure extends Error {
|
|
3
3
|
reason;
|
|
4
4
|
details;
|
|
5
|
+
cleanup;
|
|
6
|
+
partialObservation;
|
|
5
7
|
constructor(reason, message, options, details) {
|
|
6
8
|
super(message, options);
|
|
7
9
|
this.reason = reason;
|
|
8
10
|
this.details = details;
|
|
9
11
|
this.name = "ArtifactReaderFailure";
|
|
12
|
+
this.cleanup = options?.cleanup;
|
|
13
|
+
this.partialObservation = options?.partialObservation;
|
|
14
|
+
}
|
|
15
|
+
/** Preserve the primary failure while attaching cleanup and any complete observation. */
|
|
16
|
+
static withCleanup(cause, cleanup, partialObservation) {
|
|
17
|
+
const primary = cause instanceof ArtifactReaderFailure
|
|
18
|
+
? cause
|
|
19
|
+
: new ArtifactReaderFailure("io", errorMessage(cause), { cause });
|
|
20
|
+
const mergedObservation = partialObservation ?? primary.partialObservation;
|
|
21
|
+
return new ArtifactReaderFailure(primary.reason, primary.message, {
|
|
22
|
+
cause: primary,
|
|
23
|
+
cleanup: combineCleanup(primary.cleanup, cleanup),
|
|
24
|
+
...(mergedObservation === undefined
|
|
25
|
+
? {}
|
|
26
|
+
: { partialObservation: mergedObservation }),
|
|
27
|
+
}, primary.details);
|
|
28
|
+
}
|
|
29
|
+
/** Give otherwise opaque cleanup failures a concrete owned resource. */
|
|
30
|
+
static cleanupObservation(cause, resource) {
|
|
31
|
+
if (cause instanceof ArtifactReaderFailure && cause.cleanup !== undefined)
|
|
32
|
+
return cause.cleanup;
|
|
33
|
+
return { reason: errorMessage(cause), resources: [resource] };
|
|
10
34
|
}
|
|
11
35
|
}
|
|
36
|
+
const combineCleanup = (primary, cleanup) => primary === undefined || primary === cleanup
|
|
37
|
+
? cleanup
|
|
38
|
+
: {
|
|
39
|
+
reason: `${primary.reason}; ${cleanup.reason}`,
|
|
40
|
+
resources: [...new Set([...primary.resources, ...cleanup.resources])],
|
|
41
|
+
};
|
|
42
|
+
const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { constants } from "node:fs";
|
|
2
2
|
import { lstat, open, opendir, realpath } from "node:fs/promises";
|
|
3
3
|
import { isAbsolute, join, relative, sep } from "node:path";
|
|
4
|
+
import { compareCodePoints } from "../domain/canonicalOrdering.js";
|
|
4
5
|
import { ArtifactReaderFailure, } from "./ArtifactReader.js";
|
|
5
6
|
/** Deterministic, non-symlink-following directory reader. */
|
|
6
7
|
export class DirectoryArtifactReader {
|
|
@@ -38,7 +39,7 @@ export class DirectoryArtifactReader {
|
|
|
38
39
|
await handle.close().catch(() => undefined);
|
|
39
40
|
}
|
|
40
41
|
await withDirectoryIoContext("inspect directory", directory, () => assertContainedDirectory(root, directory));
|
|
41
|
-
children.sort(
|
|
42
|
+
children.sort(compareCodePoints);
|
|
42
43
|
const directories = [];
|
|
43
44
|
for (const name of children) {
|
|
44
45
|
abortIfNeeded(signal);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createReadStream } from "node:fs";
|
|
2
|
-
import { stat } from "node:fs/promises";
|
|
2
|
+
import { open as openFile, stat } from "node:fs/promises";
|
|
3
3
|
import { Readable } from "node:stream";
|
|
4
4
|
import { XcrunCommandRunner, } from "../native/CommandRunner.js";
|
|
5
|
-
import { parseLipoArchitectures } from "../native/parsers/lipo.js";
|
|
5
|
+
import { parseLipoArchitectures, } from "../native/parsers/lipo.js";
|
|
6
|
+
import { readMachoImage } from "./apple/MachoLoadCommandReader.js";
|
|
6
7
|
import { ArtifactReaderFailure, } from "./ArtifactReader.js";
|
|
7
8
|
import { streamChunkToBuffer } from "./StreamBytes.js";
|
|
8
9
|
/** Read-only universal Mach-O slice reader backed by native lipo metadata. */
|
|
@@ -11,7 +12,7 @@ export class MachOSliceArtifactReader {
|
|
|
11
12
|
runner;
|
|
12
13
|
format = "file";
|
|
13
14
|
#command;
|
|
14
|
-
constructor(path, runner = new XcrunCommandRunner()) {
|
|
15
|
+
constructor(path, environment, runner = new XcrunCommandRunner(environment)) {
|
|
15
16
|
this.path = path;
|
|
16
17
|
this.runner = runner;
|
|
17
18
|
}
|
|
@@ -28,28 +29,75 @@ export class MachOSliceArtifactReader {
|
|
|
28
29
|
effects: ["read"],
|
|
29
30
|
};
|
|
30
31
|
const fileSize = (await stat(this.path)).size;
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const architectures = parseLipoArchitectures(captured.value.stdout);
|
|
33
|
+
const structural = await readStructuralSlices(this.path, fileSize);
|
|
34
|
+
if (structural.status === "malformed")
|
|
35
|
+
throw new ArtifactReaderFailure("integrity", `Mach-O structural slice index is malformed: ${structural.reason}`);
|
|
36
|
+
if (structural.status === "unsupported")
|
|
37
|
+
throw new ArtifactReaderFailure("format", `Mach-O structural slice index is unsupported: ${structural.reason}`);
|
|
38
|
+
const slices = structural.status === "parsed" ? structural.slices : null;
|
|
39
|
+
const matchingSlices = new Map();
|
|
40
|
+
if (slices !== null) {
|
|
41
|
+
if (slices.length !== architectures.length)
|
|
42
|
+
throw new ArtifactReaderFailure("integrity", "lipo architecture count disagrees with the Mach-O FAT table");
|
|
43
|
+
const unmatched = [...slices];
|
|
44
|
+
for (const reported of architectures) {
|
|
45
|
+
const match = unmatched.findIndex((observed) => lipoMatchesSlice(reported, observed, slices.length === 1));
|
|
46
|
+
if (match < 0)
|
|
47
|
+
throw new ArtifactReaderFailure("integrity", `lipo slice metadata disagrees with the Mach-O FAT table: ${reported.name} (cputype=${reported.cpu_type ?? "unknown"}, cpusubtype=${reported.cpu_subtype ?? "unknown"}, offset=${reported.file_offset ?? "unknown"}, size=${reported.size ?? "unknown"}, alignment=${reported.alignment ?? "unknown"})`);
|
|
48
|
+
const [observed] = unmatched.splice(match, 1);
|
|
49
|
+
if (observed !== undefined)
|
|
50
|
+
matchingSlices.set(reported, observed);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const architecture of architectures) {
|
|
54
|
+
const structuralSlice = matchingSlices.get(architecture);
|
|
55
|
+
const offset = architecture.file_offset ?? structuralSlice?.slice_offset;
|
|
56
|
+
const sliceSize = architecture.size ?? structuralSlice?.slice_size;
|
|
57
|
+
if (offset === undefined || sliceSize === undefined)
|
|
33
58
|
throw new ArtifactReaderFailure("integrity", "lipo omitted a universal slice byte range");
|
|
34
|
-
if (!Number.isSafeInteger(
|
|
35
|
-
!Number.isSafeInteger(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
!Number.isSafeInteger(
|
|
39
|
-
|
|
59
|
+
if (!Number.isSafeInteger(offset) ||
|
|
60
|
+
!Number.isSafeInteger(sliceSize) ||
|
|
61
|
+
offset < 0 ||
|
|
62
|
+
sliceSize <= 0 ||
|
|
63
|
+
!Number.isSafeInteger(offset + sliceSize) ||
|
|
64
|
+
offset + sliceSize > fileSize)
|
|
40
65
|
throw new ArtifactReaderFailure("integrity", `lipo reported an out-of-bounds Mach-O slice: ${architecture.name}`);
|
|
41
66
|
yield {
|
|
42
67
|
path: `slices/${architecture.name}`,
|
|
43
68
|
kind: "slice",
|
|
44
|
-
declaredSize:
|
|
69
|
+
declaredSize: sliceSize,
|
|
45
70
|
compressedSize: null,
|
|
46
71
|
executable: true,
|
|
47
72
|
encrypted: false,
|
|
48
|
-
byteOffset:
|
|
73
|
+
byteOffset: offset,
|
|
49
74
|
declaredSha256: null,
|
|
50
75
|
unpacked: false,
|
|
51
|
-
limitations: [
|
|
52
|
-
|
|
76
|
+
limitations: [
|
|
77
|
+
...(structural.status === "not-mach-o"
|
|
78
|
+
? [
|
|
79
|
+
"Structural Mach-O facts were unavailable; slice range is based on lipo output.",
|
|
80
|
+
]
|
|
81
|
+
: []),
|
|
82
|
+
...(architecture.file_offset === null || architecture.size === null
|
|
83
|
+
? [
|
|
84
|
+
"Slice range was derived from structural Mach-O facts because lipo omitted it.",
|
|
85
|
+
]
|
|
86
|
+
: []),
|
|
87
|
+
...(architecture.cpu_type !== null &&
|
|
88
|
+
architecture.cpu_type_code === null
|
|
89
|
+
? [
|
|
90
|
+
`lipo CPU type is retained as unnormalized source text: ${architecture.cpu_type}`,
|
|
91
|
+
]
|
|
92
|
+
: []),
|
|
93
|
+
...(architecture.cpu_subtype !== null &&
|
|
94
|
+
architecture.cpu_subtype_code === null
|
|
95
|
+
? [
|
|
96
|
+
`lipo CPU subtype is retained as unnormalized source text: ${architecture.cpu_subtype}${architecture.capabilities === null ? "" : `; capabilities ${architecture.capabilities}`}`,
|
|
97
|
+
]
|
|
98
|
+
: []),
|
|
99
|
+
],
|
|
100
|
+
adapterKey: `${String(offset)}:${String(sliceSize)}`,
|
|
53
101
|
};
|
|
54
102
|
}
|
|
55
103
|
}
|
|
@@ -103,6 +151,49 @@ export class MachOSliceArtifactReader {
|
|
|
103
151
|
return Promise.resolve();
|
|
104
152
|
}
|
|
105
153
|
}
|
|
154
|
+
/** Compare lipo's independent ranges with structurally parsed slice identity. */
|
|
155
|
+
const readStructuralSlices = async (path, size) => {
|
|
156
|
+
const file = await openFile(path, "r");
|
|
157
|
+
try {
|
|
158
|
+
const readAt = async (offset, length) => {
|
|
159
|
+
const bytes = Buffer.alloc(length);
|
|
160
|
+
const { bytesRead } = await file.read(bytes, 0, length, offset);
|
|
161
|
+
return bytes.subarray(0, bytesRead);
|
|
162
|
+
};
|
|
163
|
+
const facts = await readMachoImage(readAt, size);
|
|
164
|
+
return facts;
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
await file.close();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const lipoMatchesSlice = (reported, observed, structurallyUnique) => {
|
|
171
|
+
const observedCpuType = observed.fat_cpu_type ?? observed.cpu_type;
|
|
172
|
+
const observedCpuSubtype = observed.fat_cpu_subtype ?? observed.cpu_subtype;
|
|
173
|
+
const hasPhysicalIdentity = reported.file_offset !== null ||
|
|
174
|
+
reported.size !== null ||
|
|
175
|
+
reported.cpu_type_code !== null ||
|
|
176
|
+
reported.cpu_subtype_code !== null;
|
|
177
|
+
return ((hasPhysicalIdentity || structurallyUnique) &&
|
|
178
|
+
lipoNameMatches(reported.name, observed.architecture) &&
|
|
179
|
+
(reported.file_offset === null ||
|
|
180
|
+
reported.file_offset === observed.slice_offset) &&
|
|
181
|
+
(reported.size === null || reported.size === observed.slice_size) &&
|
|
182
|
+
(reported.cpu_type_code === null ||
|
|
183
|
+
reported.cpu_type_code === observedCpuType) &&
|
|
184
|
+
(reported.cpu_subtype_code === null ||
|
|
185
|
+
reported.cpu_subtype_code === observedCpuSubtype) &&
|
|
186
|
+
(reported.alignment === null ||
|
|
187
|
+
observed.fat_alignment_exponent === null ||
|
|
188
|
+
reported.alignment === 2 ** observed.fat_alignment_exponent));
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Newer lipo names an arm64e ABI variant `arm64e.<variant>` (for example
|
|
192
|
+
* `arm64e.v1` for pointer-auth ABI version 1). The FAT table names that slice
|
|
193
|
+
* `arm64e`; its physical identity is still compared field by field.
|
|
194
|
+
*/
|
|
195
|
+
const lipoNameMatches = (reported, observed) => reported === observed ||
|
|
196
|
+
(observed === "arm64e" && /^arm64e\.[A-Za-z0-9_]+$/u.test(reported));
|
|
106
197
|
const parseSliceKeyInteger = (value) => {
|
|
107
198
|
if (value === undefined || !/^\d+$/u.test(value))
|
|
108
199
|
return null;
|
|
@@ -7,6 +7,13 @@ import { ArtifactReaderFailure, } from "./ArtifactReader.js";
|
|
|
7
7
|
import { DirectoryArtifactReader } from "./DirectoryArtifactReader.js";
|
|
8
8
|
import { execFileOutput } from "../process/ExecFileOutput.js";
|
|
9
9
|
const DETACH_TIMEOUT_MS = 120_000;
|
|
10
|
+
/**
|
|
11
|
+
* Waits before rechecking devices whose detach failed. A related device's
|
|
12
|
+
* later detach can eject one, `hdiutil info` can still list an ejected device
|
|
13
|
+
* briefly, and a volume can report busy just after it was read.
|
|
14
|
+
*/
|
|
15
|
+
const DETACH_SETTLE_DELAYS_MS = [250, 500, 1000];
|
|
16
|
+
const delay = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
10
17
|
const attachOutputSchema = z.object({
|
|
11
18
|
"system-entities": z.array(z.object({
|
|
12
19
|
"dev-entry": z.string().startsWith("/dev/"),
|
|
@@ -18,10 +25,12 @@ const infoOutputSchema = z.object({
|
|
|
18
25
|
"system-entities": z.array(z.object({ "dev-entry": z.string() })),
|
|
19
26
|
})),
|
|
20
27
|
});
|
|
21
|
-
const
|
|
28
|
+
const createSystemHost = (environment) => ({
|
|
29
|
+
delay,
|
|
22
30
|
async run(arguments_, signal, options) {
|
|
23
31
|
try {
|
|
24
32
|
const { stdout, stderr } = await execFileOutput("/usr/bin/hdiutil", [...arguments_], {
|
|
33
|
+
env: environment,
|
|
25
34
|
...(options === undefined ? {} : { timeout: options.timeoutMs }),
|
|
26
35
|
...(signal === undefined ? {} : { signal }),
|
|
27
36
|
});
|
|
@@ -41,7 +50,7 @@ const systemHost = {
|
|
|
41
50
|
throw new ArtifactReaderFailure(commandFailureReason(cause, arguments_[0]), `hdiutil ${arguments_[0] ?? "operation"} failed: ${describeCommandFailure(cause, arguments_)}`, { cause });
|
|
42
51
|
}
|
|
43
52
|
},
|
|
44
|
-
};
|
|
53
|
+
});
|
|
45
54
|
/** Read-only macOS DMG adapter that owns attachment and reverse-order detach. */
|
|
46
55
|
export class NativeDmgArtifactReader {
|
|
47
56
|
path;
|
|
@@ -56,10 +65,10 @@ export class NativeDmgArtifactReader {
|
|
|
56
65
|
this.host = host;
|
|
57
66
|
}
|
|
58
67
|
/** Verify and attach one image beneath an exclusively owned temporary root. */
|
|
59
|
-
static async create(path, signal, host
|
|
60
|
-
if (process.platform !== "darwin" && host ===
|
|
68
|
+
static async create(path, environment, signal, host) {
|
|
69
|
+
if (process.platform !== "darwin" && host === undefined)
|
|
61
70
|
throw new ArtifactReaderFailure("unavailable", "Native DMG traversal is available only on macOS");
|
|
62
|
-
const reader = new NativeDmgArtifactReader(path, host);
|
|
71
|
+
const reader = new NativeDmgArtifactReader(path, host ?? createSystemHost(environment));
|
|
63
72
|
await reader.attach(signal);
|
|
64
73
|
return reader;
|
|
65
74
|
}
|
|
@@ -80,28 +89,70 @@ export class NativeDmgArtifactReader {
|
|
|
80
89
|
}
|
|
81
90
|
async close() {
|
|
82
91
|
let detachFailure;
|
|
92
|
+
let remainingDevices = [];
|
|
83
93
|
for (const device of [...this.#devices].reverse()) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.#provenance.push(command(["detach", device], ["mount"]));
|
|
94
|
+
const failure = await this.#detach(device);
|
|
95
|
+
if (failure !== undefined) {
|
|
96
|
+
remainingDevices.push(device);
|
|
97
|
+
detachFailure ??= failure;
|
|
89
98
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
}
|
|
100
|
+
// Detaching a synthesized APFS container also ejects the image that backs
|
|
101
|
+
// it, so a device whose own detach failed may be gone by the end of the
|
|
102
|
+
// pass, and hdiutil can list an ejected device or report busy briefly.
|
|
103
|
+
// Only a device that stays attached through every recheck is a failure.
|
|
104
|
+
for (const delayMs of DETACH_SETTLE_DELAYS_MS) {
|
|
105
|
+
if (remainingDevices.length === 0)
|
|
106
|
+
break;
|
|
107
|
+
await (this.host.delay ?? delay)(delayMs);
|
|
108
|
+
const stillAttached = [];
|
|
109
|
+
for (const device of remainingDevices) {
|
|
110
|
+
if (!(await this.#isAttached(device)))
|
|
111
|
+
continue;
|
|
112
|
+
const failure = await this.#detach(device);
|
|
113
|
+
if (failure !== undefined) {
|
|
114
|
+
stillAttached.push(device);
|
|
115
|
+
detachFailure = failure;
|
|
116
|
+
}
|
|
96
117
|
}
|
|
118
|
+
remainingDevices = stillAttached;
|
|
97
119
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
if (remainingDevices.length === 0)
|
|
121
|
+
detachFailure = undefined;
|
|
122
|
+
this.#devices = remainingDevices.reverse();
|
|
123
|
+
if (this.#devices.length === 0 && this.#mountRoot !== undefined)
|
|
124
|
+
await rm(this.#mountRoot, { recursive: true, force: true }).then(() => {
|
|
125
|
+
this.#mountRoot = undefined;
|
|
126
|
+
this.#directory = undefined;
|
|
127
|
+
}, (cause) => {
|
|
101
128
|
detachFailure ??= cause;
|
|
102
129
|
});
|
|
103
130
|
if (detachFailure !== undefined)
|
|
104
|
-
throw new ArtifactReaderFailure("unavailable",
|
|
131
|
+
throw new ArtifactReaderFailure("unavailable", `DMG detach or mount-root cleanup failed for ${JSON.stringify(this.path)}: ${failureMessage(detachFailure)}`, {
|
|
132
|
+
cause: detachFailure,
|
|
133
|
+
cleanup: {
|
|
134
|
+
reason: failureMessage(detachFailure),
|
|
135
|
+
resources: [
|
|
136
|
+
...this.#devices.map((device) => `DMG device ${device}`),
|
|
137
|
+
...(this.#mountRoot === undefined
|
|
138
|
+
? []
|
|
139
|
+
: [`DMG mount root ${this.#mountRoot}`]),
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/** Detach one device; return the failure only while it remains attached. */
|
|
145
|
+
async #detach(device) {
|
|
146
|
+
try {
|
|
147
|
+
await runChecked(this.host, ["detach", device], undefined, {
|
|
148
|
+
timeoutMs: DETACH_TIMEOUT_MS,
|
|
149
|
+
});
|
|
150
|
+
this.#provenance.push(command(["detach", device], ["mount"]));
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
catch (cause) {
|
|
154
|
+
return (await this.#isAttached(device)) ? cause : undefined;
|
|
155
|
+
}
|
|
105
156
|
}
|
|
106
157
|
/**
|
|
107
158
|
* Report whether hdiutil still lists a device; unknown state counts as
|
|
@@ -169,11 +220,12 @@ export class NativeDmgArtifactReader {
|
|
|
169
220
|
cleanupFailure = cleanupCause;
|
|
170
221
|
}
|
|
171
222
|
if (cleanupFailure !== undefined)
|
|
172
|
-
throw
|
|
223
|
+
throw ArtifactReaderFailure.withCleanup(cause, ArtifactReaderFailure.cleanupObservation(cleanupFailure, `DMG mount root ${this.#mountRoot ?? this.path}`));
|
|
173
224
|
throw cause;
|
|
174
225
|
}
|
|
175
226
|
}
|
|
176
227
|
}
|
|
228
|
+
const failureMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
177
229
|
const runChecked = async (host, arguments_, signal, options) => {
|
|
178
230
|
let result;
|
|
179
231
|
try {
|
|
@@ -129,7 +129,13 @@ export class SafeOutputTree {
|
|
|
129
129
|
async rollback() {
|
|
130
130
|
if (this.#published)
|
|
131
131
|
return structuredClone(this.#cleanup);
|
|
132
|
-
|
|
132
|
+
let removalFailure;
|
|
133
|
+
try {
|
|
134
|
+
await rm(this.#outputRoot, { recursive: true, force: true });
|
|
135
|
+
}
|
|
136
|
+
catch (cause) {
|
|
137
|
+
removalFailure = cause;
|
|
138
|
+
}
|
|
133
139
|
const absent = await isAbsent(this.#outputRoot);
|
|
134
140
|
this.#cleanup = absent
|
|
135
141
|
? { status: "complete", residualPaths: [] }
|
|
@@ -138,7 +144,15 @@ export class SafeOutputTree {
|
|
|
138
144
|
residualPaths: [basename(this.#outputRoot)],
|
|
139
145
|
};
|
|
140
146
|
if (!absent)
|
|
141
|
-
throw new ArtifactReaderFailure("integrity",
|
|
147
|
+
throw new ArtifactReaderFailure("integrity", `Extraction output cleanup could not be verified${removalFailure === undefined ? "" : `: ${removalFailure instanceof Error ? removalFailure.message : String(removalFailure)}`}`, {
|
|
148
|
+
cause: removalFailure,
|
|
149
|
+
cleanup: {
|
|
150
|
+
reason: removalFailure instanceof Error
|
|
151
|
+
? removalFailure.message
|
|
152
|
+
: "Extraction output root remains after rollback",
|
|
153
|
+
resources: [this.#outputRoot],
|
|
154
|
+
},
|
|
155
|
+
});
|
|
142
156
|
return structuredClone(this.#cleanup);
|
|
143
157
|
}
|
|
144
158
|
async #prepareParent(relativePath) {
|
|
@@ -5,10 +5,12 @@ import { Reader, ZipReader } from "@zip.js/zip.js";
|
|
|
5
5
|
import { ArtifactReaderFailure, } from "./ArtifactReader.js";
|
|
6
6
|
class NodeFileReader extends Reader {
|
|
7
7
|
path;
|
|
8
|
+
maximumReadBytes;
|
|
8
9
|
#handle;
|
|
9
|
-
constructor(path) {
|
|
10
|
+
constructor(path, maximumReadBytes) {
|
|
10
11
|
super(path);
|
|
11
12
|
this.path = path;
|
|
13
|
+
this.maximumReadBytes = maximumReadBytes;
|
|
12
14
|
}
|
|
13
15
|
async init() {
|
|
14
16
|
this.#handle = await open(this.path, "r");
|
|
@@ -18,7 +20,11 @@ class NodeFileReader extends Reader {
|
|
|
18
20
|
const handle = this.#handle;
|
|
19
21
|
if (handle === undefined)
|
|
20
22
|
throw new Error("ZIP reader is not initialized");
|
|
21
|
-
const
|
|
23
|
+
const readBytes = Math.min(length, this.size - index);
|
|
24
|
+
if (this.maximumReadBytes !== undefined &&
|
|
25
|
+
readBytes > this.maximumReadBytes)
|
|
26
|
+
throw new ArtifactReaderFailure("limit", `ZIP metadata read requires ${readBytes} bytes, exceeding the ${this.maximumReadBytes}-byte read budget`);
|
|
27
|
+
const bytes = Buffer.alloc(readBytes);
|
|
22
28
|
const read = await handle.read(bytes, 0, bytes.length, index);
|
|
23
29
|
return bytes.subarray(0, read.bytesRead);
|
|
24
30
|
}
|
|
@@ -33,9 +39,10 @@ export class ZipArtifactReader {
|
|
|
33
39
|
#source;
|
|
34
40
|
#reader;
|
|
35
41
|
#entries = new Map();
|
|
36
|
-
|
|
42
|
+
/** Optionally bound each metadata read before allocating its backing buffer. */
|
|
43
|
+
constructor(path, format, maximumMetadataReadBytes) {
|
|
37
44
|
this.format = format;
|
|
38
|
-
this.#source = new NodeFileReader(path);
|
|
45
|
+
this.#source = new NodeFileReader(path, maximumMetadataReadBytes);
|
|
39
46
|
this.#reader = new ZipReader(this.#source, {
|
|
40
47
|
checkSignature: true,
|
|
41
48
|
checkOverlappingEntry: true,
|