rea-agents 5.0.0 → 6.1.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 +168 -655
- package/bridge/android/ReaJadxBridge.java +14 -5
- package/bridge/ghidra/ReaGhidraBridge.java +173 -47
- package/bridge/hopper_bridge.py +310 -128
- package/bridge/mitmproxy/capture.py +208 -0
- package/bridge/native/rea_lldb_tracer.py +839 -0
- package/bridge/process/ProcessRunTokenReader.swift +297 -0
- package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
- package/bridge/pwndbg/core_context.py +101 -0
- package/bridge/pwndbg/launch.py +39 -0
- package/bridge/pwndbg/launch_impl.py +34 -0
- package/bridge/pwntools/decoder_runtime.py +59 -0
- package/bridge/pwntools/layout.py +39 -0
- package/bridge/pwntools/layout_impl.py +309 -0
- package/bridge/pwntools/recorded_crash.py +39 -0
- package/bridge/pwntools/recorded_crash_impl.py +147 -0
- package/dist/android/JadxConfiguration.js +196 -33
- package/dist/android/JadxMcpTransport.js +4 -0
- package/dist/android/JadxProtocol.js +6 -0
- package/dist/android/JadxProvider.js +20 -2
- 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/CallPathTracing.js +19 -3
- package/dist/application/CapabilityInventory.js +27 -3
- package/dist/application/ClientConfigurationDocument.js +871 -6
- package/dist/application/ClientRegistrationIdentity.js +26 -5
- package/dist/application/ClientRegistrationStatus.js +29 -14
- package/dist/application/DirectAnalysis.js +97 -33
- package/dist/application/Doctor.js +4 -2
- package/dist/application/DoctorScope.js +25 -13
- package/dist/application/EnhancedLiteralTracing.js +22 -25
- package/dist/application/EnhancedTools.js +13 -11
- package/dist/application/EvidenceBundleFiles.js +24 -12
- package/dist/application/FunctionAnalysisEvidence.js +2 -3
- package/dist/application/InventoryProjectionEvidence.js +4 -3
- package/dist/application/InvestigationProviders.js +3 -2
- package/dist/application/JsonFiles.js +50 -28
- package/dist/application/ProcedureAddressResolution.js +11 -0
- package/dist/application/ReconstructionCoverageService.js +7 -4
- package/dist/application/ReconstructionObligationCandidates.js +5 -1
- package/dist/application/ReconstructionObligationLedgerService.js +4 -3
- package/dist/application/Setup.js +13 -1
- package/dist/application/SetupClientConfiguration.js +10 -15
- package/dist/application/SetupHost.js +5 -2
- package/dist/application/SetupPlan.js +5 -3
- package/dist/application/SupportedClients.js +34 -1
- package/dist/application/Uninstall.js +4 -3
- package/dist/application/Update.js +18 -3
- package/dist/application/UpdateRuntime.js +46 -25
- package/dist/application/WebModuleTraceService.js +4 -2
- package/dist/application/WebNetworkCapturePort.js +1 -0
- package/dist/application/WebNetworkCaptureService.js +134 -0
- package/dist/application/WebRuntimeService.js +5 -3
- package/dist/application/WebScriptExportService.js +2 -2
- package/dist/application/WebSourceLocationService.js +4 -2
- package/dist/application/WindowsCapabilities.js +1 -1
- package/dist/application/WorkflowEvidence.js +82 -0
- package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
- package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
- package/dist/application/binary/AnalysisSnapshotCache.js +52 -12
- package/dist/application/binary/BinarySession.js +131 -76
- package/dist/application/binary/BinarySessionOpen.js +19 -6
- package/dist/application/binary/BinarySessionRecords.js +45 -3
- package/dist/application/binary/BinarySessionStatus.js +17 -1
- package/dist/application/binary/CompositeProvider.js +13 -0
- package/dist/application/binary/LazyAnalysisProvider.js +3 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +59 -0
- package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +62 -0
- package/dist/application/evm/EvmInterfacePort.js +1 -0
- package/dist/application/evm/EvmInterfaceService.js +64 -0
- package/dist/application/investigation/EvidenceLedger.js +21 -7
- package/dist/application/investigation/InvestigationRecords.js +8 -0
- package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +25 -5
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
- package/dist/application/javascript/JavaScriptApplicationService.js +34 -14
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +47 -27
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +80 -27
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +33 -12
- package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
- package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +149 -72
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +27 -5
- package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
- package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
- package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
- package/dist/application/managed/ManagedReconstructionService.js +4 -3
- package/dist/application/{ProcessCli.js → process/ProcessCli.js} +23 -15
- package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +8 -7
- package/dist/application/workflowInputError.js +18 -0
- package/dist/artifacts/ArtifactProvider.js +42 -5
- package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
- package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
- package/dist/artifacts/ZipArtifactReader.js +3 -0
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
- package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
- package/dist/artifacts/apple/MachoLoadCommandReader.js +355 -0
- 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/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
- package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +16 -11
- package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
- package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
- package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
- package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +14 -17
- package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
- package/dist/artifacts/readStableArtifact.js +20 -4
- package/dist/browser/CdpCaptureCompleteness.js +2 -0
- package/dist/browser/CdpCaptureEventHandlers.js +165 -12
- package/dist/browser/CdpCaptureEventTypes.js +5 -1
- package/dist/browser/CdpCaptureEvents.js +34 -0
- package/dist/browser/CdpConnection.js +30 -11
- package/dist/browser/CdpOptionalCommand.js +2 -3
- package/dist/browser/CdpPageCapture.js +23 -1
- package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
- package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +130 -122
- package/dist/browser/WebSourceMapFetcher.js +426 -72
- package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
- package/dist/browser/history/CaptureFailures.js +137 -0
- package/dist/browser/history/CaptureFormatError.js +10 -0
- package/dist/browser/history/CaptureRedaction.js +65 -0
- package/dist/browser/history/CaptureRelease.js +17 -0
- package/dist/browser/history/HarCapture.js +165 -0
- package/dist/browser/history/HarCaptureAdapter.js +20 -0
- package/dist/browser/history/HarCaptureProcess.js +57 -0
- package/dist/browser/history/HarJson.js +92 -0
- package/dist/browser/history/HarSchema.js +72 -0
- package/dist/browser/history/HistoricalCaptureDecoder.js +188 -0
- package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
- package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
- package/dist/cli/analysisSelector.js +23 -0
- package/dist/cli/applicationCommands.js +2 -3
- package/dist/cli/artifactCommands.js +26 -1
- package/dist/cli/binaryDiagnosticsCommands.js +39 -0
- package/dist/cli/coreAnalysisCommands.js +2 -2
- package/dist/cli/coreBinaryCommands.js +78 -20
- package/dist/cli/electronCommands.js +21 -13
- package/dist/cli/evmCommands.js +24 -0
- package/dist/cli/firmwareCommands.js +6 -3
- package/dist/cli/javascriptApplicationAnalysis.js +20 -3
- package/dist/cli/jsonOutput.js +38 -0
- package/dist/cli/nativeCallCommands.js +34 -0
- package/dist/cli/processCommands.js +1 -1
- package/dist/cli/streamedJsonOutput.js +56 -0
- package/dist/cli/utilityCommands.js +2 -0
- package/dist/cli/webNetworkCaptureCommands.js +40 -0
- package/dist/cli/webRuntimeCommands.js +8 -8
- package/dist/cli.js +11 -4
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +6 -1
- package/dist/cliJsonInput.js +35 -1
- package/dist/cliOutput.js +21 -6
- package/dist/composition/binaryDiagnostics.js +8 -0
- package/dist/composition/evm.js +4 -0
- package/dist/composition/webNetworkCaptures.js +6 -0
- package/dist/config/environment.js +4 -0
- package/dist/config/ghidraStartupTimeout.js +17 -0
- package/dist/config/mcpResponseBudget.js +22 -0
- package/dist/config/parseConfig.js +2 -1
- package/dist/contracts/artifactToolContracts.js +6 -0
- package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
- package/dist/contracts/browserToolContracts.js +4 -3
- package/dist/contracts/enhancedInputs.js +5 -3
- package/dist/contracts/enhancedToolContracts.js +3 -3
- package/dist/contracts/errorSchemas.js +8 -1
- package/dist/contracts/evm/evmToolContracts.js +20 -0
- package/dist/contracts/hopperMemoryContracts.js +2 -5
- package/dist/contracts/investigationExamples.js +2 -2
- package/dist/contracts/javascript/electronToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +8 -6
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
- package/dist/contracts/native/nativeToolContracts.js +21 -3
- package/dist/contracts/officialToolContracts.js +26 -24
- package/dist/contracts/process/processCaptureExample.js +2 -0
- package/dist/contracts/promptContracts.js +3 -3
- package/dist/contracts/sessionLifecycleInputs.js +18 -5
- package/dist/contracts/sessionStatusContract.js +8 -2
- package/dist/contracts/sessionToolContracts.js +8 -3
- package/dist/contracts/sessionToolSchemas.js +8 -4
- package/dist/contracts/toolContractExamples.js +1 -2
- package/dist/contracts/toolContractHelpers.js +4 -1
- package/dist/contracts/toolContracts.js +6 -0
- package/dist/contracts/toolEffects.js +30 -1
- package/dist/contracts/toolOutputSchemaGroups.js +33 -28
- package/dist/contracts/toolOutputSchemaPrimitives.js +19 -1
- package/dist/contracts/toolSchemaMetadata.js +69 -10
- package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
- package/dist/domain/analysisErrorBase.js +22 -2
- package/dist/domain/analysisErrorCore.js +61 -5
- package/dist/domain/analysisErrorPresentation.js +95 -12
- package/dist/domain/analysisErrorProjection.js +148 -19
- package/dist/domain/analysisSnapshot.js +166 -2
- package/dist/domain/android/androidAnalysis.js +2 -4
- package/dist/domain/android/androidApplication.js +17 -9
- package/dist/domain/apple/appleApplication.js +41 -14
- package/dist/domain/apple/dyldEnvironment.js +73 -0
- package/dist/domain/apple/dyldPaths.js +81 -0
- package/dist/domain/apple/dylibResolution.js +478 -0
- package/dist/domain/apple/dylibResolutionFindings.js +77 -0
- package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
- package/dist/domain/apple/keyedArchive.js +9 -1
- package/dist/domain/apple/machoContainer.js +54 -0
- package/dist/domain/apple/plistNumbers.js +76 -0
- package/dist/domain/artifactIdentity.js +29 -0
- package/dist/domain/artifactInventoryEvidence.js +19 -24
- package/dist/domain/artifactPathSyntax.js +1 -1
- package/dist/domain/bridgeCandidateProjection.js +71 -0
- package/dist/domain/browserCompleteness.js +1 -0
- package/dist/domain/browserObservation.js +1 -1
- package/dist/domain/browserObservationError.js +24 -5
- package/dist/domain/browserObservationSchemas.js +13 -0
- package/dist/domain/browserScenarioValues.js +5 -2
- package/dist/domain/bundleComparison.js +3 -2
- package/dist/domain/callPathSchemas.js +1 -1
- package/dist/domain/canonicalDigest.js +13 -1
- 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/comparisonStatus.js +2 -30
- package/dist/domain/configurationErrors.js +1 -1
- package/dist/domain/conformanceTrustGate.js +0 -16
- package/dist/domain/evidence.js +78 -11
- package/dist/domain/evidenceBundle.js +42 -1
- package/dist/domain/evidenceErrors.js +12 -1
- package/dist/domain/evm/evmInterface.js +63 -0
- package/dist/domain/explicitSensitiveFailure.js +108 -0
- package/dist/domain/explicitSensitiveValues.js +10 -0
- package/dist/domain/firmware/firmwareAnalysis.js +10 -4
- 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 +37 -6
- package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
- package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
- package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
- package/dist/domain/javascript/javascriptAstValues.js +20 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
- package/dist/domain/javascript/javascriptRecovery.js +3 -8
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
- package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
- package/dist/domain/javascript/javascriptSemanticGraph.js +34 -5
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
- 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 +14 -4
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
- package/dist/domain/jsonSerialization.js +109 -0
- package/dist/domain/jsonValue.js +91 -3
- package/dist/domain/localPath.js +8 -0
- package/dist/domain/managed/managedApplicationGraph.js +10 -10
- package/dist/domain/managed/managedInspectionEvidence.js +16 -0
- package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
- package/dist/domain/managed/managedNativeVerification.js +3 -9
- package/dist/domain/native/binaryLayout.js +357 -0
- package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
- package/dist/domain/native/nativeCallObservation.js +186 -0
- package/dist/domain/native/nativeCallPartialObservation.js +33 -0
- package/dist/domain/native/objcSwiftMetadata.js +0 -39
- package/dist/domain/native/recordedCrash.js +266 -0
- package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
- package/dist/domain/{processCapture.js → process/processCapture.js} +143 -2
- package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
- package/dist/domain/process/processCaptureParsing.js +54 -0
- package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
- package/dist/domain/{processComparison.js → process/processComparison.js} +39 -5
- package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
- package/dist/domain/{processScenario.js → process/processScenario.js} +11 -10
- package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
- package/dist/domain/propertyListKeys.js +1 -1
- package/dist/domain/propertyListXmlText.js +19 -0
- package/dist/domain/providerAdapterError.js +1 -1
- package/dist/domain/providerOperationHealth.js +54 -0
- package/dist/domain/providerSelectionError.js +4 -2
- package/dist/domain/reconstructionVerification.js +9 -46
- package/dist/domain/reconstructionVerificationSchemas.js +3 -3
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +9 -46
- 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 +1 -0
- package/dist/domain/webNetworkCapture.js +118 -0
- package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
- package/dist/domain/webRuntime.js +19 -5
- package/dist/domain/webSourceLocation.js +1 -0
- package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
- package/dist/dotnet/ManagedMemberInspector.js +4 -2
- package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
- package/dist/dotnet/ManagedMemberRows.js +14 -3
- package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
- package/dist/dotnet/ManagedMetadataInventory.js +38 -28
- package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
- package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
- package/dist/dotnet/ManagedPeReader.js +11 -0
- package/dist/evm/EvmBytecodeCarrier.js +21 -0
- package/dist/evm/EvmWorkerLimits.js +40 -0
- package/dist/evm/EvmoleFailures.js +126 -0
- package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
- package/dist/evm/EvmoleInterfaceProvider.js +273 -0
- package/dist/evm/EvmoleInterfaceWorker.js +87 -0
- package/dist/evm/EvmoleRelease.js +16 -0
- package/dist/firmware/FirmwareCommand.js +1 -0
- package/dist/firmware/FirmwareFiles.js +1 -1
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
- package/dist/ghidra/GhidraClient.js +47 -14
- package/dist/ghidra/GhidraDiagnostics.js +7 -7
- package/dist/ghidra/GhidraFunctionValues.js +10 -7
- package/dist/ghidra/GhidraInstallation.js +18 -21
- package/dist/ghidra/GhidraInventoryValues.js +14 -4
- package/dist/ghidra/GhidraJavaLaunch.js +62 -0
- package/dist/ghidra/GhidraLauncher.js +34 -16
- package/dist/ghidra/GhidraProvider.js +2 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +15 -3
- package/dist/ghidra/GhidraProviderClient.js +23 -12
- package/dist/ghidra/GhidraSessionError.js +11 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
- package/dist/ghidra/GhidraTransport.js +20 -0
- package/dist/hopper/BridgeLauncher.js +33 -11
- package/dist/hopper/HopperAnalysisProfile.js +62 -4
- package/dist/hopper/HopperCleanup.js +15 -3
- package/dist/hopper/HopperClient.js +222 -14
- package/dist/hopper/HopperFileOffset.js +237 -0
- package/dist/hopper/HopperMachOImage.js +196 -0
- package/dist/hopper/HopperOperationStage.js +6 -0
- package/dist/hopper/HopperProvider.js +63 -9
- package/dist/hopper/HopperProviderCapabilities.js +19 -1
- package/dist/hopper/HopperRegexSearch.js +137 -0
- package/dist/hopper/HopperRegexWorker.js +27 -0
- package/dist/hopper/HopperRequestQueue.js +68 -19
- package/dist/hopper/HopperTargetLease.js +3 -2
- package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
- package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
- package/dist/inspector/V8InspectorProvider.js +47 -11
- package/dist/javascript/recovery/WakaruCommand.js +3 -0
- package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +17 -0
- package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
- package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
- 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 +32 -16
- 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 +82 -84
- package/dist/native/LldbCallTracer.js +541 -0
- package/dist/native/LldbRetainedObservations.js +178 -0
- package/dist/native/NativeCallObservation.js +194 -0
- package/dist/native/NativeMacOSProvider.js +117 -20
- package/dist/native/NativeMacOSProviderMetadata.js +8 -3
- package/dist/native/SignatureTargetBinding.js +155 -0
- package/dist/native/parsers/lipo.js +71 -1
- package/dist/native/pwndbg/PwndbgCoreContext.js +180 -0
- package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
- package/dist/native/pwntools/PwntoolsFailures.js +180 -0
- package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
- package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
- package/dist/native/pwntools/PwntoolsRelease.js +19 -0
- package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
- package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +103 -0
- package/dist/process/DarwinProcessRunTokenReader.js +293 -0
- package/dist/process/ExecFileOutput.js +20 -0
- package/dist/process/OwnedCommand.js +118 -0
- package/dist/process/ProcessOwnership.js +431 -51
- package/dist/process/ProcessOwnershipObservation.js +209 -27
- package/dist/process/ProviderProcess.js +68 -10
- package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
- package/dist/{application → process/capture}/ProcessCaptureError.js +18 -2
- package/dist/process/capture/ProcessCaptureLifecycle.js +681 -0
- package/dist/{application → process/capture}/ProcessHarness.js +195 -29
- package/dist/{application → process/capture}/ProcessSampling.js +2 -2
- package/dist/server/EvidenceMcpServer.js +146 -0
- package/dist/server/createServer.js +37 -8
- package/dist/server/promptCompletion.js +10 -3
- package/dist/server/registerAndroidTools.js +2 -4
- package/dist/server/registerApplicationTools/helpers.js +2 -4
- package/dist/server/registerArtifactComparisonTool.js +11 -7
- package/dist/server/registerBinaryDiagnosticsTools.js +15 -0
- package/dist/server/registerBrowserScenarioTool.js +2 -4
- package/dist/server/registerBrowserTools.js +2 -4
- package/dist/server/registerBundleComparisonTool.js +2 -3
- package/dist/server/registerCloseLifecycleTool.js +8 -18
- package/dist/server/registerElectronTools.js +2 -4
- package/dist/server/registerEnhancedTools.js +18 -59
- package/dist/server/registerEvidenceTools.js +3 -5
- package/dist/server/registerEvmTools.js +15 -0
- package/dist/server/registerFirmwareTools.js +2 -4
- package/dist/server/registerFunctionComparisonTool.js +10 -6
- package/dist/server/registerInvestigationTools.js +7 -7
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
- package/dist/server/registerOfficialTools.js +2 -4
- package/dist/server/registerProcessComparisonTool.js +72 -46
- package/dist/server/registerRecordedCrashTools.js +15 -0
- package/dist/server/registerSessionRecordTools.js +5 -6
- package/dist/server/registerSessionStatusTool.js +17 -3
- package/dist/server/registerSessionTools.js +13 -5
- package/dist/server/registerWebModuleTool.js +2 -4
- package/dist/server/registerWebNetworkCaptureTool.js +26 -0
- package/dist/server/registerWebRuntimeTools.js +3 -7
- package/dist/server/registerWebScriptTool.js +2 -4
- package/dist/server/registerWebSourceLocationTool.js +2 -4
- package/dist/server/runDerivedOperation.js +15 -3
- package/dist/server/sessionAvailabilityPolicy.js +3 -1
- package/dist/server/sessionToolPolicies.js +1 -1
- package/dist/server/toolRegistrationOptions.js +2 -2
- package/dist/server/toolResult.js +63 -11
- package/dist/server/toolResultEncoding.js +33 -0
- package/install.sh +1 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +42 -9
- package/scripts/electron-active-hook-boundaries.cjs +18 -20
- package/scripts/electron-active-hook.cjs +241 -37
- package/scripts/rea.mjs +11 -3
- package/skills/reverse-engineer-anything/SKILL.md +32 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
- package/third_party/README.md +60 -0
- package/third_party/evmole/LICENSE +21 -0
- package/third_party/evmole/README.md +22 -0
- package/third_party/pwndbg/LICENSE.md +21 -0
- package/third_party/pwndbg/README.md +23 -0
- package/third_party/pwntools/README.md +40 -0
- package/dist/application/AuthorizedArtifactInventory.js +0 -7
- package/dist/application/ProcessCaptureLifecycle.js +0 -299
- package/dist/application/StoreFileLock.js +0 -124
- package/dist/contracts/processCaptureExample.js +0 -2
- package/dist/domain/bytecodeProvider.js +0 -178
- package/dist/domain/customProtocolCapture.js +0 -137
- package/dist/domain/eventProcessTree.js +0 -225
- package/dist/domain/mobileApplicationInvestigation.js +0 -159
- package/dist/domain/packageAnalysis.js +0 -123
- package/dist/domain/peInspection.js +0 -197
- package/dist/domain/processCaptureParsing.js +0 -21
- package/dist/domain/protocolCapture.js +0 -217
- package/dist/domain/runtimeIdentification.js +0 -212
- package/dist/generatedMcpToolCatalog.js +0 -37
- package/dist/ghidra/GhidraDefaults.js +0 -2
- /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
- /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
- /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
- /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
- /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
- /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
- /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
- /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
- /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
- /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
- /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
- /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
- /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
- /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
- /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Worker } from "node:worker_threads";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { AnalysisCancelledError, AnalysisOutputError, AnalysisResourceConstraintError, } from "../domain/analysisErrorCore.js";
|
|
4
|
+
import { analysisStringSchema } from "../domain/hopperValues.js";
|
|
5
|
+
import { HopperRemoteError } from "../domain/hopperErrors.js";
|
|
6
|
+
import { err, ok } from "../domain/result.js";
|
|
7
|
+
import { analysisSearchInput } from "../contracts/analysisSearchContract.js";
|
|
8
|
+
const MATCHING_DEADLINE_MS = 5_000;
|
|
9
|
+
const inputSchema = z.strictObject({
|
|
10
|
+
...analysisSearchInput,
|
|
11
|
+
mode: z.literal("regex"),
|
|
12
|
+
document: z.string().nullish(),
|
|
13
|
+
case_sensitive: z
|
|
14
|
+
.boolean()
|
|
15
|
+
.nullish()
|
|
16
|
+
.transform((value) => value ?? false),
|
|
17
|
+
});
|
|
18
|
+
const replySchema = z.discriminatedUnion("status", [
|
|
19
|
+
z.strictObject({
|
|
20
|
+
status: z.literal("matched"),
|
|
21
|
+
indices: z.array(z.number().int().nonnegative()),
|
|
22
|
+
}),
|
|
23
|
+
z.strictObject({ status: z.literal("invalid_pattern"), reason: z.string() }),
|
|
24
|
+
]);
|
|
25
|
+
/** Match collected native facts off Hopper's API thread, with cancellable lifetime. */
|
|
26
|
+
export class HopperRegexSearch {
|
|
27
|
+
client;
|
|
28
|
+
#active = new Map();
|
|
29
|
+
constructor(client) {
|
|
30
|
+
this.client = client;
|
|
31
|
+
}
|
|
32
|
+
execute(operation, parameters, options) {
|
|
33
|
+
const controller = new AbortController();
|
|
34
|
+
const signal = options?.signal === undefined
|
|
35
|
+
? controller.signal
|
|
36
|
+
: AbortSignal.any([controller.signal, options.signal]);
|
|
37
|
+
const pending = this.#execute(operation, parameters, {
|
|
38
|
+
...options,
|
|
39
|
+
signal,
|
|
40
|
+
});
|
|
41
|
+
this.#active.set(controller, pending);
|
|
42
|
+
void pending.then(() => this.#active.delete(controller), () => this.#active.delete(controller));
|
|
43
|
+
return pending;
|
|
44
|
+
}
|
|
45
|
+
/** Abort matching workers before their provider session closes. */
|
|
46
|
+
async close() {
|
|
47
|
+
for (const controller of this.#active.keys())
|
|
48
|
+
controller.abort();
|
|
49
|
+
await Promise.all(this.#active.values());
|
|
50
|
+
}
|
|
51
|
+
async #execute(operation, parameters, options) {
|
|
52
|
+
const input = inputSchema.safeParse(parameters);
|
|
53
|
+
if (!input.success)
|
|
54
|
+
return err(new HopperRemoteError(-32000, `Invalid search arguments: ${input.error.message}`, { diagnosticType: "invalid_request", operation }));
|
|
55
|
+
const inventoryOptions = {
|
|
56
|
+
...options,
|
|
57
|
+
...(options.progress === undefined
|
|
58
|
+
? {}
|
|
59
|
+
: {
|
|
60
|
+
progress: {
|
|
61
|
+
report: (update) => options.progress?.report({
|
|
62
|
+
...update,
|
|
63
|
+
completed: update.total === null || update.total === 0
|
|
64
|
+
? 0
|
|
65
|
+
: Math.min(0.5, update.completed / update.total / 2),
|
|
66
|
+
total: 1,
|
|
67
|
+
}) ?? Promise.resolve(),
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
const inventory = await this.client.callTool(operation === "search_strings" ? "list_strings" : "list_procedures", input.data.document == null ? {} : { document: input.data.document }, inventoryOptions);
|
|
72
|
+
if (!inventory.ok)
|
|
73
|
+
return inventory;
|
|
74
|
+
const parsed = z.array(analysisStringSchema).safeParse(inventory.value);
|
|
75
|
+
if (!parsed.success)
|
|
76
|
+
return err(new AnalysisOutputError(operation, "Hopper search inventory is malformed"));
|
|
77
|
+
if (options.signal?.aborted)
|
|
78
|
+
return err(new AnalysisCancelledError(operation));
|
|
79
|
+
await options.progress
|
|
80
|
+
?.report({
|
|
81
|
+
phase: "hopper_regex",
|
|
82
|
+
completed: 0.5,
|
|
83
|
+
total: 1,
|
|
84
|
+
message: "Matching inventory in cancellable regex worker",
|
|
85
|
+
})
|
|
86
|
+
.catch(() => undefined);
|
|
87
|
+
if (options.signal?.aborted)
|
|
88
|
+
return err(new AnalysisCancelledError(operation));
|
|
89
|
+
let worker;
|
|
90
|
+
try {
|
|
91
|
+
worker = new Worker(new URL("./HopperRegexWorker.js", import.meta.url), {
|
|
92
|
+
workerData: {
|
|
93
|
+
pattern: input.data.pattern,
|
|
94
|
+
caseSensitive: input.data.case_sensitive,
|
|
95
|
+
values: parsed.data.map((item) => item.value),
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (cause) {
|
|
100
|
+
return err(new AnalysisOutputError(operation, `Cannot start regex worker: ${cause instanceof Error ? cause.message : String(cause)}`, { cause }));
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
return await new Promise((resolve) => {
|
|
104
|
+
const finish = (result) => {
|
|
105
|
+
clearTimeout(timer);
|
|
106
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
107
|
+
resolve(result);
|
|
108
|
+
};
|
|
109
|
+
const onAbort = () => finish(err(new AnalysisCancelledError(operation)));
|
|
110
|
+
const timer = setTimeout(() => finish(err(new AnalysisResourceConstraintError(operation, "cpu", "Regex matching exceeded its supervised deadline; the Hopper API thread remains available.", { matching_deadline_ms: MATCHING_DEADLINE_MS }, {
|
|
111
|
+
remediationAction: "Simplify the ECMAScript Unicode regex or use literal mode, then retry in the same session.",
|
|
112
|
+
}))), MATCHING_DEADLINE_MS);
|
|
113
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
114
|
+
if (options.signal?.aborted)
|
|
115
|
+
onAbort();
|
|
116
|
+
worker.once("message", (message) => {
|
|
117
|
+
const reply = replySchema.safeParse(message);
|
|
118
|
+
if (!reply.success)
|
|
119
|
+
return finish(err(new AnalysisOutputError(operation, "Regex worker reply is malformed")));
|
|
120
|
+
if (reply.data.status === "invalid_pattern")
|
|
121
|
+
return finish(err(new HopperRemoteError(-32000, `Invalid regex pattern: ${reply.data.reason}`, { diagnosticType: "invalid_request", operation })));
|
|
122
|
+
const indices = reply.data.indices;
|
|
123
|
+
if (indices.some((index, position) => index >= parsed.data.length ||
|
|
124
|
+
(position > 0 && index <= (indices[position - 1] ?? -1))))
|
|
125
|
+
return finish(err(new AnalysisOutputError(operation, "Regex worker returned invalid inventory indices")));
|
|
126
|
+
const selected = new Set(indices);
|
|
127
|
+
finish(ok(parsed.data.filter((_, index) => selected.has(index))));
|
|
128
|
+
});
|
|
129
|
+
worker.once("error", (cause) => finish(err(new AnalysisOutputError(operation, `Regex worker failed: ${cause.message}`, { cause }))));
|
|
130
|
+
worker.once("exit", (code) => finish(err(new AnalysisOutputError(operation, `Regex worker exited without a result (${code})`))));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
await worker.terminate();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const input = z
|
|
4
|
+
.strictObject({
|
|
5
|
+
pattern: z.string().min(1),
|
|
6
|
+
caseSensitive: z.boolean(),
|
|
7
|
+
values: z.array(z.string()),
|
|
8
|
+
})
|
|
9
|
+
.parse(workerData);
|
|
10
|
+
let expression;
|
|
11
|
+
try {
|
|
12
|
+
expression = new RegExp(input.pattern, input.caseSensitive ? "u" : "iu");
|
|
13
|
+
}
|
|
14
|
+
catch (cause) {
|
|
15
|
+
parentPort?.postMessage({
|
|
16
|
+
status: "invalid_pattern",
|
|
17
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (expression !== undefined) {
|
|
21
|
+
const indices = [];
|
|
22
|
+
for (const [index, value] of input.values.entries()) {
|
|
23
|
+
if (expression.test(value))
|
|
24
|
+
indices.push(index);
|
|
25
|
+
}
|
|
26
|
+
parentPort?.postMessage({ status: "matched", indices });
|
|
27
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hopperOperationStage } from "./HopperOperationStage.js";
|
|
2
|
+
import { HopperCancelledError, HopperProcessError, HopperProtocolError, HopperRemoteError, HopperTimeoutError, } from "../domain/hopperErrors.js";
|
|
2
3
|
import { err } from "../domain/result.js";
|
|
4
|
+
/** Node timer ceiling; larger deadlines would be clamped instead of honored. */
|
|
5
|
+
const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
3
6
|
/** FIFO that keeps the wire serialized until Hopper actually replies. */
|
|
4
7
|
export class HopperRequestQueue {
|
|
5
8
|
send;
|
|
@@ -8,10 +11,18 @@ export class HopperRequestQueue {
|
|
|
8
11
|
constructor(send) {
|
|
9
12
|
this.send = send;
|
|
10
13
|
}
|
|
11
|
-
/**
|
|
14
|
+
/** Settle the caller on reply, cancellation, or deadline; retain active wire work. */
|
|
12
15
|
run(id, method, params, options) {
|
|
13
16
|
if (options.signal?.aborted === true)
|
|
14
17
|
return Promise.resolve(err(new HopperCancelledError()));
|
|
18
|
+
const timeoutMs = options.timeoutMs;
|
|
19
|
+
if (timeoutMs !== undefined &&
|
|
20
|
+
(!Number.isInteger(timeoutMs) ||
|
|
21
|
+
timeoutMs < 0 ||
|
|
22
|
+
timeoutMs > MAX_TIMEOUT_MS))
|
|
23
|
+
return Promise.resolve(err(new HopperProtocolError(`Hopper timeoutMs must be an integer between 0 and ${String(MAX_TIMEOUT_MS)}`)));
|
|
24
|
+
if (timeoutMs === 0)
|
|
25
|
+
return Promise.resolve(err(new HopperTimeoutError(0, method, id, "not_started", hopperOperationStage(method))));
|
|
15
26
|
return new Promise((resolve) => {
|
|
16
27
|
let entry;
|
|
17
28
|
const onAbort = options.signal === undefined ? undefined : () => this.#cancel(entry);
|
|
@@ -25,12 +36,18 @@ export class HopperRequestQueue {
|
|
|
25
36
|
onAbort,
|
|
26
37
|
callerState: "waiting",
|
|
27
38
|
callerSettled: false,
|
|
39
|
+
transmitted: false,
|
|
28
40
|
startedAt: undefined,
|
|
29
41
|
heartbeat: undefined,
|
|
42
|
+
deadline: undefined,
|
|
43
|
+
deadlineAt: timeoutMs === undefined ? undefined : performance.now() + timeoutMs,
|
|
44
|
+
timeoutMs,
|
|
30
45
|
};
|
|
31
46
|
this.#queue.push(entry);
|
|
32
47
|
if (onAbort !== undefined)
|
|
33
48
|
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
49
|
+
if (timeoutMs !== undefined)
|
|
50
|
+
entry.deadline = setTimeout(() => this.#cancel(entry, this.#timeoutError(entry, timeoutMs)), timeoutMs);
|
|
34
51
|
if (this.#active !== undefined || this.#queue.length > 1)
|
|
35
52
|
this.#report(entry, `${method} queued behind ${String(this.#size() - 1)} Hopper request(s)`);
|
|
36
53
|
this.#drain();
|
|
@@ -41,17 +58,10 @@ export class HopperRequestQueue {
|
|
|
41
58
|
const entry = this.#active;
|
|
42
59
|
if (entry === undefined || entry.id !== id)
|
|
43
60
|
return false;
|
|
61
|
+
this.#expireIfElapsed(entry);
|
|
44
62
|
this.#releaseWire(entry);
|
|
45
|
-
if (!entry.callerSettled)
|
|
46
|
-
|
|
47
|
-
? err(new HopperRemoteError(result.error.code, result.error.safeMessage, {
|
|
48
|
-
diagnosticType: result.error.diagnosticType,
|
|
49
|
-
operation: entry.method,
|
|
50
|
-
requestId: entry.id,
|
|
51
|
-
}))
|
|
52
|
-
: result;
|
|
53
|
-
this.#settleCaller(entry, contextual, "waiting");
|
|
54
|
-
}
|
|
63
|
+
if (!entry.callerSettled)
|
|
64
|
+
this.#settleCaller(entry, result.ok ? result : err(withRequestContext(result.error, entry)), "waiting");
|
|
55
65
|
this.#active = undefined;
|
|
56
66
|
this.#drain();
|
|
57
67
|
return true;
|
|
@@ -120,6 +130,10 @@ export class HopperRequestQueue {
|
|
|
120
130
|
const entry = this.#queue.shift();
|
|
121
131
|
if (entry === undefined)
|
|
122
132
|
return;
|
|
133
|
+
if (this.#expireIfElapsed(entry)) {
|
|
134
|
+
this.#drain();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
123
137
|
if (entry.signal?.aborted === true) {
|
|
124
138
|
this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
|
|
125
139
|
this.#drain();
|
|
@@ -128,6 +142,17 @@ export class HopperRequestQueue {
|
|
|
128
142
|
this.#active = entry;
|
|
129
143
|
entry.startedAt = performance.now();
|
|
130
144
|
this.#report(entry, `${entry.method} started on Hopper's serial bridge`);
|
|
145
|
+
this.#expireIfElapsed(entry);
|
|
146
|
+
// A progress observer may cancel or tear down synchronously before send.
|
|
147
|
+
// No native work exists yet, so it is safe to release this reserved slot.
|
|
148
|
+
if (this.#active !== entry || entry.callerSettled) {
|
|
149
|
+
if (this.#active === entry) {
|
|
150
|
+
this.#active = undefined;
|
|
151
|
+
this.#releaseWire(entry);
|
|
152
|
+
this.#drain();
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
131
156
|
entry.heartbeat = setInterval(() => {
|
|
132
157
|
if (entry.callerSettled || entry.startedAt === undefined)
|
|
133
158
|
return;
|
|
@@ -135,30 +160,44 @@ export class HopperRequestQueue {
|
|
|
135
160
|
this.#report(entry, `${entry.method} is still running in Hopper (${String(elapsed)} ms elapsed)`);
|
|
136
161
|
}, 1_000);
|
|
137
162
|
try {
|
|
138
|
-
|
|
163
|
+
entry.transmitted = true;
|
|
164
|
+
this.send({ id: entry.id, method: entry.method, params: entry.params }, () => this.accept(entry.id, err(new HopperProcessError(null, undefined, entry.method, entry.id, "unreachable", hopperOperationStage(entry.method)))));
|
|
139
165
|
}
|
|
140
166
|
catch (cause) {
|
|
141
167
|
this.accept(entry.id, err(new HopperProtocolError("Hopper socket write failed", { cause })));
|
|
142
168
|
}
|
|
143
169
|
}
|
|
144
|
-
#
|
|
170
|
+
#timeoutError(entry, timeoutMs) {
|
|
171
|
+
return new HopperTimeoutError(timeoutMs, entry.method, entry.id, entry.transmitted ? "busy" : "not_started", hopperOperationStage(entry.method));
|
|
172
|
+
}
|
|
173
|
+
#expireIfElapsed(entry) {
|
|
174
|
+
if (entry.deadlineAt !== undefined &&
|
|
175
|
+
entry.timeoutMs !== undefined &&
|
|
176
|
+
performance.now() >= entry.deadlineAt)
|
|
177
|
+
this.#settleCaller(entry, err(this.#timeoutError(entry, entry.timeoutMs)), "cancelled");
|
|
178
|
+
return entry.callerSettled;
|
|
179
|
+
}
|
|
180
|
+
#cancel(entry, error = new HopperCancelledError()) {
|
|
145
181
|
if (entry.callerSettled)
|
|
146
182
|
return;
|
|
147
183
|
if (this.#active === entry) {
|
|
148
|
-
this.#settleCaller(entry, err(
|
|
184
|
+
this.#settleCaller(entry, err(error), "cancelled");
|
|
149
185
|
return;
|
|
150
186
|
}
|
|
151
187
|
const index = this.#queue.indexOf(entry);
|
|
152
188
|
if (index < 0)
|
|
153
189
|
return;
|
|
154
190
|
this.#queue.splice(index, 1);
|
|
155
|
-
this.#settleCaller(entry, err(
|
|
191
|
+
this.#settleCaller(entry, err(error), "cancelled");
|
|
156
192
|
}
|
|
157
193
|
#settleCaller(entry, result, callerState) {
|
|
158
194
|
if (entry.callerSettled)
|
|
159
195
|
return;
|
|
160
196
|
entry.callerSettled = true;
|
|
161
197
|
entry.callerState = callerState;
|
|
198
|
+
if (entry.deadline !== undefined)
|
|
199
|
+
clearTimeout(entry.deadline);
|
|
200
|
+
entry.deadline = undefined;
|
|
162
201
|
if (this.#active === entry && entry.heartbeat !== undefined) {
|
|
163
202
|
clearInterval(entry.heartbeat);
|
|
164
203
|
entry.heartbeat = undefined;
|
|
@@ -195,6 +234,16 @@ export class HopperRequestQueue {
|
|
|
195
234
|
}
|
|
196
235
|
}
|
|
197
236
|
}
|
|
198
|
-
const withRequestContext = (error, entry) =>
|
|
199
|
-
|
|
200
|
-
|
|
237
|
+
const withRequestContext = (error, entry) => {
|
|
238
|
+
if (error instanceof HopperProcessError)
|
|
239
|
+
return new HopperProcessError(error.exitCode, error.diagnostic, error.operation ?? entry.method, error.requestId ?? entry.id, error.providerState, error.operation === undefined && error.stage === "connection"
|
|
240
|
+
? hopperOperationStage(entry.method)
|
|
241
|
+
: error.stage);
|
|
242
|
+
if (error instanceof HopperRemoteError)
|
|
243
|
+
return new HopperRemoteError(error.code, error.safeMessage, {
|
|
244
|
+
diagnosticType: error.diagnosticType,
|
|
245
|
+
operation: error.operation ?? entry.method,
|
|
246
|
+
requestId: error.requestId ?? entry.id,
|
|
247
|
+
});
|
|
248
|
+
return error;
|
|
249
|
+
};
|
|
@@ -4,10 +4,11 @@ import { createConnection, createServer, } from "node:net";
|
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { HopperStartError } from "../domain/hopperErrors.js";
|
|
6
6
|
import { safeParseJson } from "../domain/safeJson.js";
|
|
7
|
-
|
|
7
|
+
/** Shared private parent of per-target lease sockets; it outlives individual sessions. */
|
|
8
|
+
export const HOPPER_TARGET_LEASE_DIRECTORY = join("/tmp", `rea-hopper-${process.getuid?.() ?? 0}`);
|
|
8
9
|
/** Keep two REA processes from opening duplicate Hopper documents for one target/profile. */
|
|
9
10
|
export const acquireHopperTargetLease = async (input) => {
|
|
10
|
-
const directory = input.directory ??
|
|
11
|
+
const directory = input.directory ?? HOPPER_TARGET_LEASE_DIRECTORY;
|
|
11
12
|
await ensureLeaseDirectory(directory);
|
|
12
13
|
// The canonical path only derives the lease key; it never authorizes access.
|
|
13
14
|
// Common expected `realpath` failures include a missing target or path
|
|
@@ -6,6 +6,7 @@ import { parseLinuxPrivateDisplayDiagnostic } from "./LinuxPrivateDisplayDiagnos
|
|
|
6
6
|
const PYTHON_PATH = "/usr/bin/python3";
|
|
7
7
|
const UNSHARE_PATH = "/usr/bin/unshare";
|
|
8
8
|
const DEFAULT_PROBE_TIMEOUT_MS = 5_000;
|
|
9
|
+
const isAborted = (signal) => signal?.aborted === true;
|
|
9
10
|
/** Probe the exact Xvfb boundary and select the least-privileged viable strategy. */
|
|
10
11
|
export const selectLinuxPrivateDisplayStrategy = async (options) => {
|
|
11
12
|
const timeoutMs = options.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
|
@@ -39,7 +40,7 @@ export const selectLinuxPrivateDisplayStrategy = async (options) => {
|
|
|
39
40
|
};
|
|
40
41
|
/** Run one helper probe in an owned process group and retain its full diagnostics. */
|
|
41
42
|
export const runLinuxPrivateDisplayProbe = async (strategy, options) => {
|
|
42
|
-
if (options.signal
|
|
43
|
+
if (isAborted(options.signal))
|
|
43
44
|
return emptyProcessResult("cancelled");
|
|
44
45
|
const command = privateDisplayProbeCommand(options.helperPath, strategy);
|
|
45
46
|
let started;
|
|
@@ -49,12 +50,13 @@ export const runLinuxPrivateDisplayProbe = async (strategy, options) => {
|
|
|
49
50
|
arguments: command.arguments,
|
|
50
51
|
runId: randomUUID(),
|
|
51
52
|
expectedCommand: null,
|
|
53
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
52
54
|
});
|
|
53
55
|
}
|
|
54
56
|
catch (cause) {
|
|
55
57
|
// best-effort cleanup: probe spawn failure is reported as launch-failed.
|
|
56
58
|
void cause;
|
|
57
|
-
return emptyProcessResult("launch-failed");
|
|
59
|
+
return emptyProcessResult(isAborted(options.signal) ? "cancelled" : "launch-failed");
|
|
58
60
|
}
|
|
59
61
|
const launch = {
|
|
60
62
|
process: started.process,
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { pathToFileURL } from "node:url";
|
|
2
2
|
import { browserOriginSchema, sanitizeBrowserUrl, } from "../domain/browserObservation.js";
|
|
3
|
+
import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
|
|
3
4
|
import { authorizedElectronFile } from "../browser/ElectronFileScope.js";
|
|
5
|
+
/** Throw the operation's typed cancellation error whenever its signal is aborted. */
|
|
6
|
+
export const throwIfRuntimeObservationCancelled = (signal) => {
|
|
7
|
+
if (signal?.aborted === true)
|
|
8
|
+
throw new AnalysisCancelledError("observe_javascript_runtime");
|
|
9
|
+
};
|
|
4
10
|
/**
|
|
5
11
|
* Wire bucket for inspector script exclusions. The V8 observation schemas
|
|
6
12
|
* fix the `unsupported_location` key, so every canonical denial reason maps
|
|
@@ -13,7 +19,8 @@ export const inspectorExclusionKey = (reason) => {
|
|
|
13
19
|
return "unsupported_location";
|
|
14
20
|
};
|
|
15
21
|
/** Resolve a protocol location exposed by the explicitly selected Inspector endpoint. */
|
|
16
|
-
export const authorizeRuntimeLocation = async (value) => {
|
|
22
|
+
export const authorizeRuntimeLocation = async (value, signal) => {
|
|
23
|
+
throwIfRuntimeObservationCancelled(signal);
|
|
17
24
|
if (value.startsWith("node:") && value.length > 0)
|
|
18
25
|
return {
|
|
19
26
|
allowed: true,
|
|
@@ -21,6 +28,7 @@ export const authorizeRuntimeLocation = async (value) => {
|
|
|
21
28
|
};
|
|
22
29
|
if (value.startsWith("file:")) {
|
|
23
30
|
const filePath = await authorizedElectronFile(value);
|
|
31
|
+
throwIfRuntimeObservationCancelled(signal);
|
|
24
32
|
return filePath === undefined
|
|
25
33
|
? { allowed: false, reason: "not_approved" }
|
|
26
34
|
: { allowed: true, location: { kind: "file", file_path: filePath } };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { authorizeRuntimeLocation, inspectorExclusionKey, } from "./JavaScriptRuntimeScope.js";
|
|
2
|
+
import { authorizeRuntimeLocation, inspectorExclusionKey, throwIfRuntimeObservationCancelled, } from "./JavaScriptRuntimeScope.js";
|
|
3
3
|
/** Empty durable-location exclusion counters. */
|
|
4
4
|
export const createInspectorExclusionCounts = () => ({
|
|
5
5
|
unsupported_location: 0,
|
|
@@ -15,7 +15,8 @@ export const describeInspectorTargetLimitations = () => [
|
|
|
15
15
|
];
|
|
16
16
|
const LOCATION_AUTHORIZATION_WORKERS = 8;
|
|
17
17
|
/** Canonically authorize, deduplicate, and sort one bounded raw capture. */
|
|
18
|
-
export const finalizeInspectorCapture = async ({ input, runtime, target, state, authorizeLocation = authorizeRuntimeLocation, }) => {
|
|
18
|
+
export const finalizeInspectorCapture = async ({ input, runtime, target, state, authorizeLocation = authorizeRuntimeLocation, signal, }) => {
|
|
19
|
+
throwIfRuntimeObservationCancelled(signal);
|
|
19
20
|
const exclusions = createInspectorExclusionCounts();
|
|
20
21
|
const scripts = new Map();
|
|
21
22
|
const draftsByUrl = new Map();
|
|
@@ -31,6 +32,7 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
|
|
|
31
32
|
const worker = async () => {
|
|
32
33
|
try {
|
|
33
34
|
for (;;) {
|
|
35
|
+
throwIfRuntimeObservationCancelled(signal);
|
|
34
36
|
if (stopScheduling)
|
|
35
37
|
return;
|
|
36
38
|
const index = nextGroup;
|
|
@@ -41,8 +43,9 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
|
|
|
41
43
|
const [rawUrl, drafts] = group;
|
|
42
44
|
authorizedGroups[index] = {
|
|
43
45
|
drafts,
|
|
44
|
-
decision: await authorizeLocation(rawUrl),
|
|
46
|
+
decision: await authorizeLocation(rawUrl, signal),
|
|
45
47
|
};
|
|
48
|
+
throwIfRuntimeObservationCancelled(signal);
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
51
|
catch (cause) {
|
|
@@ -52,6 +55,7 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
|
|
|
52
55
|
};
|
|
53
56
|
const workerResults = await Promise.allSettled(Array.from({ length: Math.min(LOCATION_AUTHORIZATION_WORKERS, groups.length) }, worker));
|
|
54
57
|
const failedWorker = workerResults.find((result) => result.status === "rejected");
|
|
58
|
+
throwIfRuntimeObservationCancelled(signal);
|
|
55
59
|
if (failedWorker?.status === "rejected")
|
|
56
60
|
throw failedWorker.reason;
|
|
57
61
|
for (const { drafts, decision } of authorizedGroups) {
|
|
@@ -81,6 +85,7 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
|
|
|
81
85
|
: left.context_key > right.context_key
|
|
82
86
|
? 1
|
|
83
87
|
: 0);
|
|
88
|
+
throwIfRuntimeObservationCancelled(signal);
|
|
84
89
|
return {
|
|
85
90
|
runtime,
|
|
86
91
|
target: {
|
|
@@ -12,6 +12,11 @@ import { discoverV8Inspector, } from "./V8InspectorEndpoint.js";
|
|
|
12
12
|
/** Public identity committed by passive V8 Inspector observations. */
|
|
13
13
|
export { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
|
|
14
14
|
import { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
|
|
15
|
+
/** Maximum decoded CDP message accepted while observing one Inspector target. */
|
|
16
|
+
export const INSPECTOR_MAX_PAYLOAD_BYTES = 16 * 1024 * 1024;
|
|
17
|
+
/** Aggregate retained metadata budget, including an estimate of JS object overhead. */
|
|
18
|
+
export const INSPECTOR_MAX_RETAINED_METADATA_BYTES = 8 * 1024 * 1024;
|
|
19
|
+
const RETAINED_OBJECT_OVERHEAD_BYTES = 512;
|
|
15
20
|
/** Attach-only provider; sends only Runtime.enable and Debugger.enable. */
|
|
16
21
|
export class V8InspectorProvider {
|
|
17
22
|
identity() {
|
|
@@ -61,7 +66,7 @@ export class V8InspectorProvider {
|
|
|
61
66
|
const target = await authorizedTarget(discovery.targets, input, discovery.runtime.product);
|
|
62
67
|
if (input.runtime_kind !== undefined)
|
|
63
68
|
assertRuntimeKind(target, input.runtime_kind);
|
|
64
|
-
connection = await CdpConnection.connect(target.webSocketUrl, "observe_javascript_runtime", options.signal);
|
|
69
|
+
connection = await CdpConnection.connect(target.webSocketUrl, "observe_javascript_runtime", options.signal, { maxPayloadBytes: INSPECTOR_MAX_PAYLOAD_BYTES });
|
|
65
70
|
const state = emptyCaptureState();
|
|
66
71
|
const removeListener = connection.onEvent((event) => ingestEvent(event, input, state));
|
|
67
72
|
try {
|
|
@@ -77,6 +82,7 @@ export class V8InspectorProvider {
|
|
|
77
82
|
runtime: discovery.runtime,
|
|
78
83
|
target,
|
|
79
84
|
state,
|
|
85
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
80
86
|
});
|
|
81
87
|
outcome = ok(javascriptRuntimeObservationSchema.parse(result));
|
|
82
88
|
}
|
|
@@ -206,15 +212,24 @@ const ingestScript = (event, input, state) => {
|
|
|
206
212
|
length: nonnegativeInteger(value?.length),
|
|
207
213
|
isModule: value?.isModule === true,
|
|
208
214
|
};
|
|
209
|
-
const bytes =
|
|
210
|
-
retainEvent(state, bytes)
|
|
215
|
+
const bytes = retainedMetadataBytes(draft);
|
|
216
|
+
if (!retainEvent(state, bytes))
|
|
217
|
+
return;
|
|
211
218
|
state.scripts.push(draft);
|
|
212
219
|
};
|
|
213
220
|
const ingestContext = (event, input, state) => {
|
|
214
221
|
if (event.method === "Runtime.executionContextsCleared") {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
222
|
+
let byteDelta = 0;
|
|
223
|
+
for (const context of state.contexts.values()) {
|
|
224
|
+
byteDelta +=
|
|
225
|
+
retainedMetadataBytes({ ...context, state: "cleared" }) -
|
|
226
|
+
retainedMetadataBytes(context);
|
|
227
|
+
}
|
|
228
|
+
if (replaceRetainedMetadata(state, byteDelta)) {
|
|
229
|
+
for (const context of state.contexts.values())
|
|
230
|
+
context.state = "cleared";
|
|
231
|
+
retainEvent(state, 0);
|
|
232
|
+
}
|
|
218
233
|
return;
|
|
219
234
|
}
|
|
220
235
|
const parameters = recordValue(event.params);
|
|
@@ -238,18 +253,33 @@ const ingestContext = (event, input, state) => {
|
|
|
238
253
|
: "destroyed",
|
|
239
254
|
origin: origin === "" ? null : origin,
|
|
240
255
|
};
|
|
241
|
-
const
|
|
242
|
-
|
|
256
|
+
const previous = state.contexts.get(key);
|
|
257
|
+
const bytes = retainedMetadataBytes(draft) -
|
|
258
|
+
(previous === undefined ? 0 : retainedMetadataBytes(previous));
|
|
259
|
+
if (!retainEvent(state, bytes))
|
|
260
|
+
return;
|
|
243
261
|
state.contexts.set(key, draft);
|
|
244
262
|
};
|
|
245
263
|
const retainEvent = (state, bytes) => {
|
|
246
|
-
state
|
|
264
|
+
if (!replaceRetainedMetadata(state, bytes))
|
|
265
|
+
return false;
|
|
247
266
|
state.eventsRetained += 1;
|
|
267
|
+
return true;
|
|
268
|
+
};
|
|
269
|
+
const replaceRetainedMetadata = (state, byteDelta) => {
|
|
270
|
+
if (state.metadataBytes + byteDelta > INSPECTOR_MAX_RETAINED_METADATA_BYTES) {
|
|
271
|
+
state.eventsDropped += 1;
|
|
272
|
+
state.truncated = true;
|
|
273
|
+
state.truncationReasons.add("retained_metadata_budget_exceeded");
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
state.metadataBytes += byteDelta;
|
|
277
|
+
return true;
|
|
248
278
|
};
|
|
249
279
|
const waitForCapture = async (connection, observationMs, signal) => {
|
|
250
280
|
let removeDisconnect = () => undefined;
|
|
251
281
|
const disconnected = new Promise((_resolve, reject) => {
|
|
252
|
-
removeDisconnect = connection.onDisconnect(() => reject(
|
|
282
|
+
removeDisconnect = connection.onDisconnect((error) => reject(error));
|
|
253
283
|
});
|
|
254
284
|
try {
|
|
255
285
|
await Promise.race([
|
|
@@ -261,7 +291,13 @@ const waitForCapture = async (connection, observationMs, signal) => {
|
|
|
261
291
|
removeDisconnect();
|
|
262
292
|
}
|
|
263
293
|
};
|
|
264
|
-
const
|
|
294
|
+
const retainedMetadataBytes = (value) => {
|
|
295
|
+
const strings = "rawUrl" in value
|
|
296
|
+
? [value.rawUrl, value.rawUrl, value.executionContextKey, value.cdpHash]
|
|
297
|
+
: [value.contextKey, value.origin];
|
|
298
|
+
return (RETAINED_OBJECT_OVERHEAD_BYTES +
|
|
299
|
+
strings.reduce((total, text) => total + (text?.length ?? 0) * 2, 0));
|
|
300
|
+
};
|
|
265
301
|
const nonnegativeInteger = (value) => {
|
|
266
302
|
const parsed = numberValue(value);
|
|
267
303
|
return parsed === undefined ? 0 : Math.max(0, Math.trunc(parsed));
|
|
@@ -51,8 +51,11 @@ export const runWakaruCommand = async (context) => {
|
|
|
51
51
|
runId,
|
|
52
52
|
cwd: context.cwd,
|
|
53
53
|
hostEnvironment: context.environment,
|
|
54
|
+
...(context.signal === undefined ? {} : { signal: context.signal }),
|
|
54
55
|
env: { TMPDIR: context.cwd, RAYON_NUM_THREADS: "1", NO_COLOR: "1" },
|
|
55
56
|
}).catch((cause) => {
|
|
57
|
+
if (context.signal?.aborted === true)
|
|
58
|
+
throw new AnalysisCancelledError(OPERATION);
|
|
56
59
|
throw new ProviderAdapterError("wakaru", OPERATION, {
|
|
57
60
|
cause,
|
|
58
61
|
diagnostics: {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { TraceMap, decodedMappings } from "@jridgewell/trace-mapping";
|
|
2
|
+
import { SourceMapFormatFailure, } from "./SourceMapFormat.js";
|
|
3
|
+
/** Determine whether a leaf-local mapping falls before its enclosing boundary. */
|
|
4
|
+
export const isBeforeSourceMapLeafStop = (leaf, line, column) => {
|
|
5
|
+
if (leaf.stop === null)
|
|
6
|
+
return true;
|
|
7
|
+
const generatedLine = leaf.offset.line + line;
|
|
8
|
+
const generatedColumn = column + (line === 0 ? leaf.offset.column : 0);
|
|
9
|
+
return (generatedLine < leaf.stop.line ||
|
|
10
|
+
(generatedLine === leaf.stop.line && generatedColumn < leaf.stop.column));
|
|
11
|
+
};
|
|
12
|
+
/** Resolve one declaration with the same pinned upstream implementation used by full maps. */
|
|
13
|
+
export const resolveSourceMapSource = (source, sourceRoot, mapUrl) => {
|
|
14
|
+
const map = new TraceMap({
|
|
15
|
+
version: 3,
|
|
16
|
+
names: [],
|
|
17
|
+
sources: [source ?? ""],
|
|
18
|
+
...(sourceRoot == null ? {} : { sourceRoot }),
|
|
19
|
+
mappings: "",
|
|
20
|
+
}, mapUrl);
|
|
21
|
+
const resolved = map.resolvedSources[0];
|
|
22
|
+
if (resolved === undefined)
|
|
23
|
+
throw new SourceMapFormatFailure("format", "Source-map resolver did not return the requested source identity.");
|
|
24
|
+
return resolved;
|
|
25
|
+
};
|
|
26
|
+
/** Decode leaf mappings and validate producer indices before any consumer publishes them. */
|
|
27
|
+
export const decodeValidatedSourceMapLeaves = (leaves, mapUrl, check) => leaves.map((leaf) => {
|
|
28
|
+
check?.();
|
|
29
|
+
const map = new TraceMap(JSON.stringify(leaf.map), mapUrl);
|
|
30
|
+
const rows = decodedMappings(map);
|
|
31
|
+
for (const [line, row] of rows.entries()) {
|
|
32
|
+
if ((line & 255) === 0)
|
|
33
|
+
check?.();
|
|
34
|
+
for (const segment of row) {
|
|
35
|
+
const generatedLine = leaf.offset.line + line;
|
|
36
|
+
const generatedColumn = segment[0] + (line === 0 ? leaf.offset.column : 0);
|
|
37
|
+
if (!Number.isSafeInteger(generatedLine) ||
|
|
38
|
+
!Number.isSafeInteger(generatedColumn) ||
|
|
39
|
+
![1, 4, 5].includes(segment.length) ||
|
|
40
|
+
segment.some((value) => !Number.isSafeInteger(value) || value < 0) ||
|
|
41
|
+
(segment.length !== 1 && segment[1] >= leaf.map.sources.length) ||
|
|
42
|
+
(segment.length === 5 && segment[4] >= leaf.map.names.length))
|
|
43
|
+
throw new SourceMapFormatFailure("format", "Decoded local or absolute position, source index or name index is invalid.");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { leaf, rows, resolvedSources: map.resolvedSources };
|
|
47
|
+
});
|