rea-agents 3.1.0 → 3.2.1
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 +72 -95
- package/bridge/ghidra/ReaGhidraBridge.java +609 -841
- package/bridge/hopper_bridge.py +99 -344
- package/dist/application/AbortablePromise.js +6 -3
- package/dist/application/AnalysisSnapshotCache.js +0 -1
- package/dist/application/AnalysisSnapshotFiles.js +7 -7
- package/dist/application/AndroidApplicationService.js +1 -1
- package/dist/application/AppleApplicationService.js +1 -1
- package/dist/application/ArtifactExtraction.js +35 -54
- package/dist/application/ArtifactExtractionDestination.js +17 -0
- package/dist/application/ArtifactGraphConstruction.js +2 -17
- package/dist/application/ArtifactInventory/classify.js +2 -6
- package/dist/application/ArtifactInventory/hash.js +2 -20
- package/dist/application/ArtifactInventory/scanCanonical.js +8 -12
- package/dist/application/ArtifactInventory/scanReader.js +69 -51
- package/dist/application/ArtifactInventory.js +6 -14
- package/dist/application/AuthorizedArtifactInventory.js +3 -13
- package/dist/application/BinarySession.js +41 -13
- package/dist/application/BinarySessionComposition.js +0 -11
- package/dist/application/BinarySessionOpen.js +2 -1
- package/dist/application/BinarySessionRecords.js +5 -93
- package/dist/application/BinarySessionStatus.js +5 -16
- package/dist/application/BinaryTargetResolver.js +216 -0
- package/dist/application/BrowserEvidence.js +42 -58
- package/dist/application/BrowserObservationService.js +3 -6
- package/dist/application/BrowserScenarioCaptureService.js +3 -6
- package/dist/application/BrowserScenarioEvidence.js +3 -3
- package/dist/application/CallPathTracing.js +2 -36
- package/dist/application/CapabilityInventory.js +10 -15
- package/dist/application/ClientConfigurationDocument.js +27 -0
- package/dist/application/ClientRegistrationStatus.js +16 -13
- package/dist/application/CommandShimReplay.js +14 -1
- package/dist/application/DirectAnalysis.js +22 -46
- package/dist/application/DirectAnalysisStatus.js +5 -61
- package/dist/application/Doctor.js +11 -32
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/DoctorScope.js +1 -1
- package/dist/application/ElectronActiveEvidence.js +3 -8
- package/dist/application/ElectronActiveObservationService.js +3 -6
- package/dist/application/ElectronBoundaryAnalysis.js +7 -8
- package/dist/application/ElectronBoundaryGraphContext.js +1 -1
- package/dist/application/ElectronBoundaryGraphIpc.js +3 -3
- package/dist/application/ElectronBoundaryGraphNative.js +1 -2
- package/dist/application/ElectronBoundaryGraphWindows.js +6 -8
- package/dist/application/ElectronEvidence.js +4 -7
- package/dist/application/ElectronObservationService.js +5 -9
- package/dist/application/EnhancedLiteralTracing.js +42 -65
- package/dist/application/EnhancedTools.js +76 -44
- package/dist/application/EvidenceBundleCommands.js +11 -11
- package/dist/application/EvidenceBundleFiles.js +9 -15
- package/dist/application/EvidenceLedger.js +6 -41
- package/dist/application/FilesystemSnapshot.js +2 -3
- package/dist/application/InterfaceBuilderAnalysis.js +266 -0
- package/dist/application/InventoryProjectionEvidence.js +4 -2
- package/dist/application/InvestigationProviders.js +1 -1
- package/dist/application/JavaScriptApplicationEvidence.js +2 -5
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +6 -10
- package/dist/application/JavaScriptApplicationService.js +6 -29
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +5 -5
- package/dist/application/JavaScriptApplicationWorkflowService.js +0 -8
- package/dist/application/JavaScriptArtifactAnalysis.js +38 -127
- package/dist/application/JavaScriptArtifactFiles.js +67 -107
- package/dist/application/JavaScriptArtifactGraphAccumulator.js +0 -7
- package/dist/application/JavaScriptArtifactGraphBuilder.js +7 -58
- package/dist/application/JavaScriptArtifactGraphBundlers.js +1 -6
- package/dist/application/JavaScriptArtifactGraphContext.js +12 -39
- package/dist/application/JavaScriptArtifactGraphDocuments.js +4 -11
- package/dist/application/JavaScriptArtifactGraphEvidence.js +0 -14
- package/dist/application/JavaScriptArtifactGraphFindings.js +3 -3
- package/dist/application/JavaScriptArtifactGraphStructure.js +16 -17
- package/dist/application/JavaScriptArtifactPathResolution.js +61 -49
- package/dist/application/JavaScriptArtifactReconstruction.js +5 -10
- package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -14
- package/dist/application/JavaScriptJsonModules.js +2 -2
- package/dist/application/JavaScriptModuleRelationships.js +22 -27
- package/dist/application/JavaScriptReplayPlanning.js +9 -3
- package/dist/application/JavaScriptReplayService.js +6 -32
- package/dist/application/JavaScriptReturnShapeProjection.js +12 -42
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +7 -8
- package/dist/application/JavaScriptRuntimeObservationService.js +4 -8
- package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +2 -3
- package/dist/application/JavaScriptSemanticGraphBuilder.js +11 -41
- package/dist/application/JavaScriptSemanticGraphConstruction.js +5 -29
- package/dist/application/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +1 -1
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +0 -13
- package/dist/application/JavaScriptSemanticGraphProjection.js +1 -3
- package/dist/application/JavaScriptSemanticTraceService.js +1 -10
- package/dist/application/JsonFiles.js +79 -0
- package/dist/application/LinuxHopper.js +11 -9
- package/dist/application/LoopbackReplay.js +26 -23
- package/dist/application/LoopbackReplayRecorder.js +29 -1
- package/dist/application/ManagedApplicationGraphService.js +1 -2
- package/dist/application/ManagedMemberComparisonService.js +11 -41
- package/dist/application/ManagedNativeVerificationService.js +1 -2
- package/dist/application/ManagedReconstructionService.js +1 -1
- package/dist/application/ManagedRuntimeCorrelationService.js +5 -8
- package/dist/application/NativeApiInspection.js +2 -7
- package/dist/application/NativeUiActionTrace.js +394 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +3 -7
- package/dist/application/PermissionAuthority.js +15 -7
- package/dist/application/PermissionFailure.js +5 -0
- package/dist/application/ProcessCaptureAuthority.js +5 -7
- package/dist/application/ProcessCaptureJournal.js +3 -2
- package/dist/application/ProcessCaptureLifecycle.js +5 -12
- package/dist/application/ProcessCheckpoints.js +29 -11
- package/dist/application/ProcessCli.js +6 -16
- package/dist/application/ProcessEvidence.js +5 -7
- package/dist/application/ProcessHarness.js +52 -17
- package/dist/application/ProcessReactiveCoordinator.js +2 -4
- package/dist/application/ProcessReactiveEffects.js +9 -3
- package/dist/application/ProcessReactiveHarness.js +13 -7
- package/dist/application/ProcessSampling.js +2 -4
- package/dist/application/ProcessTimer.js +39 -0
- package/dist/application/ProjectPermissionStore.js +39 -96
- package/dist/application/RealHopperAssertions.js +20 -66
- package/dist/application/ReconstructionCoverageService.js +12 -58
- package/dist/application/ReconstructionObligationAuthority.js +2 -2
- package/dist/application/ReconstructionObligationCandidates.js +4 -4
- package/dist/application/ReconstructionObligationLedgerEvaluation.js +8 -15
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -7
- package/dist/application/ReconstructionObligationLedgerService.js +19 -38
- package/dist/application/ReferenceSourceImport.js +19 -45
- package/dist/application/ReferenceSourceImportEntries.js +2 -4
- package/dist/application/ReferenceSourceImportPolicy.js +5 -32
- package/dist/application/ReferenceSourceImportTypes.js +0 -16
- package/dist/application/RuntimeExecutableDiagnostics.js +55 -29
- package/dist/application/SessionProviderRouter.js +2 -2
- package/dist/application/Setup.js +1 -3
- package/dist/application/SetupClientConfiguration.js +22 -93
- package/dist/application/SetupRegistrationEnvironment.js +0 -7
- package/dist/application/StoreFileLock.js +119 -0
- package/dist/application/TerminalRenderer.js +2 -3
- package/dist/application/Uninstall.js +9 -14
- package/dist/application/UnknownEvidence.js +1 -1
- package/dist/artifacts/ArtifactPaths.js +2 -5
- package/dist/artifacts/ArtifactProvider.js +36 -58
- package/dist/artifacts/DirectoryArtifactReader.js +13 -8
- package/dist/artifacts/MachOSliceArtifactReader.js +1 -5
- package/dist/artifacts/NativeDmgArtifactReader.js +11 -11
- package/dist/artifacts/NibArchive.js +269 -0
- package/dist/artifacts/SafeOutputTree.js +15 -24
- package/dist/browser/BrowserProcessStartup.js +1 -2
- package/dist/browser/CdpAuthorizedMainFrame.js +16 -0
- package/dist/browser/CdpBrowserProvider.js +3 -13
- package/dist/browser/CdpCanonicalJsonDigest.js +9 -0
- package/dist/browser/CdpCaptureDocuments.js +28 -76
- package/dist/browser/CdpCaptureEventBodyShapes.js +13 -33
- package/dist/browser/CdpCaptureEventHandlers.js +22 -87
- package/dist/browser/CdpCaptureEvents.js +2 -8
- package/dist/browser/CdpCaptureStorage.js +9 -20
- package/dist/browser/CdpCaptureStorageFingerprints.js +85 -98
- package/dist/browser/CdpCaptureValues.js +21 -21
- package/dist/browser/CdpConnection.js +10 -25
- package/dist/browser/CdpElectronInspection.js +26 -50
- package/dist/browser/CdpElectronProvider.js +10 -35
- package/dist/browser/CdpElectronScriptEvents.js +8 -16
- package/dist/browser/CdpElectronScripts.js +6 -35
- package/dist/browser/CdpElectronWorkers.js +6 -10
- package/dist/browser/CdpEndpoint.js +25 -41
- package/dist/browser/CdpObservationSession.js +14 -26
- package/dist/browser/CdpPageCapture.js +34 -48
- package/dist/browser/CdpPageCaptureScripts.js +1 -19
- package/dist/browser/CdpPageCaptureWorkers.js +6 -10
- package/dist/browser/CdpSafeMetadata.js +19 -22
- package/dist/browser/CdpScreenshot.js +3 -5
- package/dist/browser/CdpTargetSession.js +1 -2
- package/dist/browser/CdpWebMcpDiscovery.js +13 -22
- package/dist/browser/ElectronFileScope.js +8 -19
- package/dist/browser/JavaScriptRuntimeScope.js +9 -14
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +31 -64
- package/dist/browser/PlaywrightElectronActiveActions.js +54 -69
- package/dist/browser/PlaywrightElectronActiveProvider.js +14 -34
- package/dist/browser/PlaywrightExecutionBoundary.js +16 -5
- package/dist/browser/PlaywrightScenarioActions.js +3 -7
- package/dist/browser/PlaywrightScenarioArtifacts.js +23 -92
- package/dist/browser/PlaywrightScenarioBrowser.js +3 -5
- package/dist/browser/PlaywrightScenarioEvents.js +45 -94
- package/dist/browser/PlaywrightScenarioSession.js +14 -30
- package/dist/browser/PngVisualDiff.js +22 -14
- package/dist/browser/SensitiveTextCapture.js +0 -17
- package/dist/browser/V8InspectorCaptureProjection.js +7 -8
- package/dist/browser/V8InspectorEndpoint.js +12 -14
- package/dist/browser/V8InspectorProvider.js +20 -61
- package/dist/browser/WebSourceMapFetcher.js +56 -176
- package/dist/catalogIdentity.js +0 -54
- package/dist/cli/artifactCommands.js +49 -77
- package/dist/cli/coreAnalysisCommands.js +83 -133
- package/dist/cli/javascriptApplicationAnalysis.js +1 -9
- package/dist/cli/managedCommands.js +5 -270
- package/dist/cli/setupCommands.js +3 -12
- package/dist/cli/utilityCommands.js +7 -41
- package/dist/cli.js +0 -2
- package/dist/cliApplicationCommands.js +42 -112
- package/dist/cliBrowserAdvancedCommands.js +10 -106
- package/dist/cliBrowserCommands.js +15 -127
- package/dist/cliBrowserContext.js +30 -0
- package/dist/cliCommandNames.js +4 -5
- package/dist/cliElectronCommands.js +8 -72
- package/dist/cliEvidenceCommands.js +8 -77
- package/dist/cliJavaScriptRuntimeCommands.js +9 -91
- package/dist/cliJsonInput.js +4 -14
- package/dist/cliObservationOptions.js +11 -96
- package/dist/cliPolicyCommands.js +2 -17
- package/dist/cliProcessCommands.js +3 -3
- package/dist/cliSetup.js +0 -13
- package/dist/config/browserScenario.js +2 -2
- package/dist/config/environment.js +0 -9
- package/dist/config/parseConfig.js +1 -33
- package/dist/config/parsers.js +6 -27
- package/dist/config/passiveObservation.js +7 -77
- package/dist/config/permissions.js +0 -7
- package/dist/contracts/analysisSearchContract.js +2 -5
- package/dist/contracts/applicationToolContracts.js +56 -109
- package/dist/contracts/applicationWorkflowInputContracts.js +27 -102
- package/dist/contracts/artifactComparisonExample.js +58 -60
- package/dist/contracts/artifactToolContracts.js +20 -67
- package/dist/contracts/browserScenarioToolContracts.js +6 -51
- package/dist/contracts/browserToolContracts.js +8 -73
- package/dist/contracts/electronToolContracts.js +8 -108
- package/dist/contracts/enhancedInputs.js +23 -54
- package/dist/contracts/errorSchemas.js +0 -1
- package/dist/contracts/functionComparisonExample.js +10 -24
- package/dist/contracts/functionInstructionContract.js +1 -3
- package/dist/contracts/functionWorkflowToolContracts.js +2 -2
- package/dist/contracts/hopperMemoryContracts.js +3 -3
- package/dist/contracts/investigationExamples.js +14 -11
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +12 -19
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +2 -20
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +45 -12
- package/dist/contracts/managedToolContracts.js +6 -95
- package/dist/contracts/managedWorkflowExamples.js +77 -128
- package/dist/contracts/managedWorkflowToolContracts.js +51 -77
- package/dist/contracts/nativeToolContracts.js +7 -11
- package/dist/contracts/processCaptureExample.js +2 -69
- package/dist/contracts/promptContracts.js +49 -67
- package/dist/contracts/providerSelection.js +0 -1
- package/dist/contracts/reconstructionReadinessExample.js +1 -6
- package/dist/contracts/sessionStatusContract.js +1 -17
- package/dist/contracts/sessionToolSchemas.js +6 -15
- package/dist/contracts/toolContractExamples.js +11 -11
- package/dist/contracts/toolContractHelpers.js +0 -4
- package/dist/contracts/toolContracts.js +60 -71
- package/dist/contracts/toolEffects.js +5 -13
- package/dist/contracts/toolOutputSchemaGroups.js +37 -91
- package/dist/contracts/toolOutputSchemaPrimitives.js +16 -56
- package/dist/contracts/toolSchemaMetadata.js +8 -19
- package/dist/contracts/unknownContractExamples.js +0 -2
- package/dist/domain/analysisErrorPresentation.js +46 -54
- package/dist/domain/analysisErrorProjection.js +28 -37
- package/dist/domain/analysisProfile.js +3 -31
- package/dist/domain/analysisSnapshot.js +3 -12
- package/dist/domain/androidApplication.js +15 -54
- package/dist/domain/appleApplication.js +24 -67
- package/dist/domain/artifactComparison.js +11 -29
- package/dist/domain/artifactGraph.js +14 -44
- package/dist/domain/artifactInspection.js +38 -69
- package/dist/domain/artifactInventoryEvidence.js +27 -21
- package/dist/domain/binaryTarget.js +2 -221
- package/dist/domain/browserCaptureComparison.js +47 -24
- package/dist/domain/browserObservation.js +28 -193
- package/dist/domain/browserObservationSchemas.js +5 -23
- package/dist/domain/browserScenario.js +11 -14
- package/dist/domain/browserScenarioCapture.js +11 -12
- package/dist/domain/browserScenarioCaptureValues.js +146 -84
- package/dist/domain/browserScenarioDiff.js +2 -59
- package/dist/domain/browserScenarioDiffEvidence.js +51 -0
- package/dist/domain/browserScenarioDiffValues.js +21 -38
- package/dist/domain/browserScenarioValues.js +80 -109
- package/dist/domain/browserSession.js +4 -7
- package/dist/domain/bundleComparison.js +6 -32
- package/dist/domain/bytecodeProvider.js +20 -19
- package/dist/domain/callPath.js +47 -167
- package/dist/domain/callPathSchemas.js +79 -0
- package/dist/domain/changedBehavior.js +34 -60
- package/dist/domain/completionLedgerGeneration.js +8 -14
- package/dist/domain/conformancePackage.js +126 -97
- package/dist/domain/conformanceReplay.js +36 -8
- package/dist/domain/conformanceTrustGate.js +23 -14
- package/dist/domain/customProtocolCapture.js +1 -1
- package/dist/domain/electronActiveObservation.js +70 -103
- package/dist/domain/electronObservation.js +14 -80
- package/dist/domain/electronStaticAnalysisBrowser.js +36 -46
- package/dist/domain/electronStaticAnalysisIpc.js +38 -14
- package/dist/domain/electronStaticAnalysisNative.js +1 -8
- package/dist/domain/electronStaticAnalysisValues.js +10 -17
- package/dist/domain/errors.js +33 -54
- package/dist/domain/eventProcessTree.js +20 -12
- package/dist/domain/evidence.js +2 -10
- package/dist/domain/evidenceBundle.js +3 -5
- package/dist/domain/evidenceCompletionLedger.js +6 -8
- package/dist/domain/functionComparison.js +4 -14
- package/dist/domain/functionComparisonNormalization.js +4 -11
- package/dist/domain/functionComparisonResults.js +25 -15
- package/dist/domain/functionComparisonSchemas.js +49 -33
- package/dist/domain/functionDossierEvidence.js +31 -156
- package/dist/domain/hopperStartupFailure.js +1 -1
- package/dist/domain/hopperValues.js +15 -136
- package/dist/domain/interfaceBuilderGraph.js +654 -0
- package/dist/domain/javascriptApplicationAnalysis.js +8 -112
- package/dist/domain/javascriptApplicationChangeGraph.js +22 -82
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +59 -47
- package/dist/domain/javascriptApplicationGraph.js +3 -13
- package/dist/domain/javascriptApplicationGraphSchemas.js +12 -34
- package/dist/domain/javascriptApplicationVersionComparison.js +26 -30
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +123 -68
- package/dist/domain/javascriptApplicationVersionItems.js +120 -53
- package/dist/domain/javascriptApplicationVersionKeys.js +24 -11
- package/dist/domain/javascriptAstFingerprint.js +25 -58
- package/dist/domain/javascriptAstValues.js +9 -0
- package/dist/domain/javascriptExportInstrumentation.js +2 -4
- package/dist/domain/javascriptExportShapeComparison.js +6 -7
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +68 -75
- package/dist/domain/javascriptExportShapeSelection.js +17 -19
- package/dist/domain/javascriptFeatureSeed.js +20 -12
- package/dist/domain/javascriptFeatureTrace.js +13 -67
- package/dist/domain/javascriptFeatureTraceSchemas.js +24 -52
- package/dist/domain/javascriptFeatureTraversal.js +1 -44
- package/dist/domain/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascriptReplay.js +24 -41
- package/dist/domain/javascriptRuntimeLoadState.js +3 -8
- package/dist/domain/javascriptRuntimeObservation.js +42 -103
- package/dist/domain/javascriptRuntimeReconciliation.js +1 -3
- package/dist/domain/javascriptRuntimeReconciliationActive.js +8 -17
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +10 -23
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +18 -12
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +16 -45
- package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -5
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +8 -12
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +33 -48
- package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -3
- package/dist/domain/javascriptSemanticAnalysis.js +12 -45
- package/dist/domain/javascriptSemanticAsyncEffects.js +1 -9
- package/dist/domain/javascriptSemanticCallResolution.js +6 -16
- package/dist/domain/javascriptSemanticCalls.js +5 -32
- package/dist/domain/javascriptSemanticChildProcesses.js +1 -11
- package/dist/domain/javascriptSemanticCoverage.js +11 -0
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +1 -8
- package/dist/domain/javascriptSemanticDataEffects.js +1 -11
- package/dist/domain/javascriptSemanticFingerprints.js +3 -5
- package/dist/domain/javascriptSemanticGraphSchemas.js +25 -51
- package/dist/domain/javascriptSemanticGraphSerialization.js +2 -13
- package/dist/domain/javascriptSemanticIr.js +1 -29
- package/dist/domain/javascriptSemanticObjects.js +1 -5
- package/dist/domain/javascriptSemanticPrimitives.js +2 -9
- package/dist/domain/javascriptSemanticProjection.js +0 -18
- package/dist/domain/javascriptSemanticPromises.js +9 -16
- package/dist/domain/javascriptSemanticProvenance.js +16 -19
- package/dist/domain/javascriptSemanticQuery.js +17 -139
- package/dist/domain/javascriptSemanticQueryAssessment.js +9 -37
- package/dist/domain/javascriptSemanticQueryIdentity.js +2 -23
- package/dist/domain/javascriptSemanticQuerySchemas.js +14 -107
- package/dist/domain/javascriptSemanticResources.js +1 -6
- package/dist/domain/javascriptSemanticReturns.js +10 -27
- package/dist/domain/javascriptSemanticValueTypes.js +1 -0
- package/dist/domain/javascriptSemanticValues.js +44 -62
- package/dist/domain/javascriptStaticAnalysis.js +21 -43
- package/dist/domain/javascriptStaticAnalysisBundler.js +34 -93
- package/dist/domain/javascriptStaticAnalysisCalls.js +17 -16
- package/dist/domain/javascriptStaticAnalysisFindings.js +3 -19
- package/dist/domain/javascriptStaticAnalysisHelpers.js +47 -88
- package/dist/domain/javascriptStaticAnalysisState.js +1 -5
- package/dist/domain/javascriptStaticAnalysisTypes.js +1 -0
- package/dist/domain/jsonShape.js +7 -33
- package/dist/domain/localPath.js +7 -0
- package/dist/domain/managedApplicationGraph.js +9 -41
- package/dist/domain/managedApplicationGraphCoverage.js +24 -156
- package/dist/domain/managedApplicationGraphNodes.js +10 -13
- package/dist/domain/managedArtifact.js +14 -27
- package/dist/domain/managedMemberComparison.js +90 -92
- package/dist/domain/managedMemberComparisonCoverage.js +11 -33
- package/dist/domain/managedMemberComparisonItems.js +221 -0
- package/dist/domain/managedMemberComparisonMatch.js +8 -208
- package/dist/domain/managedNativeVerification.js +3 -6
- package/dist/domain/managedNativeVerificationMatch.js +55 -59
- package/dist/domain/managedNativeVerificationSchemas.js +83 -47
- package/dist/domain/managedReconstruction.js +19 -23
- package/dist/domain/managedRuntimeCorrelation.js +6 -9
- package/dist/domain/nativeApiBoundary.js +2 -7
- package/dist/domain/nativeInspection.js +0 -2
- package/dist/domain/nativeInvestigationGraph.js +351 -0
- package/dist/domain/nativeValueFlow.js +61 -0
- package/dist/domain/nodeRuntimeCharacterization.js +1 -5
- package/dist/domain/objcSwiftMetadata.js +254 -0
- package/dist/domain/peInspection.js +1 -1
- package/dist/domain/permissionPolicy.js +13 -0
- package/dist/domain/processCapture.js +76 -113
- package/dist/domain/processCaptureExample.js +68 -0
- package/dist/domain/processCaptureParsing.js +21 -0
- package/dist/domain/processCaptureReactiveSchema.js +68 -0
- package/dist/domain/processCaptureValidation.js +1 -7
- package/dist/domain/processComparison.js +3 -12
- package/dist/domain/processReactiveMatching.js +29 -50
- package/dist/domain/processReactiveRuntime.js +4 -8
- package/dist/domain/processReactiveScenario.js +28 -94
- package/dist/domain/processReactiveScenarioPreflight.js +5 -30
- package/dist/domain/processReactiveTransition.js +33 -18
- package/dist/domain/processScenario.js +56 -90
- package/dist/domain/processTraceComparison.js +0 -8
- package/dist/domain/processTraceEvaluation.js +14 -4
- package/dist/domain/processTraceSpecification.js +11 -17
- package/dist/domain/protocolCapture.js +3 -3
- package/dist/domain/reconstructionCoverage.js +62 -129
- package/dist/domain/reconstructionCoverageEvaluation.js +17 -17
- package/dist/domain/reconstructionObligationLedgerSchemas.js +45 -72
- package/dist/domain/reconstructionReadiness.js +1 -2
- package/dist/domain/reconstructionReadinessSchemas.js +36 -38
- package/dist/domain/reconstructionUnknowns.js +3 -3
- package/dist/domain/reconstructionVerification.js +13 -47
- package/dist/domain/reconstructionVerificationSchemas.js +50 -38
- package/dist/domain/referenceSourceGraph.js +53 -61
- package/dist/domain/referenceSourceImportParsing.js +1 -5
- package/dist/domain/replayMachine.js +19 -31
- package/dist/domain/replayMachineRun.js +15 -63
- package/dist/domain/replayMachineRuntime.js +41 -41
- package/dist/domain/replayMachineValues.js +84 -0
- package/dist/domain/residualUnknown.js +25 -30
- package/dist/domain/runtimeCharacterization.js +15 -16
- package/dist/domain/runtimeIdentification.js +48 -47
- package/dist/domain/sourceToBundleComparison.js +9 -85
- package/dist/domain/sourceToBundleComparisonSchemas.js +17 -42
- package/dist/domain/sourceToBundleSignals.js +4 -15
- package/dist/domain/staticRuntimeCorrelation.js +37 -49
- package/dist/domain/symbolAnalysis.js +10 -19
- package/dist/domain/unicodeCodePointOrder.js +12 -0
- package/dist/domain/webBundleAnalysis.js +70 -99
- package/dist/domain/webBundleAnalyzer.js +2 -4
- package/dist/domain/webBundleAnalyzerAst.js +0 -13
- package/dist/domain/webBundleAnalyzerInspection.js +26 -52
- package/dist/domain/webBundleAnalyzerResult.js +7 -24
- package/dist/domain/webCaptureDiff.js +33 -73
- package/dist/domain/webCaptureDiffSchemas.js +86 -0
- package/dist/domain/webContentArtifact.js +1 -10
- package/dist/domain/webMcpDiscovery.js +3 -14
- package/dist/domain/webScreenshot.js +58 -34
- package/dist/domain/zipPackageFormat.js +7 -0
- package/dist/dotnet/ManagedArtifactInspector.js +17 -50
- package/dist/dotnet/ManagedMemberInspector.js +27 -58
- package/dist/dotnet/ManagedMemberInspectorCore.js +14 -51
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +2 -2
- package/dist/dotnet/ManagedMemberRows.js +16 -16
- package/dist/dotnet/ManagedMetadataHeaps.js +26 -8
- package/dist/dotnet/ManagedMetadataInventory.js +21 -30
- package/dist/dotnet/ManagedMetadataInventoryRows.js +57 -63
- package/dist/dotnet/ManagedMetadataLayout.js +3 -5
- package/dist/dotnet/ManagedMethodBodyReader.js +5 -30
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +19 -49
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +13 -41
- package/dist/dotnet/ManagedPeReader.js +2 -2
- package/dist/dotnet/ManagedStaticProvider.js +13 -71
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraAnalysisProfile.js +3 -8
- package/dist/ghidra/GhidraClient.js +4 -12
- package/dist/ghidra/GhidraClientWire.js +9 -5
- package/dist/ghidra/GhidraDefaults.js +0 -18
- package/dist/ghidra/GhidraDiagnostics.js +0 -2
- package/dist/ghidra/GhidraDoctor.js +16 -12
- package/dist/ghidra/GhidraFunctionValues.js +65 -108
- package/dist/ghidra/GhidraInstallation.js +98 -42
- package/dist/ghidra/GhidraInventoryValues.js +16 -85
- package/dist/ghidra/GhidraLauncher.js +0 -8
- package/dist/ghidra/GhidraProvider.js +15 -22
- package/dist/ghidra/GhidraProviderCapabilities.js +6 -47
- package/dist/ghidra/GhidraRequestQueue.js +6 -30
- package/dist/ghidra/GhidraResponseBuffer.js +1 -7
- package/dist/ghidra/GhidraSessionValues.js +0 -2
- package/dist/ghidra/GhidraTransport.js +4 -7
- package/dist/ghidra/protocol.js +2 -2
- package/dist/hopper/BridgeLauncher.js +112 -36
- package/dist/hopper/HopperAnalysisProfile.js +1 -1
- package/dist/hopper/HopperCleanup.js +6 -3
- package/dist/hopper/HopperClient.js +4 -7
- package/dist/hopper/HopperProcessDiagnostic.js +2 -2
- package/dist/hopper/HopperProvider.js +0 -16
- package/dist/hopper/HopperRequestQueue.js +21 -40
- package/dist/hopper/HopperResponseStream.js +1 -9
- package/dist/hopper/HopperSessionValues.js +3 -2
- package/dist/hopper/HopperTargetLease.js +119 -0
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +24 -31
- package/dist/hopper/LinuxPrivateDisplayProbe.js +5 -16
- package/dist/hopper/protocol.js +6 -4
- package/dist/main/reload.js +0 -3
- package/dist/main/shutdown.js +1 -1
- package/dist/main/state.js +0 -9
- package/dist/main/transport.js +0 -5
- package/dist/mcpDoctor.js +25 -45
- package/dist/native/CommandRunner.js +18 -25
- package/dist/native/NativeMacOSProvider.js +13 -38
- package/dist/native/NativeMachoInspection.js +1 -1
- package/dist/process/BoundedFileBytes.js +17 -0
- package/dist/process/ExecFileOutput.js +11 -0
- package/dist/process/PendingOperations.js +8 -6
- package/dist/process/ProcessOwnership.js +3 -2
- package/dist/process/ProcessOwnershipObservation.js +0 -1
- package/dist/process/ProviderProcess.js +7 -28
- package/dist/reference/ReferenceSourceReader.js +8 -24
- package/dist/reference/ReferenceSourceReaderEntries.js +11 -39
- package/dist/reference/ReferenceSourceReaderFile.js +13 -31
- package/dist/reference/ReferenceSourceReaderPaths.js +3 -18
- package/dist/reference/ReferenceSourceReaderValidate.js +3 -6
- package/dist/replay/JavaScriptReplayWorker.js +3 -5
- package/dist/replay/LinuxJavaScriptReplayRunner.js +33 -29
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -19
- package/dist/replay/LinuxRuntimeClosure.js +1 -3
- package/dist/replay/ReplayOutcome.js +1 -3
- package/dist/replay/ReplayProcessLifecycle.js +32 -7
- package/dist/replay/ReplaySeccompFile.js +29 -0
- package/dist/replay/ReplayWorkerProtocol.js +0 -2
- package/dist/replay/SystemJavaScriptReplayHost.js +45 -74
- package/dist/server/ProcessCaptureElicitation.js +4 -8
- package/dist/server/createServer.js +6 -44
- package/dist/server/promptCompletion.js +37 -61
- package/dist/server/recordDerivedEvidence.js +1 -1
- package/dist/server/registerApplicationTools/characterization.js +4 -8
- package/dist/server/registerApplicationTools/compareExportShapes.js +5 -10
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +6 -10
- package/dist/server/registerApplicationTools/compareVersions.js +5 -10
- package/dist/server/registerApplicationTools/controlledReplay.js +3 -5
- package/dist/server/registerApplicationTools/coverage.js +6 -71
- package/dist/server/registerApplicationTools/helpers.js +1 -13
- package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
- package/dist/server/registerApplicationTools/traceFeature.js +5 -9
- package/dist/server/registerApplicationTools/traceSemantics.js +5 -8
- package/dist/server/registerApplicationTools.js +0 -2
- package/dist/server/registerArtifactComparisonTool.js +23 -27
- package/dist/server/registerBrowserScenarioTool.js +4 -4
- package/dist/server/registerBrowserTools.js +5 -8
- package/dist/server/registerBundleComparisonTool.js +5 -7
- package/dist/server/registerCloseLifecycleTool.js +2 -16
- package/dist/server/registerElectronTools.js +10 -29
- package/dist/server/registerEnhancedTools.js +10 -11
- package/dist/server/registerEvidenceTools.js +15 -22
- package/dist/server/registerFunctionComparisonTool.js +30 -25
- package/dist/server/registerInvestigationTools/helpers.js +3 -32
- package/dist/server/registerInvestigationTools.js +20 -116
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -4
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +15 -17
- package/dist/server/registerManagedWorkflowTools/evidence.js +19 -35
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +10 -14
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +9 -15
- package/dist/server/registerOfficialTools.js +1 -43
- package/dist/server/registerProcessComparisonTool.js +33 -23
- package/dist/server/registerPrompts.js +19 -17
- package/dist/server/registerSessionRecordTools.js +10 -156
- package/dist/server/registerSessionStatusTool.js +6 -69
- package/dist/server/registerSessionTools.js +10 -51
- package/dist/server/sessionAvailabilityPolicy.js +0 -2
- package/dist/server/sessionEvidence.js +9 -15
- package/dist/server/sessionToolPolicies.js +0 -8
- package/dist/server/toolResult.js +14 -50
- package/dist/serverIdentity.js +0 -20
- package/install.sh +1 -1
- package/package.json +11 -7
- package/scripts/electron-active-hook.cjs +23 -55
- package/scripts/hopper-demo-x11.py +13 -32
- package/skills/reverse-engineer-anything/SKILL.md +47 -12
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +6 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +13 -13
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +12 -8
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +0 -188
- package/dist/application/BoundedJsonFiles.js +0 -86
- package/dist/application/CrossVersionInventory.js +0 -129
- package/dist/application/CrossVersionInvestigation.js +0 -301
- package/dist/application/CrossVersionInvestigationCollections.js +0 -23
- package/dist/application/CrossVersionInvestigationEvidence.js +0 -64
- package/dist/application/CrossVersionInvestigationReplay.js +0 -170
- package/dist/application/DeferredFileAuthorization.js +0 -61
- package/dist/application/DoctorProjection.js +0 -43
- package/dist/application/EnhancedToolPagination.js +0 -22
- package/dist/application/EvidenceReferenceResolver.js +0 -26
- package/dist/application/InvestigationWorkspaceStore.js +0 -204
- package/dist/application/ProcessPairedExperiment.js +0 -72
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +0 -31
- package/dist/application/ReconstructionReadinessService.js +0 -48
- package/dist/cliInvestigationCommands.js +0 -173
- package/dist/domain/boundedCartesianProjection.js +0 -15
- package/dist/domain/investigationWorkspace.js +0 -347
- package/dist/domain/jsonLimits.js +0 -26
- package/dist/domain/knownPageCoverage.js +0 -29
- package/dist/domain/processPairedExperiment.js +0 -128
- package/dist/server/javascriptApplicationResult.js +0 -106
- package/dist/server/permissionFailure.js +0 -12
- package/dist/server/registerApplicationTools/readiness.js +0 -50
- package/dist/server/registerEvidenceResources.js +0 -315
- package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -65
- package/dist/server/registerReconstructionObligationLedgerResource.js +0 -32
- package/dist/server/registerReconstructionReadinessResource.js +0 -32
|
@@ -7,7 +7,7 @@ export const UNKNOWN_REGISTRY_PROVIDER = {
|
|
|
7
7
|
};
|
|
8
8
|
/** Create immutable evidence for one approved residual-unknown mutation. */
|
|
9
9
|
export const unknownMutationEvidence = (target, input) => createEvidence(target, UNKNOWN_REGISTRY_PROVIDER, {
|
|
10
|
-
predicateType: "rea.residual-unknown-mutation
|
|
10
|
+
predicateType: "rea.residual-unknown-mutation",
|
|
11
11
|
operation: "record_unknown",
|
|
12
12
|
parameters: { domain: input.domain, severity: input.severity },
|
|
13
13
|
result: {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { Buffer } from "node:buffer";
|
|
2
1
|
import { posix } from "node:path";
|
|
3
|
-
import { ArtifactReaderFailure
|
|
2
|
+
import { ArtifactReaderFailure } from "./ArtifactReader.js";
|
|
4
3
|
const DRIVE_OR_UNC = /^(?:[A-Za-z]:|\\|\/\/)/u;
|
|
5
4
|
/** Normalize an untrusted logical archive path without touching filesystem. */
|
|
6
|
-
export const normalizeArtifactPath = (input
|
|
5
|
+
export const normalizeArtifactPath = (input) => {
|
|
7
6
|
if (input.includes("\0") ||
|
|
8
7
|
input.includes("\\") ||
|
|
9
8
|
input.startsWith("/") ||
|
|
@@ -13,8 +12,6 @@ export const normalizeArtifactPath = (input, limits) => {
|
|
|
13
12
|
const parts = normalized.split("/");
|
|
14
13
|
if (normalized.length === 0 ||
|
|
15
14
|
parts.some((part) => part === "" || part === "." || part === "..") ||
|
|
16
|
-
parts.length > limits.maxDepth ||
|
|
17
|
-
Buffer.byteLength(normalized, "utf8") > limits.maxPathBytes ||
|
|
18
15
|
posix.normalize(normalized) !== normalized)
|
|
19
16
|
throw new ArtifactReaderFailure("path", "Artifact path is not normalized");
|
|
20
17
|
return normalized;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
2
2
|
import { inventoryArtifact } from "../application/ArtifactInventory.js";
|
|
3
3
|
import { extractArtifact } from "../application/ArtifactExtraction.js";
|
|
4
|
-
import {
|
|
4
|
+
import { analyzeInterfaceBuilderBundle } from "../application/InterfaceBuilderAnalysis.js";
|
|
5
|
+
import { ARTIFACT_ANALYSIS_OPERATIONS, artifactInventoryInputSchema, artifactExtractionExecutionSchema, } from "../contracts/artifactToolContracts.js";
|
|
5
6
|
import { AnalysisCapabilityUnavailableError, ArtifactOperationError, } from "../domain/errors.js";
|
|
7
|
+
import { interfaceBuilderLimitsSchema } from "../domain/interfaceBuilderGraph.js";
|
|
6
8
|
import { err, ok } from "../domain/result.js";
|
|
7
|
-
import { ArtifactReaderFailure
|
|
9
|
+
import { ArtifactReaderFailure } from "./ArtifactReader.js";
|
|
8
10
|
import { ARTIFACT_GRAPH_PROVIDER } from "../application/InvestigationProviders.js";
|
|
9
11
|
import { createEvidence } from "../domain/evidence.js";
|
|
10
12
|
import { createArtifactInspection } from "../domain/artifactInspection.js";
|
|
@@ -18,31 +20,20 @@ export class ArtifactProvider {
|
|
|
18
20
|
this.nativeMountEnabled = nativeMountEnabled;
|
|
19
21
|
this.integrityContinueEnabled = integrityContinueEnabled;
|
|
20
22
|
}
|
|
21
|
-
#capabilities = Object.freeze(
|
|
23
|
+
#capabilities = Object.freeze(ARTIFACT_ANALYSIS_OPERATIONS.map((operation) => Object.freeze({
|
|
22
24
|
provider: IDENTITY,
|
|
23
|
-
operation
|
|
24
|
-
inputContractVersion: 1,
|
|
25
|
-
outputContractVersion: 1,
|
|
25
|
+
operation,
|
|
26
26
|
available: true,
|
|
27
27
|
reason: null,
|
|
28
|
-
pagination: contract.name === "inspect_artifact"
|
|
29
|
-
? "none"
|
|
30
|
-
: "offset",
|
|
31
|
-
exhaustive: false,
|
|
32
28
|
effects: Object.freeze({
|
|
33
29
|
mutatesArtifact: false,
|
|
34
|
-
launchesProcess:
|
|
30
|
+
launchesProcess: operation !== "decode_interface_builder",
|
|
35
31
|
mayShowUi: false,
|
|
36
32
|
mayAccessNetwork: false,
|
|
37
|
-
mayWriteFilesystem:
|
|
33
|
+
mayWriteFilesystem: operation === "extract_artifact",
|
|
38
34
|
changesPermissions: false,
|
|
39
35
|
requiresRoot: false,
|
|
40
36
|
}),
|
|
41
|
-
limits: Object.freeze({
|
|
42
|
-
maxResults: 500,
|
|
43
|
-
maxPayloadBytes: 4 * 1024 * 1024,
|
|
44
|
-
timeoutMs: 120_000,
|
|
45
|
-
}),
|
|
46
37
|
limitations: Object.freeze([
|
|
47
38
|
"DMG child inventory is macOS-only and requires per-call approval plus operator policy; PKG remains root-hash-only.",
|
|
48
39
|
"ASAR files discovered in filesystem-backed inventories are expanded without bulk extraction; other nested containers remain recorded only.",
|
|
@@ -77,22 +68,38 @@ class ArtifactClient {
|
|
|
77
68
|
const inspected = await this.inspectArtifact(parameters, options);
|
|
78
69
|
return inspected;
|
|
79
70
|
}
|
|
71
|
+
if (operation === "decode_interface_builder") {
|
|
72
|
+
if (this.target.kind !== "executable" ||
|
|
73
|
+
this.target.sourcePath === undefined ||
|
|
74
|
+
!this.target.sourcePath.toLowerCase().endsWith(".app"))
|
|
75
|
+
throw new ArtifactReaderFailure("unavailable", "decode_interface_builder requires an active .app bundle target");
|
|
76
|
+
const limits = interfaceBuilderLimitsSchema.parse(parameters);
|
|
77
|
+
const result = await analyzeInterfaceBuilderBundle({
|
|
78
|
+
bundlePath: this.target.sourcePath,
|
|
79
|
+
targetSha256: this.target.sha256,
|
|
80
|
+
limits,
|
|
81
|
+
...(options?.signal === undefined ? {} : { signal: options.signal }),
|
|
82
|
+
});
|
|
83
|
+
return ok(createAnalysisExecution(result, IDENTITY, {
|
|
84
|
+
limitations: result.limitations,
|
|
85
|
+
locations: result.documents.map(({ relative_path: path }) => ({
|
|
86
|
+
kind: "artifact-path",
|
|
87
|
+
path,
|
|
88
|
+
})),
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
80
91
|
if (operation === "extract_artifact") {
|
|
81
|
-
const parsed =
|
|
92
|
+
const parsed = artifactExtractionExecutionSchema.parse(parameters);
|
|
82
93
|
const result = await extractArtifact({
|
|
83
94
|
inputPath: this.target.sourcePath ?? this.target.path,
|
|
84
95
|
inputFormat: this.target.format,
|
|
85
96
|
outputRoot: parsed.output_root,
|
|
86
|
-
occurrenceIds: parsed.occurrence_ids,
|
|
87
|
-
offset: parsed.offset,
|
|
88
|
-
limit: parsed.limit,
|
|
89
|
-
limits: limitsFrom(parsed),
|
|
90
97
|
}, options?.signal);
|
|
91
98
|
return ok(createAnalysisExecution(result, IDENTITY, {
|
|
92
99
|
rawResult: null,
|
|
93
100
|
limitations: result.limitations,
|
|
94
101
|
subject: subjectFor(this.target.sourcePath ?? this.target.path, result.manifest),
|
|
95
|
-
locations: result.artifacts.
|
|
102
|
+
locations: result.artifacts.map(({ relative_path: path }) => ({
|
|
96
103
|
kind: "artifact-path",
|
|
97
104
|
path,
|
|
98
105
|
})),
|
|
@@ -104,7 +111,7 @@ class ArtifactClient {
|
|
|
104
111
|
rawResult: null,
|
|
105
112
|
limitations: result.limitations,
|
|
106
113
|
subject: subjectFor(this.target.sourcePath ?? this.target.path, result.manifest),
|
|
107
|
-
locations: result.occurrences.
|
|
114
|
+
locations: result.occurrences.map(({ logical_path: path }) => ({
|
|
108
115
|
kind: "artifact-path",
|
|
109
116
|
path,
|
|
110
117
|
})),
|
|
@@ -118,24 +125,11 @@ class ArtifactClient {
|
|
|
118
125
|
return Promise.resolve();
|
|
119
126
|
}
|
|
120
127
|
async inspectArtifact(parameters, options) {
|
|
121
|
-
const parsed =
|
|
128
|
+
const parsed = artifactInventoryInputSchema.parse(parameters);
|
|
122
129
|
const inventoryParameters = artifactInventoryInputSchema.parse({
|
|
123
|
-
node_offset: 0,
|
|
124
|
-
node_limit: parsed.max_observations,
|
|
125
|
-
occurrence_offset: 0,
|
|
126
|
-
occurrence_limit: parsed.max_observations,
|
|
127
|
-
edge_offset: 0,
|
|
128
|
-
edge_limit: parsed.max_relationships,
|
|
129
130
|
native_mount_approved: parsed.native_mount_approved,
|
|
130
131
|
integrity_policy: parsed.integrity_policy,
|
|
131
132
|
integrity_continue_approved: parsed.integrity_continue_approved,
|
|
132
|
-
max_integrity_mismatches: parsed.max_integrity_mismatches,
|
|
133
|
-
max_entries: parsed.max_entries,
|
|
134
|
-
max_total_bytes: parsed.max_total_bytes,
|
|
135
|
-
max_entry_bytes: parsed.max_entry_bytes,
|
|
136
|
-
max_compression_ratio: parsed.max_compression_ratio,
|
|
137
|
-
max_depth: parsed.max_depth,
|
|
138
|
-
max_path_bytes: parsed.max_path_bytes,
|
|
139
133
|
});
|
|
140
134
|
await options?.progress?.report({
|
|
141
135
|
phase: "inspect_artifact.inventory",
|
|
@@ -145,7 +139,7 @@ class ArtifactClient {
|
|
|
145
139
|
});
|
|
146
140
|
const inventory = await this.inventory(inventoryParameters, options);
|
|
147
141
|
const subject = subjectFor(this.target.sourcePath ?? this.target.path, inventory.manifest);
|
|
148
|
-
const locations = inventory.occurrences.
|
|
142
|
+
const locations = inventory.occurrences.map(({ logical_path: path }) => ({
|
|
149
143
|
kind: "artifact-path",
|
|
150
144
|
path,
|
|
151
145
|
}));
|
|
@@ -157,7 +151,7 @@ class ArtifactClient {
|
|
|
157
151
|
limitations: inventory.limitations,
|
|
158
152
|
locations,
|
|
159
153
|
});
|
|
160
|
-
const result = createArtifactInspection(inventoryEvidence
|
|
154
|
+
const result = createArtifactInspection(inventoryEvidence);
|
|
161
155
|
await options?.progress?.report({
|
|
162
156
|
phase: "inspect_artifact.inventory",
|
|
163
157
|
completed: 1,
|
|
@@ -172,34 +166,18 @@ class ArtifactClient {
|
|
|
172
166
|
}));
|
|
173
167
|
}
|
|
174
168
|
inventory(parsed, options) {
|
|
175
|
-
return inventoryArtifact(this.target.sourcePath ?? this.target.path,
|
|
176
|
-
nodeOffset: parsed.node_offset,
|
|
177
|
-
nodeLimit: parsed.node_limit,
|
|
178
|
-
occurrenceOffset: parsed.occurrence_offset,
|
|
179
|
-
occurrenceLimit: parsed.occurrence_limit,
|
|
180
|
-
edgeOffset: parsed.edge_offset,
|
|
181
|
-
edgeLimit: parsed.edge_limit,
|
|
182
|
-
}, {
|
|
169
|
+
return inventoryArtifact(this.target.sourcePath ?? this.target.path, {
|
|
183
170
|
...(options?.signal === undefined ? {} : { signal: options.signal }),
|
|
184
171
|
nativeMount: resolveNativeMountPolicy(parsed.native_mount_approved === true, this.nativeMountEnabled),
|
|
185
172
|
integrity: resolveArtifactIntegrityPolicy(parsed.integrity_policy === "fail"
|
|
186
173
|
? { mode: "fail" }
|
|
187
174
|
: {
|
|
188
175
|
mode: parsed.integrity_policy,
|
|
189
|
-
maxMismatches: parsed.max_integrity_mismatches,
|
|
190
176
|
}, this.integrityContinueEnabled),
|
|
191
177
|
});
|
|
192
178
|
}
|
|
193
179
|
}
|
|
194
|
-
const
|
|
195
|
-
maxEntries: input.max_entries,
|
|
196
|
-
maxTotalBytes: input.max_total_bytes,
|
|
197
|
-
maxEntryBytes: input.max_entry_bytes,
|
|
198
|
-
maxCompressionRatio: input.max_compression_ratio,
|
|
199
|
-
maxDepth: input.max_depth,
|
|
200
|
-
maxPathBytes: input.max_path_bytes,
|
|
201
|
-
});
|
|
202
|
-
const isArtifactOperation = (operation) => ARTIFACT_TOOL_CONTRACTS.some(({ name }) => name === operation);
|
|
180
|
+
const isArtifactOperation = (operation) => ARTIFACT_ANALYSIS_OPERATIONS.includes(operation);
|
|
203
181
|
const translateFailure = (operation, cause) => {
|
|
204
182
|
if (cause instanceof ArtifactReaderFailure)
|
|
205
183
|
return new ArtifactOperationError(operation, cause.reason, cause.details);
|
|
@@ -74,15 +74,20 @@ export class DirectoryArtifactReader {
|
|
|
74
74
|
if (entry.kind !== "file")
|
|
75
75
|
throw new ArtifactReaderFailure("format", "Only regular files can be opened");
|
|
76
76
|
const handle = await open(entry.adapterKey, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
try {
|
|
78
|
+
const observed = await handle.stat();
|
|
79
|
+
if (!observed.isFile() ||
|
|
80
|
+
entry.sourceIdentity === undefined ||
|
|
81
|
+
observed.dev !== entry.sourceIdentity.device ||
|
|
82
|
+
observed.ino !== entry.sourceIdentity.inode) {
|
|
83
|
+
throw new ArtifactReaderFailure("integrity", `Directory entry changed before open: ${entry.path}`);
|
|
84
|
+
}
|
|
85
|
+
return handle.createReadStream({ autoClose: true });
|
|
86
|
+
}
|
|
87
|
+
catch (cause) {
|
|
88
|
+
await handle.close().catch(() => undefined);
|
|
89
|
+
throw cause;
|
|
84
90
|
}
|
|
85
|
-
return handle.createReadStream({ autoClose: true });
|
|
86
91
|
}
|
|
87
92
|
close() {
|
|
88
93
|
return Promise.resolve();
|
|
@@ -13,11 +13,7 @@ export class MachOSliceArtifactReader {
|
|
|
13
13
|
this.runner = runner;
|
|
14
14
|
}
|
|
15
15
|
async *entries(signal) {
|
|
16
|
-
const captured = await this.runner.run("lipo", ["-detailed_info", this.path], {
|
|
17
|
-
...(signal === undefined ? {} : { signal }),
|
|
18
|
-
timeoutMs: 30_000,
|
|
19
|
-
maxOutputBytes: 4 * 1024 * 1024,
|
|
20
|
-
});
|
|
16
|
+
const captured = await this.runner.run("lipo", ["-detailed_info", this.path], signal === undefined ? {} : { signal });
|
|
21
17
|
if (!captured.ok)
|
|
22
18
|
throw new ArtifactReaderFailure(captured.error.reason === "cancelled" ? "cancelled" : "unavailable", "lipo could not enumerate universal Mach-O slices", { cause: captured.error });
|
|
23
19
|
this.#command = {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
1
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
2
|
import { tmpdir } from "node:os";
|
|
4
3
|
import { basename, join } from "node:path";
|
|
5
|
-
import { promisify } from "node:util";
|
|
6
4
|
import { parse } from "plist";
|
|
7
5
|
import { z } from "zod";
|
|
8
6
|
import { ArtifactReaderFailure, } from "./ArtifactReader.js";
|
|
9
7
|
import { DirectoryArtifactReader } from "./DirectoryArtifactReader.js";
|
|
10
|
-
|
|
8
|
+
import { execFileOutput } from "../process/ExecFileOutput.js";
|
|
9
|
+
const DETACH_TIMEOUT_MS = 120_000;
|
|
11
10
|
const attachOutputSchema = z.object({
|
|
12
11
|
"system-entities": z.array(z.object({
|
|
13
12
|
"dev-entry": z.string().startsWith("/dev/"),
|
|
@@ -15,11 +14,10 @@ const attachOutputSchema = z.object({
|
|
|
15
14
|
})),
|
|
16
15
|
});
|
|
17
16
|
const systemHost = {
|
|
18
|
-
async run(arguments_, signal) {
|
|
17
|
+
async run(arguments_, signal, options) {
|
|
19
18
|
try {
|
|
20
|
-
const { stdout } = await
|
|
21
|
-
|
|
22
|
-
timeout: 120_000,
|
|
19
|
+
const { stdout } = await execFileOutput("/usr/bin/hdiutil", [...arguments_], {
|
|
20
|
+
...(options === undefined ? {} : { timeout: options.timeoutMs }),
|
|
23
21
|
...(signal === undefined ? {} : { signal }),
|
|
24
22
|
});
|
|
25
23
|
return { stdout, exitCode: 0 };
|
|
@@ -48,7 +46,7 @@ export class NativeDmgArtifactReader {
|
|
|
48
46
|
}
|
|
49
47
|
/** Verify and attach one image beneath an exclusively owned temporary root. */
|
|
50
48
|
static async create(path, signal, host = systemHost) {
|
|
51
|
-
if (process.platform !== "darwin")
|
|
49
|
+
if (process.platform !== "darwin" && host === systemHost)
|
|
52
50
|
throw new ArtifactReaderFailure("unavailable", "Native DMG traversal is available only on macOS");
|
|
53
51
|
const reader = new NativeDmgArtifactReader(path, host);
|
|
54
52
|
await reader.attach(signal);
|
|
@@ -73,7 +71,9 @@ export class NativeDmgArtifactReader {
|
|
|
73
71
|
let detachFailure;
|
|
74
72
|
for (const device of [...this.#devices].reverse()) {
|
|
75
73
|
try {
|
|
76
|
-
await runChecked(this.host, ["detach", device]
|
|
74
|
+
await runChecked(this.host, ["detach", device], undefined, {
|
|
75
|
+
timeoutMs: DETACH_TIMEOUT_MS,
|
|
76
|
+
});
|
|
77
77
|
this.#provenance.push(command(["detach", device], ["mount"]));
|
|
78
78
|
}
|
|
79
79
|
catch (cause) {
|
|
@@ -135,8 +135,8 @@ export class NativeDmgArtifactReader {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
const runChecked = async (host, arguments_, signal) => {
|
|
139
|
-
const result = await host.run(arguments_, signal);
|
|
138
|
+
const runChecked = async (host, arguments_, signal, options) => {
|
|
139
|
+
const result = await host.run(arguments_, signal, options);
|
|
140
140
|
if (result.exitCode !== 0)
|
|
141
141
|
throw new ArtifactReaderFailure("unavailable", `hdiutil ${arguments_[0] ?? "operation"} failed with a non-zero exit code`);
|
|
142
142
|
return { stdout: result.stdout, exitCode: 0 };
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { TextDecoder } from "node:util";
|
|
2
|
+
const MAGIC = Buffer.from("NIBArchive", "ascii");
|
|
3
|
+
const MAX_RECORDS = 1_000_000;
|
|
4
|
+
/** Decode Apple's length-prefixed NIBArchive representation without loading UI classes. */
|
|
5
|
+
export const decodeNibArchive = (bytes) => {
|
|
6
|
+
if (bytes.length < 50 || !bytes.subarray(0, MAGIC.length).equals(MAGIC))
|
|
7
|
+
throw new TypeError("NIBArchive magic or header is invalid");
|
|
8
|
+
const formatVersion = readU32(bytes, 10);
|
|
9
|
+
const coderVersion = readU32(bytes, 14);
|
|
10
|
+
if (formatVersion !== 1)
|
|
11
|
+
throw new TypeError(`Unsupported NIBArchive format version ${formatVersion}`);
|
|
12
|
+
const objectCount = readCount(bytes, 18, "object");
|
|
13
|
+
const objectsOffset = readOffset(bytes, 22, bytes.length, "object");
|
|
14
|
+
const keyCount = readCount(bytes, 26, "key");
|
|
15
|
+
const keysOffset = readOffset(bytes, 30, bytes.length, "key");
|
|
16
|
+
const valueCount = readCount(bytes, 34, "value");
|
|
17
|
+
const valuesOffset = readOffset(bytes, 38, bytes.length, "value");
|
|
18
|
+
const classCount = readCount(bytes, 42, "class");
|
|
19
|
+
const classesOffset = readOffset(bytes, 46, bytes.length, "class");
|
|
20
|
+
assertOrderedOffsets(bytes.length, [
|
|
21
|
+
objectsOffset,
|
|
22
|
+
keysOffset,
|
|
23
|
+
valuesOffset,
|
|
24
|
+
classesOffset,
|
|
25
|
+
]);
|
|
26
|
+
const objectRecords = parseObjects(bytes, objectsOffset, keysOffset, objectCount, valueCount, classCount);
|
|
27
|
+
const keys = parseStrings(bytes, keysOffset, valuesOffset, keyCount, "key");
|
|
28
|
+
const classes = parseClasses(bytes, classesOffset, bytes.length, classCount);
|
|
29
|
+
const neededValues = valueIndexes(objectRecords, valueCount);
|
|
30
|
+
const values = parseValues(bytes, valuesOffset, classesOffset, valueCount, keyCount, neededValues);
|
|
31
|
+
for (const { value } of values.values()) {
|
|
32
|
+
if (typeof value === "object" &&
|
|
33
|
+
value !== null &&
|
|
34
|
+
!Array.isArray(value) &&
|
|
35
|
+
typeof value.$nib_object_ref === "number" &&
|
|
36
|
+
value.$nib_object_ref >= objectCount)
|
|
37
|
+
throw new TypeError("NIBArchive object reference is outside the object table");
|
|
38
|
+
}
|
|
39
|
+
const objects = objectRecords.flatMap((object, id) => {
|
|
40
|
+
const className = classes[object.class_index];
|
|
41
|
+
if (className === undefined)
|
|
42
|
+
return [];
|
|
43
|
+
const fields = {};
|
|
44
|
+
for (let index = object.value_start; index < object.value_start + object.value_count; index += 1) {
|
|
45
|
+
const value = values.get(index);
|
|
46
|
+
if (value === undefined)
|
|
47
|
+
continue;
|
|
48
|
+
const key = keys[value.key_index];
|
|
49
|
+
if (key !== undefined)
|
|
50
|
+
fields[key] = value.value;
|
|
51
|
+
}
|
|
52
|
+
return [{ id, class_name: className, values: fields }];
|
|
53
|
+
});
|
|
54
|
+
let connectionObjectCount = 0;
|
|
55
|
+
for (const object of objects)
|
|
56
|
+
if (/(?:Outlet|Connection|Segue|ActionConnection)/iu.test(object.class_name))
|
|
57
|
+
connectionObjectCount += 1;
|
|
58
|
+
return {
|
|
59
|
+
format_version: formatVersion,
|
|
60
|
+
coder_version: coderVersion,
|
|
61
|
+
object_count: objectCount,
|
|
62
|
+
connection_object_count: connectionObjectCount,
|
|
63
|
+
objects,
|
|
64
|
+
classes,
|
|
65
|
+
limitations: [
|
|
66
|
+
"NIBArchive class extensions and unsupported value encodings are retained as unavailable fields.",
|
|
67
|
+
"NIBArchive object relationships are decoded from serialized references; runtime object creation and execution are not performed.",
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
const parseObjects = (bytes, start, end, count, valueCount, classCount) => {
|
|
72
|
+
const cursor = { offset: start };
|
|
73
|
+
const output = [];
|
|
74
|
+
for (let index = 0; index < count; index += 1) {
|
|
75
|
+
const classIndex = readVarint(bytes, cursor, end);
|
|
76
|
+
const valueStart = readVarint(bytes, cursor, end);
|
|
77
|
+
const countForObject = readVarint(bytes, cursor, end);
|
|
78
|
+
if (classIndex >= classCount ||
|
|
79
|
+
valueStart > valueCount ||
|
|
80
|
+
countForObject > valueCount - valueStart)
|
|
81
|
+
throw new TypeError(`NIBArchive object ${index} references an invalid table range`);
|
|
82
|
+
output.push({
|
|
83
|
+
class_index: classIndex,
|
|
84
|
+
value_start: valueStart,
|
|
85
|
+
value_count: countForObject,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (cursor.offset > end)
|
|
89
|
+
throw new TypeError("NIBArchive object table overlaps the next table");
|
|
90
|
+
return output;
|
|
91
|
+
};
|
|
92
|
+
const parseStrings = (bytes, start, end, count, label) => {
|
|
93
|
+
const cursor = { offset: start };
|
|
94
|
+
const output = [];
|
|
95
|
+
for (let index = 0; index < count; index += 1) {
|
|
96
|
+
const length = readVarint(bytes, cursor, end);
|
|
97
|
+
const next = checkedEnd(cursor.offset, length, end, `${label} ${index}`);
|
|
98
|
+
const value = decodeUtf8(bytes, cursor.offset, next, `${label} ${index}`);
|
|
99
|
+
cursor.offset = next;
|
|
100
|
+
output.push(value);
|
|
101
|
+
}
|
|
102
|
+
return output;
|
|
103
|
+
};
|
|
104
|
+
const parseClasses = (bytes, start, end, count) => {
|
|
105
|
+
const cursor = { offset: start };
|
|
106
|
+
const output = [];
|
|
107
|
+
for (let index = 0; index < count; index += 1) {
|
|
108
|
+
const length = readVarint(bytes, cursor, end);
|
|
109
|
+
const extraCount = readVarint(bytes, cursor, end);
|
|
110
|
+
if (extraCount > 16)
|
|
111
|
+
throw new TypeError(`NIBArchive class ${index} has too many extension values`);
|
|
112
|
+
ensureRange(cursor.offset, extraCount * 4, end, `class ${index} extensions`);
|
|
113
|
+
cursor.offset += extraCount * 4;
|
|
114
|
+
const next = checkedEnd(cursor.offset, length, end, `class ${index}`);
|
|
115
|
+
const name = decodeUtf8(bytes, cursor.offset, next, `class ${index}`).replace(/\0+$/u, "");
|
|
116
|
+
cursor.offset = next;
|
|
117
|
+
output.push(name);
|
|
118
|
+
}
|
|
119
|
+
return output;
|
|
120
|
+
};
|
|
121
|
+
const parseValues = (bytes, start, end, count, keyCount, needed) => {
|
|
122
|
+
const cursor = { offset: start };
|
|
123
|
+
const output = new Map();
|
|
124
|
+
for (let index = 0; index < count; index += 1) {
|
|
125
|
+
const keyIndex = readVarint(bytes, cursor, end);
|
|
126
|
+
if (keyIndex >= keyCount)
|
|
127
|
+
throw new TypeError(`NIBArchive value ${index} references an invalid key`);
|
|
128
|
+
ensureRange(cursor.offset, 1, end, `value ${index} type`);
|
|
129
|
+
const type = bytes[cursor.offset++] ?? -1;
|
|
130
|
+
const value = readValue(bytes, cursor, end, type, index);
|
|
131
|
+
if (needed.has(index))
|
|
132
|
+
output.set(index, { key_index: keyIndex, value });
|
|
133
|
+
}
|
|
134
|
+
if (cursor.offset > end)
|
|
135
|
+
throw new TypeError("NIBArchive value table overlaps the next table");
|
|
136
|
+
return output;
|
|
137
|
+
};
|
|
138
|
+
const readValue = (bytes, cursor, end, type, index) => {
|
|
139
|
+
switch (type) {
|
|
140
|
+
case 0:
|
|
141
|
+
ensureRange(cursor.offset, 1, end, `value ${index}`);
|
|
142
|
+
return bytes.readInt8(cursor.offset++);
|
|
143
|
+
case 1:
|
|
144
|
+
ensureRange(cursor.offset, 2, end, `value ${index}`);
|
|
145
|
+
{
|
|
146
|
+
const value = bytes.readInt16LE(cursor.offset);
|
|
147
|
+
cursor.offset += 2;
|
|
148
|
+
return value;
|
|
149
|
+
}
|
|
150
|
+
case 2:
|
|
151
|
+
ensureRange(cursor.offset, 4, end, `value ${index}`);
|
|
152
|
+
{
|
|
153
|
+
const value = bytes.readInt32LE(cursor.offset);
|
|
154
|
+
cursor.offset += 4;
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
case 3:
|
|
158
|
+
ensureRange(cursor.offset, 8, end, `value ${index}`);
|
|
159
|
+
{
|
|
160
|
+
const value = bytes.readBigInt64LE(cursor.offset);
|
|
161
|
+
cursor.offset += 8;
|
|
162
|
+
return value <= BigInt(Number.MAX_SAFE_INTEGER) &&
|
|
163
|
+
value >= BigInt(Number.MIN_SAFE_INTEGER)
|
|
164
|
+
? Number(value)
|
|
165
|
+
: value.toString();
|
|
166
|
+
}
|
|
167
|
+
case 4:
|
|
168
|
+
return true;
|
|
169
|
+
case 5:
|
|
170
|
+
return false;
|
|
171
|
+
case 6:
|
|
172
|
+
ensureRange(cursor.offset, 4, end, `value ${index}`);
|
|
173
|
+
{
|
|
174
|
+
const value = bytes.readFloatLE(cursor.offset);
|
|
175
|
+
cursor.offset += 4;
|
|
176
|
+
return Number.isFinite(value) ? value : null;
|
|
177
|
+
}
|
|
178
|
+
case 7:
|
|
179
|
+
ensureRange(cursor.offset, 8, end, `value ${index}`);
|
|
180
|
+
{
|
|
181
|
+
const value = bytes.readDoubleLE(cursor.offset);
|
|
182
|
+
cursor.offset += 8;
|
|
183
|
+
return Number.isFinite(value) ? value : null;
|
|
184
|
+
}
|
|
185
|
+
case 8: {
|
|
186
|
+
const length = readVarint(bytes, cursor, end);
|
|
187
|
+
const next = checkedEnd(cursor.offset, length, end, `value ${index} data`);
|
|
188
|
+
const encoded = bytes.subarray(cursor.offset, next).toString("base64");
|
|
189
|
+
cursor.offset = next;
|
|
190
|
+
return { $nib_data_base64: encoded };
|
|
191
|
+
}
|
|
192
|
+
case 9:
|
|
193
|
+
return null;
|
|
194
|
+
case 10:
|
|
195
|
+
ensureRange(cursor.offset, 4, end, `value ${index} reference`);
|
|
196
|
+
{
|
|
197
|
+
const objectIndex = bytes.readUInt32LE(cursor.offset);
|
|
198
|
+
cursor.offset += 4;
|
|
199
|
+
return { $nib_object_ref: objectIndex };
|
|
200
|
+
}
|
|
201
|
+
default:
|
|
202
|
+
throw new TypeError(`NIBArchive value ${index} has unsupported type ${type}`);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const valueIndexes = (objects, total) => {
|
|
206
|
+
const indexes = new Set();
|
|
207
|
+
for (const object of objects)
|
|
208
|
+
for (let index = object.value_start; index < object.value_start + object.value_count; index += 1)
|
|
209
|
+
indexes.add(index);
|
|
210
|
+
if (indexes.size > total)
|
|
211
|
+
throw new TypeError("NIBArchive object value ranges exceed the value table");
|
|
212
|
+
return indexes;
|
|
213
|
+
};
|
|
214
|
+
const readCount = (bytes, offset, label) => {
|
|
215
|
+
const count = readU32(bytes, offset);
|
|
216
|
+
if (count > MAX_RECORDS)
|
|
217
|
+
throw new TypeError(`NIBArchive ${label} count exceeds the decoder bound`);
|
|
218
|
+
return count;
|
|
219
|
+
};
|
|
220
|
+
const readOffset = (bytes, offset, fileLength, label) => {
|
|
221
|
+
const value = readU32(bytes, offset);
|
|
222
|
+
if (value < 50 || value > fileLength)
|
|
223
|
+
throw new TypeError(`NIBArchive ${label} table offset is invalid`);
|
|
224
|
+
return value;
|
|
225
|
+
};
|
|
226
|
+
const readU32 = (bytes, offset) => {
|
|
227
|
+
ensureRange(offset, 4, bytes.length, "header");
|
|
228
|
+
return bytes.readUInt32LE(offset);
|
|
229
|
+
};
|
|
230
|
+
const decodeUtf8 = (bytes, start, end, label) => {
|
|
231
|
+
try {
|
|
232
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(start, end));
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
throw new TypeError(`NIBArchive ${label} is not valid UTF-8`);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const readVarint = (bytes, cursor, end) => {
|
|
239
|
+
let value = 0;
|
|
240
|
+
let shift = 0;
|
|
241
|
+
for (let index = 0; index < 5; index += 1) {
|
|
242
|
+
ensureRange(cursor.offset, 1, end, "variable integer");
|
|
243
|
+
const byte = bytes[cursor.offset++] ?? 0;
|
|
244
|
+
value += (byte & 0x7f) * 2 ** shift;
|
|
245
|
+
if ((byte & 0x80) !== 0) {
|
|
246
|
+
if (value > 0x7fff_ffff)
|
|
247
|
+
throw new TypeError("NIBArchive variable integer is out of range");
|
|
248
|
+
return value;
|
|
249
|
+
}
|
|
250
|
+
shift += 7;
|
|
251
|
+
}
|
|
252
|
+
throw new TypeError("NIBArchive variable integer is too long");
|
|
253
|
+
};
|
|
254
|
+
const checkedEnd = (start, length, limit, label) => {
|
|
255
|
+
if (!Number.isSafeInteger(length) || length < 0 || start + length > limit)
|
|
256
|
+
throw new TypeError(`NIBArchive ${label} exceeds its table`);
|
|
257
|
+
return start + length;
|
|
258
|
+
};
|
|
259
|
+
const ensureRange = (start, length, limit, label) => {
|
|
260
|
+
checkedEnd(start, length, limit, label);
|
|
261
|
+
};
|
|
262
|
+
const assertOrderedOffsets = (length, offsets) => {
|
|
263
|
+
let previous = 50;
|
|
264
|
+
for (const offset of offsets) {
|
|
265
|
+
if (offset < previous || offset > length)
|
|
266
|
+
throw new TypeError("NIBArchive table offsets are out of order");
|
|
267
|
+
previous = offset;
|
|
268
|
+
}
|
|
269
|
+
};
|