rea-agents 6.2.0 → 6.3.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 +18 -20
- package/bridge/hopper_bridge.py +2 -0
- package/dist/android/JadxProvider.js +8 -2
- package/dist/android/JadxSession.js +51 -9
- package/dist/application/BinaryTargetResolver.js +63 -17
- package/dist/application/BrowserScenarioEvidence.js +2 -2
- package/dist/application/ClientConfigurationDocument.js +28 -0
- package/dist/application/ClientRegistrationStatus.js +19 -6
- package/dist/application/DirectAnalysis.js +12 -6
- package/dist/application/DirectAnalysisCleanup.js +0 -1
- package/dist/application/DirectAnalysisStatus.js +2 -5
- package/dist/application/Doctor.js +25 -34
- package/dist/application/DoctorDiagnostics.js +1 -1
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/InvestigationProviders.js +4 -4
- package/dist/application/JsonFiles.js +15 -15
- package/dist/application/LinuxHopper.js +2 -1
- package/dist/application/ReconstructionObligationCandidates.js +9 -2
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
- package/dist/application/RegularFileRead.js +17 -0
- package/dist/application/Setup.js +18 -7
- package/dist/application/SetupClientConfiguration.js +18 -7
- package/dist/application/SetupHost.js +6 -4
- package/dist/application/SetupPlan.js +19 -15
- package/dist/application/SetupSkill.js +57 -8
- package/dist/application/SupportedClients.js +43 -0
- package/dist/application/Uninstall.js +18 -2
- package/dist/application/UpdateMaintenance.js +6 -2
- package/dist/application/Utf8JsonInput.js +64 -0
- package/dist/application/WebScriptExportService.js +13 -6
- package/dist/application/android/AndroidAnalysisService.js +1 -1
- package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
- package/dist/application/binary/BinarySession.js +16 -0
- package/dist/application/binary/BinarySessionOpen.js +9 -1
- package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
- package/dist/application/javascript/JavaScriptApplicationService.js +1 -0
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +0 -6
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +8 -18
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +34 -26
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +44 -12
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +6 -3
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
- package/dist/application/javascript/JavaScriptModuleRelationships.js +5 -17
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +10 -7
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
- package/dist/application/native/NativeCallRoutes.js +2 -4
- package/dist/artifacts/ArtifactProvider.js +14 -16
- package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
- package/dist/artifacts/AsarArtifactReader.js +81 -17
- package/dist/artifacts/DirectoryArtifactReader.js +2 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +152 -67
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +54 -46
- package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
- package/dist/artifacts/extraction/ArtifactExtraction.js +29 -11
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +7 -8
- package/dist/artifacts/inventory/classify.js +33 -14
- package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
- package/dist/artifacts/inventory/scanCanonical.js +28 -22
- package/dist/artifacts/inventory/scanReader.js +7 -11
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
- package/dist/browser/CdpBrowserProvider.js +4 -3
- package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
- package/dist/browser/CdpElectronInspection.js +2 -2
- package/dist/browser/CdpElectronProvider.js +4 -3
- package/dist/browser/CdpElectronScripts.js +2 -2
- package/dist/browser/CdpWebMcpDiscovery.js +16 -13
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +6 -6
- package/dist/browser/PlaywrightScenarioBrowser.js +145 -42
- package/dist/browser/PlaywrightScenarioSession.js +3 -11
- package/dist/browser/WebSourceMapFetcher.js +32 -6
- package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
- package/dist/cli/coreAnalysisCommands.js +2 -2
- package/dist/cli/coreBinaryCommands.js +13 -9
- package/dist/cli/electronCommands.js +9 -10
- package/dist/cli/javascriptApplicationAnalysis.js +2 -12
- package/dist/cli/jsonOutput.js +3 -2
- package/dist/cli/streamedJsonOutput.js +83 -4
- package/dist/cli/utilityCommands.js +2 -4
- package/dist/cli.js +5 -2
- package/dist/cliJsonFile.js +179 -0
- package/dist/cliJsonInput.js +47 -34
- package/dist/cliObservationOptions.js +4 -0
- package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
- package/dist/composition/browserScenario.js +2 -2
- package/dist/composition/directAnalysis.js +2 -3
- package/dist/contracts/artifactComparisonExample.js +5 -5
- package/dist/contracts/errorSchemas.js +3 -1
- package/dist/contracts/functionComparisonExample.js +8 -0
- package/dist/contracts/inputSchemaPresentation.js +94 -3
- package/dist/contracts/javascript/electronToolContracts.js +2 -1
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
- package/dist/contracts/managed/managedToolContracts.js +3 -2
- package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
- package/dist/contracts/native/nativeToolContracts.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +4 -3
- package/dist/contracts/sessionStatusContract.js +3 -2
- package/dist/contracts/sessionToolContracts.js +3 -2
- package/dist/contracts/sessionToolSchemas.js +3 -2
- package/dist/contracts/toolOutputSchemaGroups.js +2 -2
- package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
- package/dist/domain/analysisErrorBase.js +5 -0
- package/dist/domain/analysisErrorPresentation.js +4 -2
- package/dist/domain/analysisSnapshot.js +3 -1
- package/dist/domain/analysisView/analysisView.js +1 -3
- package/dist/domain/android/androidPartialObservation.js +36 -0
- package/dist/domain/apple/dylibResolution.js +1 -1
- package/dist/domain/artifactComparison.js +4 -4
- package/dist/domain/artifactGraph.js +1 -1
- package/dist/domain/artifactIdentity.js +8 -8
- package/dist/domain/artifactInspection.js +8 -8
- package/dist/domain/artifactInventoryEvidence.js +5 -5
- package/dist/domain/browserCompleteness.js +3 -2
- package/dist/domain/browserScenarioCaptureValues.js +2 -2
- package/dist/domain/browserScenarioNormalization.js +3 -3
- package/dist/domain/browserScenarioValues.js +3 -2
- package/dist/domain/callPath.js +8 -10
- package/dist/domain/canonicalDigest.js +7 -1
- package/dist/domain/canonicalOrdering.js +1 -13
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/comparisonSemantics.js +0 -5
- package/dist/domain/digests.js +0 -3
- package/dist/domain/evidence.js +10 -5
- package/dist/domain/evidenceBundle.js +51 -33
- package/dist/domain/firmware/firmwareAnalysis.js +4 -3
- package/dist/domain/functionComparison.js +2 -1
- package/dist/domain/functionComparisonNormalization.js +4 -3
- package/dist/domain/functionComparisonResults.js +2 -2
- package/dist/domain/functionDossierEvidence.js +2 -1
- package/dist/domain/hopperValues.js +11 -15
- package/dist/domain/javascript/electronActiveObservation.js +4 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +2 -2
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +9 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +5 -3
- package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +15 -13
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +45 -34
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +7 -7
- package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
- package/dist/domain/javascript/javascriptAstValues.js +22 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
- package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
- package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
- package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
- package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
- package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
- package/dist/domain/javascript/javascriptNativeHandoff.js +6 -6
- package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -6
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +200 -8
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
- package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
- package/dist/domain/javascript/javascriptSemanticGraph.js +142 -35
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
- package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +497 -113
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +41 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +2 -6
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
- package/dist/domain/javascript/javascriptSemanticProjection.js +20 -14
- package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
- package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
- package/dist/domain/javascript/javascriptSemanticReturns.js +23 -27
- package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +135 -24
- package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
- package/dist/domain/javascript/javascriptSourceParser.js +34 -9
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
- package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
- package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
- package/dist/domain/jsonSerialization.js +109 -55
- package/dist/domain/jsonShape.js +46 -19
- package/dist/domain/localPath.js +10 -4
- package/dist/domain/managed/managedApplicationGraph.js +10 -6
- package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
- package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
- package/dist/domain/native/nativeCallObservation.js +2 -4
- package/dist/domain/native/nativeValueFlow.js +5 -11
- package/dist/domain/native/objcSwiftMetadata.js +15 -17
- package/dist/domain/process/processCapture.js +11 -10
- package/dist/domain/process/processCaptureCoverage.js +8 -5
- package/dist/domain/process/processCaptureExample.js +43 -0
- package/dist/domain/process/processCaptureValidation.js +4 -3
- package/dist/domain/process/processComparison.js +0 -23
- package/dist/domain/process/processScenario.js +3 -3
- package/dist/domain/process/processTraceEvaluation.js +4 -4
- package/dist/domain/process/processTraceSpecification.js +1 -3
- package/dist/domain/providerCleanupError.js +6 -2
- package/dist/domain/reconstructionCoverage.js +2 -1
- package/dist/domain/reconstructionUnknowns.js +4 -3
- package/dist/domain/reconstructionVerification.js +3 -2
- package/dist/domain/referenceSourceGraph.js +7 -7
- package/dist/domain/referenceSourceImportParsing.js +34 -45
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +2 -1
- package/dist/domain/swiftSymbolClassification.js +6 -1
- package/dist/domain/symbolAnalysis.js +17 -2
- package/dist/domain/unicodeCodePointOrder.js +6 -0
- package/dist/domain/webBundleAnalyzerInspection.js +9 -1
- package/dist/domain/webCaptureDiff.js +71 -29
- package/dist/domain/webCaptureDiffSchemas.js +2 -8
- package/dist/domain/webInventory.js +3 -2
- package/dist/domain/webMcpDiscovery.js +4 -3
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
- package/dist/dotnet/ManagedStaticProvider.js +10 -7
- package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
- package/dist/filesystem/RegularFile.js +41 -0
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraClient.js +14 -4
- package/dist/ghidra/GhidraInstallation.js +111 -10
- package/dist/ghidra/GhidraLauncher.js +43 -19
- package/dist/hopper/HopperCleanup.js +1 -1
- package/dist/ida/IdaOperationRunner.js +2 -0
- package/dist/ida/IdaSessionClient.js +4 -2
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
- package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
- package/dist/inspector/V8InspectorProvider.js +60 -8
- package/dist/main/shutdown.js +76 -32
- package/dist/main/transport.js +1 -1
- package/dist/native/AppleObjcDispatchFacets.js +3 -3
- package/dist/native/AppleObjcProperties.js +17 -7
- package/dist/native/LldbCallTracer.js +241 -75
- package/dist/native/NativeMacOSProvider.js +10 -5
- package/dist/native/NativeMacOSProviderMetadata.js +1 -2
- package/dist/process/ProcessOwnershipObservation.js +9 -13
- package/dist/process/capture/FilesystemSnapshot.js +88 -18
- package/dist/process/capture/ProcessCaptureLifecycle.js +13 -27
- package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
- package/dist/process/capture/ProcessHarness.js +8 -21
- package/dist/server/analysisAdmission.js +8 -0
- package/dist/server/createServer.js +22 -23
- package/dist/server/registerApplicationTools/compareExportShapes.js +2 -1
- package/dist/server/registerApplicationTools/helpers.js +3 -2
- package/dist/server/registerArtifactTools.js +2 -2
- package/dist/server/registerCloseLifecycleTool.js +6 -4
- package/dist/server/registerEnhancedTools.js +78 -73
- package/dist/server/registerEvidenceTools.js +54 -46
- package/dist/server/registerManagedTools.js +7 -4
- package/dist/server/registerOfficialTools.js +31 -25
- package/dist/server/registerSessionTools.js +9 -3
- package/native/windows/build/manifest.json +1 -1
- package/package.json +6 -3
- package/skills/reverse-engineer-anything/SKILL.md +5 -5
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/artifacts/inventory/policy.js +0 -2
- package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
- package/dist/server/registerNativeTools.js +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { boundedExpression, collectContextBridgeMembers, electronStaticValue, objectProperty, } from "./electronStaticAnalysisValues.js";
|
|
3
|
-
import {
|
|
3
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
4
4
|
import { addLocatedFinding } from "./javascriptStaticAnalysisFindings.js";
|
|
5
5
|
import { argumentNode, calleeName, range, staticPath, staticPathResolutionContext, } from "./javascriptStaticAnalysisHelpers.js";
|
|
6
6
|
import { semanticStaticPropertyName } from "./javascriptAstValues.js";
|
|
@@ -98,7 +98,7 @@ const collectWebPreferences = (source, object) => {
|
|
|
98
98
|
unknown += 1;
|
|
99
99
|
preferences.push({ name, value });
|
|
100
100
|
}
|
|
101
|
-
preferences.sort((left, right) =>
|
|
101
|
+
preferences.sort((left, right) => compareUnicodeCodePoints(left.name, right.name));
|
|
102
102
|
return {
|
|
103
103
|
status: "object-literal",
|
|
104
104
|
preferences,
|
|
@@ -3,6 +3,7 @@ import { boundedExpression, electronStaticValue, handlerKind, } from "./electron
|
|
|
3
3
|
import { addLocatedFinding } from "./javascriptStaticAnalysisFindings.js";
|
|
4
4
|
import { argumentNode, calleeName, range, } from "./javascriptStaticAnalysisHelpers.js";
|
|
5
5
|
import { semanticStaticPropertyName } from "./javascriptAstValues.js";
|
|
6
|
+
import { compositeKey } from "../unicodeCodePointOrder.js";
|
|
6
7
|
/** Inspect Electron IPC operations and validation candidates. */
|
|
7
8
|
export const inspectElectronIpcNode = (node, context) => {
|
|
8
9
|
if (t.isCallExpression(node)) {
|
|
@@ -116,7 +117,14 @@ const addValidation = (context, node, input) => {
|
|
|
116
117
|
};
|
|
117
118
|
addLocatedFinding(context, {
|
|
118
119
|
collection: context.accumulator.senderValidations,
|
|
119
|
-
key:
|
|
120
|
+
key: compositeKey([
|
|
121
|
+
"electron-validation",
|
|
122
|
+
input.subject,
|
|
123
|
+
input.mechanism,
|
|
124
|
+
input.expected.status === "literal"
|
|
125
|
+
? String(input.expected.value)
|
|
126
|
+
: input.expected.expression,
|
|
127
|
+
]),
|
|
120
128
|
node,
|
|
121
129
|
value: finding,
|
|
122
130
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
|
-
import {
|
|
2
|
+
import { compareUnicodeCodePoints, compositeKey, } from "../unicodeCodePointOrder.js";
|
|
3
3
|
import { stripQueryAndFragment } from "../artifactPathSyntax.js";
|
|
4
4
|
import { addLocatedFinding } from "./javascriptStaticAnalysisFindings.js";
|
|
5
5
|
import { argumentNode, calleeName, range, stringValue, } from "./javascriptStaticAnalysisHelpers.js";
|
|
@@ -98,11 +98,13 @@ const addBinding = (input) => {
|
|
|
98
98
|
const { context, node, specifier, kind } = input;
|
|
99
99
|
const unique = [
|
|
100
100
|
...new Set(input.members.filter((member) => member !== "")),
|
|
101
|
-
].sort(
|
|
101
|
+
].sort(compareUnicodeCodePoints);
|
|
102
102
|
const members = unique.length === 0 ? ["*"] : unique;
|
|
103
103
|
addLocatedFinding(context, {
|
|
104
104
|
collection: context.accumulator.nativeAddonBindings,
|
|
105
|
-
|
|
105
|
+
// Members are a variable-length source-derived list: compositeKey keeps
|
|
106
|
+
// ["a\0b"] distinct from ["a", "b"] instead of collapsing one binding.
|
|
107
|
+
key: compositeKey(["native-addon-binding", kind, specifier, members]),
|
|
106
108
|
node,
|
|
107
109
|
value: {
|
|
108
110
|
specifier,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
|
-
import {
|
|
2
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
3
3
|
import { readExactJavaScriptLiteral, semanticStaticPropertyName, } from "./javascriptAstValues.js";
|
|
4
4
|
import { sourceSlice } from "./javascriptStaticAnalysisHelpers.js";
|
|
5
5
|
/** Preserve one literal value or the exact inert expression. */
|
|
@@ -72,7 +72,7 @@ export const collectContextBridgeMembers = (node) => {
|
|
|
72
72
|
unknown: 0,
|
|
73
73
|
};
|
|
74
74
|
collectMembersAt(node, "", 0, state);
|
|
75
|
-
const members = [...new Set(state.members)].sort(
|
|
75
|
+
const members = [...new Set(state.members)].sort(compareUnicodeCodePoints);
|
|
76
76
|
return {
|
|
77
77
|
status: "object-literal",
|
|
78
78
|
members,
|
|
@@ -107,7 +107,11 @@ const literalValue = (node) => {
|
|
|
107
107
|
if (literal.found)
|
|
108
108
|
return literal;
|
|
109
109
|
if (t.isUnaryExpression(node, { operator: "-" }) &&
|
|
110
|
-
t.isNumericLiteral(node.argument))
|
|
111
|
-
|
|
110
|
+
t.isNumericLiteral(node.argument)) {
|
|
111
|
+
const value = -node.argument.value;
|
|
112
|
+
return Number.isFinite(value) && !Object.is(value, -0)
|
|
113
|
+
? { found: true, value }
|
|
114
|
+
: { found: false };
|
|
115
|
+
}
|
|
112
116
|
return { found: false };
|
|
113
117
|
};
|
|
@@ -3,12 +3,14 @@ import { javascriptApplicationGraphSchema, isValidatedImmutableJavaScriptApplica
|
|
|
3
3
|
import { javaScriptSemanticGraphSchema, isValidatedImmutableJavaScriptSemanticGraph, } from "./javascriptSemanticGraph.js";
|
|
4
4
|
import { digestSchema } from "../digests.js";
|
|
5
5
|
import { prefixedDigestSchema } from "../digests.js";
|
|
6
|
+
import { integrityContradictionSchema } from "../artifactGraph.js";
|
|
6
7
|
import { localPathStringSchema } from "../localPath.js";
|
|
7
8
|
const countSchema = z.number().int().min(0);
|
|
8
9
|
/** Public target-free request for static JavaScript application analysis. */
|
|
9
10
|
export const analyzeJavaScriptApplicationInputSchema = z.strictObject({
|
|
10
11
|
input_path: localPathStringSchema,
|
|
11
12
|
format: z.enum(["auto", "asar", "directory"]).default("auto"),
|
|
13
|
+
integrity_policy: z.enum(["fail", "record-and-continue"]).default("fail"),
|
|
12
14
|
});
|
|
13
15
|
/** Compact counts for the high-level Electron architecture/security surface. */
|
|
14
16
|
const electronBoundarySummarySchema = z.strictObject({
|
|
@@ -44,7 +46,6 @@ const reconstructionStatisticsSchema = z.strictObject({
|
|
|
44
46
|
findings: countSchema,
|
|
45
47
|
modules: countSchema,
|
|
46
48
|
parse_failures: countSchema,
|
|
47
|
-
truncated_scopes: countSchema,
|
|
48
49
|
});
|
|
49
50
|
const applicationAnalysisResultShape = z.strictObject({
|
|
50
51
|
input_path: z.string().min(1),
|
|
@@ -52,6 +53,7 @@ const applicationAnalysisResultShape = z.strictObject({
|
|
|
52
53
|
root_artifact_sha256: digestSchema,
|
|
53
54
|
inventory_manifest_id: prefixedDigestSchema("agm"),
|
|
54
55
|
inventory_graph_sha256: digestSchema,
|
|
56
|
+
integrity_contradictions: z.array(integrityContradictionSchema),
|
|
55
57
|
graph: javascriptApplicationGraphSchema,
|
|
56
58
|
summary: electronBoundarySummarySchema,
|
|
57
59
|
statistics: reconstructionStatisticsSchema,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createJavaScriptApplicationEdge,
|
|
2
|
-
import {
|
|
1
|
+
import { createJavaScriptApplicationEdge, createImmutableJavaScriptApplicationGraphSteps, createJavaScriptApplicationNode, } from "./javascriptApplicationGraph.js";
|
|
2
|
+
import { uniqueSorted } from "../canonicalOrdering.js";
|
|
3
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
3
4
|
/** Merge compared nodes and add inferred right-to-left changed_from edges. */
|
|
4
5
|
export const buildJavaScriptApplicationChangeGraph = (input) => {
|
|
5
6
|
const allNodes = nodeCandidates(input);
|
|
@@ -24,7 +25,7 @@ export const buildJavaScriptApplicationChangeGraph = (input) => {
|
|
|
24
25
|
const candidateEdges = uniqueEdges([...sourceEdges, ...comparisonEdges]);
|
|
25
26
|
const rootNodeIds = preferredRoots.filter((nodeId) => retained.has(nodeId));
|
|
26
27
|
const fallbackRoot = mergedNodes[0]?.node_id;
|
|
27
|
-
const
|
|
28
|
+
const steps = createImmutableJavaScriptApplicationGraphSteps({
|
|
28
29
|
schema: "JavaScriptApplicationGraph",
|
|
29
30
|
root_node_ids: rootNodeIds.length > 0
|
|
30
31
|
? rootNodeIds
|
|
@@ -41,7 +42,10 @@ export const buildJavaScriptApplicationChangeGraph = (input) => {
|
|
|
41
42
|
"The change graph contains compared entities and their retained relationships; it is not an executable application.",
|
|
42
43
|
]),
|
|
43
44
|
});
|
|
44
|
-
|
|
45
|
+
let next = steps.next();
|
|
46
|
+
while (!next.done)
|
|
47
|
+
next = steps.next();
|
|
48
|
+
return { graph: next.value };
|
|
45
49
|
};
|
|
46
50
|
const nodeCandidates = (input) => {
|
|
47
51
|
const required = new Set([
|
|
@@ -145,7 +149,7 @@ const changeGraphCoverage = (input) => {
|
|
|
145
149
|
};
|
|
146
150
|
const sourceCoverageLimits = (input) => [
|
|
147
151
|
...new Map([...input.left.coverage.limits, ...input.right.coverage.limits].map((limit) => [`${limit.name}\0${limit.value}\0${limit.unit}`, limit])).values(),
|
|
148
|
-
].sort((left, right) =>
|
|
152
|
+
].sort((left, right) => compareUnicodeCodePoints(left.name, right.name));
|
|
149
153
|
const combineOmittedCounts = (left, right) => left === null || right === null ? null : left + right;
|
|
150
154
|
const mergeNodes = (nodes) => {
|
|
151
155
|
const groups = new Map();
|
|
@@ -159,13 +163,13 @@ const mergeNodes = (nodes) => {
|
|
|
159
163
|
...new Map(group
|
|
160
164
|
.flatMap(({ observations: values }) => values)
|
|
161
165
|
.map((observation) => [observation.observation_id, observation])).values(),
|
|
162
|
-
].sort((left, right) =>
|
|
166
|
+
].sort((left, right) => compareUnicodeCodePoints(left.observation_id, right.observation_id));
|
|
163
167
|
return createJavaScriptApplicationNode({
|
|
164
168
|
kind: first.kind,
|
|
165
169
|
identity: first.identity,
|
|
166
170
|
observations: observations.map(({ observation_id: _id, identifier_strategy: _strategy, ...value }) => value),
|
|
167
171
|
});
|
|
168
172
|
});
|
|
169
|
-
return merged.sort((left, right) =>
|
|
173
|
+
return merged.sort((left, right) => compareUnicodeCodePoints(left.node_id, right.node_id));
|
|
170
174
|
};
|
|
171
|
-
const uniqueEdges = (edges) => [...new Map(edges.map((edge) => [edge.edge_id, edge])).values()].sort((left, right) =>
|
|
175
|
+
const uniqueEdges = (edges) => [...new Map(edges.map((edge) => [edge.edge_id, edge])).values()].sort((left, right) => compareUnicodeCodePoints(left.edge_id, right.edge_id));
|
|
@@ -232,6 +232,10 @@ const applicationGraphEvidenceBaseSchema = z.strictObject({
|
|
|
232
232
|
limitations: z.array(boundedTextSchema),
|
|
233
233
|
evidence_ids: z.array(prefixedDigestSchema("ev")),
|
|
234
234
|
});
|
|
235
|
+
/** Shared provenance fields apart from the fact-specific evidence location. */
|
|
236
|
+
export const applicationGraphEvidenceContextSchema = applicationGraphEvidenceBaseSchema.omit({ location: true });
|
|
237
|
+
/** Exact coordinates retained on each graph fact. */
|
|
238
|
+
export const applicationGraphEvidenceLocationSchema = applicationLocationReferenceSchema;
|
|
235
239
|
const checkAuthorityState = (evidence, context) => {
|
|
236
240
|
if (evidence.authority === "static-relationship-inference" &&
|
|
237
241
|
evidence.state !== "inferred")
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { canonicalJson } from "../comparisonSemantics.js";
|
|
3
|
+
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
4
|
+
import { uniqueSorted } from "../canonicalOrdering.js";
|
|
5
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
4
6
|
import { freezeOwnedJsonSnapshotSteps } from "../immutableJson.js";
|
|
5
7
|
import { applicationEdgeInputSchema, applicationEdgeSchema, applicationNodeInputSchema, applicationNodeObservationSchema, applicationNodeSchema, javascriptApplicationGraphInputSchema, javascriptApplicationGraphRecordSchema, } from "./javascriptApplicationGraphSchemas.js";
|
|
6
8
|
const OBSERVATION_IDENTIFIER_STRATEGY = {
|
|
@@ -12,7 +14,7 @@ const EDGE_IDENTIFIER_STRATEGY = {
|
|
|
12
14
|
stability: "relationship-exact",
|
|
13
15
|
};
|
|
14
16
|
const limitKey = (limit) => canonicalJson(limit, "JavaScript Application Graph");
|
|
15
|
-
const normalizeLimits = (limits) => [...new Map(limits.map((limit) => [limitKey(limit), limit])).values()].sort((left, right) =>
|
|
17
|
+
const normalizeLimits = (limits) => [...new Map(limits.map((limit) => [limitKey(limit), limit])).values()].sort((left, right) => compareUnicodeCodePoints(limitKey(left), limitKey(right)));
|
|
16
18
|
const normalizeEvidence = (evidence) => ({
|
|
17
19
|
...evidence,
|
|
18
20
|
coverage: {
|
|
@@ -29,13 +31,13 @@ const nodeSemantic = (node) => ({
|
|
|
29
31
|
kind: node.kind,
|
|
30
32
|
identity: node.identity,
|
|
31
33
|
});
|
|
32
|
-
const nodeId = (node) => `jag_node_${
|
|
34
|
+
const nodeId = (node) => `jag_node_${digestCanonicalValue(nodeSemantic(node), "JavaScript Application Graph")}`;
|
|
33
35
|
const observationSemantic = (nodeIdentifier, observation) => ({ node_id: nodeIdentifier, ...observation });
|
|
34
|
-
const observationId = (nodeIdentifier, observation) => `jag_observation_${
|
|
35
|
-
const edgeId = (edge) => `jag_edge_${
|
|
36
|
+
const observationId = (nodeIdentifier, observation) => `jag_observation_${digestCanonicalValue(observationSemantic(nodeIdentifier, observation))}`;
|
|
37
|
+
const edgeId = (edge) => `jag_edge_${digestCanonicalValue(edge, "JavaScript Application Graph")}`;
|
|
36
38
|
const sortedUniqueIssue = (values, path, label, context) => {
|
|
37
39
|
for (let index = 1; index < values.length; index += 1) {
|
|
38
|
-
if (
|
|
40
|
+
if (compareUnicodeCodePoints(values[index - 1] ?? "", values[index] ?? "") < 0)
|
|
39
41
|
continue;
|
|
40
42
|
context.addIssue({
|
|
41
43
|
code: "custom",
|
|
@@ -213,7 +215,7 @@ const checkGraphInvariants = (graph, context) => {
|
|
|
213
215
|
}
|
|
214
216
|
const { graph_id: identifier, ...semantic } = graph;
|
|
215
217
|
if (identifier !==
|
|
216
|
-
`jag_${
|
|
218
|
+
`jag_${digestCanonicalValue(semantic, "JavaScript Application Graph")}`)
|
|
217
219
|
context.addIssue({
|
|
218
220
|
code: "custom",
|
|
219
221
|
message: "Graph identifier does not match its semantic content",
|
|
@@ -239,7 +241,7 @@ export const createJavaScriptApplicationNode = (input) => {
|
|
|
239
241
|
observation_id: observationId(identifier, semantic),
|
|
240
242
|
});
|
|
241
243
|
})
|
|
242
|
-
.sort((left, right) =>
|
|
244
|
+
.sort((left, right) => compareUnicodeCodePoints(left.observation_id, right.observation_id));
|
|
243
245
|
return applicationNodeSchema.parse({
|
|
244
246
|
node_id: identifier,
|
|
245
247
|
kind: parsed.kind,
|
|
@@ -266,8 +268,8 @@ export const createJavaScriptApplicationGraph = (input) => {
|
|
|
266
268
|
const semantic = {
|
|
267
269
|
...parsed,
|
|
268
270
|
root_node_ids: uniqueSorted(parsed.root_node_ids),
|
|
269
|
-
nodes: [...parsed.nodes].sort((left, right) =>
|
|
270
|
-
edges: [...parsed.edges].sort((left, right) =>
|
|
271
|
+
nodes: [...parsed.nodes].sort((left, right) => compareUnicodeCodePoints(left.node_id, right.node_id)),
|
|
272
|
+
edges: [...parsed.edges].sort((left, right) => compareUnicodeCodePoints(left.edge_id, right.edge_id)),
|
|
271
273
|
coverage: {
|
|
272
274
|
...parsed.coverage,
|
|
273
275
|
limits: normalizeLimits(parsed.coverage.limits),
|
|
@@ -276,7 +278,7 @@ export const createJavaScriptApplicationGraph = (input) => {
|
|
|
276
278
|
};
|
|
277
279
|
return javascriptApplicationGraphSchema.parse({
|
|
278
280
|
...semantic,
|
|
279
|
-
graph_id: `jag_${
|
|
281
|
+
graph_id: `jag_${digestCanonicalValue(semantic, "JavaScript Application Graph")}`,
|
|
280
282
|
});
|
|
281
283
|
};
|
|
282
284
|
const validatedImmutableApplicationGraphs = new WeakSet();
|
|
@@ -294,6 +296,6 @@ export const isValidatedImmutableJavaScriptApplicationGraph = (value) => typeof
|
|
|
294
296
|
/** Parse a stored graph and reject stale IDs. */
|
|
295
297
|
export const parseJavaScriptApplicationGraph = (input) => javascriptApplicationGraphSchema.parse(input);
|
|
296
298
|
/** Compute the byte-stable SHA-256 commitment of a verified graph. */
|
|
297
|
-
export const computeJavaScriptApplicationGraphSha256 = (input) =>
|
|
299
|
+
export const computeJavaScriptApplicationGraphSha256 = (input) => digestCanonicalValue(parseJavaScriptApplicationGraph(input), "JavaScript Application Graph");
|
|
298
300
|
/** Serialize a verified graph as RFC 8785 canonical JSON. */
|
|
299
301
|
export const serializeJavaScriptApplicationGraph = (input) => canonicalJson(parseJavaScriptApplicationGraph(input), "JavaScript Application Graph");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
2
2
|
import { uniqueSorted } from "../canonicalOrdering.js";
|
|
3
3
|
import { buildJavaScriptApplicationChangeGraph } from "./javascriptApplicationChangeGraph.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ownedApplicationVersionComparisonResultSchema, } from "./javascriptApplicationVersionComparisonSchemas.js";
|
|
5
5
|
import { classifyJavaScriptApplicationVersions } from "./javascriptApplicationVersionItems.js";
|
|
6
6
|
import { matchJavaScriptApplicationVersions } from "./javascriptApplicationVersionKeys.js";
|
|
7
7
|
/** Compare application entities with ordered unique-only identity tiers. */
|
|
@@ -47,9 +47,9 @@ export const compareJavaScriptApplicationVersions = (input) => {
|
|
|
47
47
|
evidence_links: evidenceLinks,
|
|
48
48
|
limitations: comparisonLimitations(input),
|
|
49
49
|
};
|
|
50
|
-
return
|
|
50
|
+
return ownedApplicationVersionComparisonResultSchema.parse({
|
|
51
51
|
...semantic,
|
|
52
|
-
comparison_id: `javc_${
|
|
52
|
+
comparison_id: `javc_${digestCanonicalValue(semantic, "Application version comparison")}`,
|
|
53
53
|
});
|
|
54
54
|
};
|
|
55
55
|
const summary = (items) => ({
|
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { emptyArraySchema } from "../emptyArraySchema.js";
|
|
3
3
|
import { evidenceSchema } from "../evidence.js";
|
|
4
|
-
import { javascriptApplicationGraphSchema } from "./javascriptApplicationGraph.js";
|
|
4
|
+
import { isValidatedImmutableJavaScriptApplicationGraph, javascriptApplicationGraphSchema, } from "./javascriptApplicationGraph.js";
|
|
5
5
|
import { JAVASCRIPT_APPLICATION_NODE_KINDS } from "./javascriptApplicationGraphSchemas.js";
|
|
6
6
|
import { prefixedDigestSchema } from "../digests.js";
|
|
7
7
|
const evidenceIdSchema = prefixedDigestSchema("ev");
|
|
8
8
|
const nodeIdSchema = prefixedDigestSchema("jag_node");
|
|
9
9
|
const textSchema = z.string().min(1);
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
.strictObject({
|
|
13
|
-
left: evidenceSchema,
|
|
14
|
-
right: evidenceSchema,
|
|
15
|
-
left_native_observations: z.array(evidenceSchema).default([]),
|
|
16
|
-
right_native_observations: z.array(evidenceSchema).default([]),
|
|
17
|
-
})
|
|
18
|
-
.superRefine((input, context) => {
|
|
10
|
+
/** Check paired version identities and per-side native identity uniqueness. */
|
|
11
|
+
const validateApplicationVersionIdentities = (input, context) => {
|
|
19
12
|
if (input.left.evidence_id === input.right.evidence_id)
|
|
20
13
|
context.addIssue({
|
|
21
14
|
code: "custom",
|
|
@@ -34,8 +27,26 @@ export const compareApplicationVersionsInputSchema = z
|
|
|
34
27
|
message: "Native observations must be unique on each side",
|
|
35
28
|
});
|
|
36
29
|
}
|
|
37
|
-
}
|
|
38
|
-
const
|
|
30
|
+
};
|
|
31
|
+
const evidenceIdentitySchema = z.object({ evidence_id: evidenceIdSchema });
|
|
32
|
+
/** Validate paired version identities without capturing whole analysis graphs. */
|
|
33
|
+
export const applicationVersionIdentitiesSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
left: evidenceIdentitySchema,
|
|
36
|
+
right: evidenceIdentitySchema,
|
|
37
|
+
left_native_observations: z.array(evidenceIdentitySchema),
|
|
38
|
+
right_native_observations: z.array(evidenceIdentitySchema),
|
|
39
|
+
})
|
|
40
|
+
.superRefine(validateApplicationVersionIdentities);
|
|
41
|
+
/** Two authenticated application versions and their native observations. */
|
|
42
|
+
export const compareApplicationVersionsInputSchema = z
|
|
43
|
+
.strictObject({
|
|
44
|
+
left: evidenceSchema,
|
|
45
|
+
right: evidenceSchema,
|
|
46
|
+
left_native_observations: z.array(evidenceSchema).default([]),
|
|
47
|
+
right_native_observations: z.array(evidenceSchema).default([]),
|
|
48
|
+
})
|
|
49
|
+
.superRefine(validateApplicationVersionIdentities);
|
|
39
50
|
const candidateNodesSchema = z.tuple([nodeIdSchema]).rest(nodeIdSchema);
|
|
40
51
|
const exactMatchSchema = z.strictObject({
|
|
41
52
|
status: z.literal("matched"),
|
|
@@ -45,22 +56,22 @@ const exactMatchSchema = z.strictObject({
|
|
|
45
56
|
"exact-module-source-digest",
|
|
46
57
|
]),
|
|
47
58
|
confidence: z.literal("exact"),
|
|
48
|
-
candidate_left_node_ids:
|
|
49
|
-
candidate_right_node_ids:
|
|
59
|
+
candidate_left_node_ids: emptyArraySchema,
|
|
60
|
+
candidate_right_node_ids: emptyArraySchema,
|
|
50
61
|
});
|
|
51
62
|
const sourceMapMatchSchema = z.strictObject({
|
|
52
63
|
status: z.literal("matched"),
|
|
53
64
|
basis: z.literal("source-map-identity"),
|
|
54
65
|
confidence: z.literal("high"),
|
|
55
|
-
candidate_left_node_ids:
|
|
56
|
-
candidate_right_node_ids:
|
|
66
|
+
candidate_left_node_ids: emptyArraySchema,
|
|
67
|
+
candidate_right_node_ids: emptyArraySchema,
|
|
57
68
|
});
|
|
58
69
|
const inferredMatchSchema = z.strictObject({
|
|
59
70
|
status: z.literal("matched"),
|
|
60
71
|
basis: z.enum(["structural-fingerprint", "semantic-key"]),
|
|
61
72
|
confidence: z.literal("medium"),
|
|
62
|
-
candidate_left_node_ids:
|
|
63
|
-
candidate_right_node_ids:
|
|
73
|
+
candidate_left_node_ids: emptyArraySchema,
|
|
74
|
+
candidate_right_node_ids: emptyArraySchema,
|
|
64
75
|
});
|
|
65
76
|
const matchedItemMatchSchema = z.union([
|
|
66
77
|
exactMatchSchema,
|
|
@@ -71,14 +82,14 @@ const unmatchedItemMatchSchema = z.strictObject({
|
|
|
71
82
|
status: z.literal("unmatched"),
|
|
72
83
|
basis: z.literal("none"),
|
|
73
84
|
confidence: z.literal("unknown"),
|
|
74
|
-
candidate_left_node_ids:
|
|
75
|
-
candidate_right_node_ids:
|
|
85
|
+
candidate_left_node_ids: emptyArraySchema,
|
|
86
|
+
candidate_right_node_ids: emptyArraySchema,
|
|
76
87
|
});
|
|
77
88
|
const leftAmbiguousMatchSchema = z.strictObject({
|
|
78
89
|
status: z.literal("ambiguous"),
|
|
79
90
|
basis: z.literal("none"),
|
|
80
91
|
confidence: z.literal("unknown"),
|
|
81
|
-
candidate_left_node_ids:
|
|
92
|
+
candidate_left_node_ids: emptyArraySchema,
|
|
82
93
|
candidate_right_node_ids: candidateNodesSchema,
|
|
83
94
|
});
|
|
84
95
|
const rightAmbiguousMatchSchema = z.strictObject({
|
|
@@ -86,7 +97,7 @@ const rightAmbiguousMatchSchema = z.strictObject({
|
|
|
86
97
|
basis: z.literal("none"),
|
|
87
98
|
confidence: z.literal("unknown"),
|
|
88
99
|
candidate_left_node_ids: candidateNodesSchema,
|
|
89
|
-
candidate_right_node_ids:
|
|
100
|
+
candidate_right_node_ids: emptyArraySchema,
|
|
90
101
|
});
|
|
91
102
|
const comparisonItemContextShape = {
|
|
92
103
|
item_id: prefixedDigestSchema("javc_item"),
|
|
@@ -194,3 +205,7 @@ export const applicationVersionComparisonResultSchema = z
|
|
|
194
205
|
message: "Comparison coverage must match source graph completeness",
|
|
195
206
|
});
|
|
196
207
|
});
|
|
208
|
+
/** Reuse the exact owned change graph while validating the rest of the result. */
|
|
209
|
+
export const ownedApplicationVersionComparisonResultSchema = applicationVersionComparisonResultSchema.safeExtend({
|
|
210
|
+
graph: z.custom(isValidatedImmutableJavaScriptApplicationGraph),
|
|
211
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { absenceClaimable,
|
|
2
|
-
import {
|
|
1
|
+
import { absenceClaimable, canonicalJson } from "../comparisonSemantics.js";
|
|
2
|
+
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
3
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
3
4
|
/** Classify matched, unmatched, and ambiguous nodes without inventing absence. */
|
|
4
5
|
export const classifyJavaScriptApplicationVersions = (matching, context) => {
|
|
5
6
|
const pairByLeft = new Map(matching.pairs.map(({ left, right }) => [
|
|
@@ -10,7 +11,13 @@ export const classifyJavaScriptApplicationVersions = (matching, context) => {
|
|
|
10
11
|
right.node_id,
|
|
11
12
|
`pair:${left.node_id}:${right.node_id}`,
|
|
12
13
|
]));
|
|
13
|
-
const fullContext = {
|
|
14
|
+
const fullContext = {
|
|
15
|
+
...context,
|
|
16
|
+
pairByLeft,
|
|
17
|
+
pairByRight,
|
|
18
|
+
leftRelationships: indexRelationships(context.leftGraph),
|
|
19
|
+
rightRelationships: indexRelationships(context.rightGraph),
|
|
20
|
+
};
|
|
14
21
|
const leftItems = matching.unmatchedLeft.map((node) => {
|
|
15
22
|
const candidates = matching.candidatesForLeft.get(node.node_id) ?? [];
|
|
16
23
|
return unmatchedItem({
|
|
@@ -30,7 +37,7 @@ export const classifyJavaScriptApplicationVersions = (matching, context) => {
|
|
|
30
37
|
...matching.pairs.map((pair) => matchedItem(pair, fullContext)),
|
|
31
38
|
...leftItems,
|
|
32
39
|
...rightItems,
|
|
33
|
-
].sort((left, right) =>
|
|
40
|
+
].sort((left, right) => compareUnicodeCodePoints(left.item_id, right.item_id)),
|
|
34
41
|
};
|
|
35
42
|
};
|
|
36
43
|
const matchedItem = (pair, context) => {
|
|
@@ -201,42 +208,46 @@ const contentIdentity = (node) => {
|
|
|
201
208
|
};
|
|
202
209
|
const locations = (node) => node.observations
|
|
203
210
|
.map(({ evidence }) => evidence.location.available ? evidence.location.value : evidence.location)
|
|
204
|
-
.sort((left, right) =>
|
|
211
|
+
.sort((left, right) => compareUnicodeCodePoints(canonicalJson(left), canonicalJson(right)));
|
|
205
212
|
const properties = (node) => node.observations
|
|
206
213
|
.map(({ label, properties: values, source_map_reference }) => ({
|
|
207
214
|
label,
|
|
208
215
|
properties: values,
|
|
209
216
|
source_map_reference,
|
|
210
217
|
}))
|
|
211
|
-
.sort((left, right) =>
|
|
218
|
+
.sort((left, right) => compareUnicodeCodePoints(canonicalJson(left), canonicalJson(right)));
|
|
219
|
+
const indexRelationships = (graph) => {
|
|
220
|
+
const adjacency = new Map();
|
|
221
|
+
const add = (nodeId, relationship) => {
|
|
222
|
+
const existing = adjacency.get(nodeId);
|
|
223
|
+
if (existing === undefined)
|
|
224
|
+
adjacency.set(nodeId, [relationship]);
|
|
225
|
+
else
|
|
226
|
+
existing.push(relationship);
|
|
227
|
+
};
|
|
228
|
+
for (const edge of graph.edges) {
|
|
229
|
+
add(edge.source_node_id, {
|
|
230
|
+
direction: "out",
|
|
231
|
+
relation: edge.relation,
|
|
232
|
+
neighborId: edge.target_node_id,
|
|
233
|
+
});
|
|
234
|
+
if (edge.target_node_id !== edge.source_node_id)
|
|
235
|
+
add(edge.target_node_id, {
|
|
236
|
+
direction: "in",
|
|
237
|
+
relation: edge.relation,
|
|
238
|
+
neighborId: edge.source_node_id,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
nodeById: new Map(graph.nodes.map((value) => [value.node_id, value])),
|
|
243
|
+
adjacency,
|
|
244
|
+
};
|
|
245
|
+
};
|
|
212
246
|
const relationshipSignature = (node, side, context) => {
|
|
213
|
-
const
|
|
247
|
+
const { nodeById, adjacency } = side === "left" ? context.leftRelationships : context.rightRelationships;
|
|
214
248
|
const paired = side === "left" ? context.pairByLeft : context.pairByRight;
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
if (edge.source_node_id === node.node_id)
|
|
218
|
-
return [
|
|
219
|
-
edgeSignature({
|
|
220
|
-
direction: "out",
|
|
221
|
-
relation: edge.relation,
|
|
222
|
-
neighborId: edge.target_node_id,
|
|
223
|
-
paired,
|
|
224
|
-
nodeById,
|
|
225
|
-
}),
|
|
226
|
-
];
|
|
227
|
-
if (edge.target_node_id === node.node_id)
|
|
228
|
-
return [
|
|
229
|
-
edgeSignature({
|
|
230
|
-
direction: "in",
|
|
231
|
-
relation: edge.relation,
|
|
232
|
-
neighborId: edge.source_node_id,
|
|
233
|
-
paired,
|
|
234
|
-
nodeById,
|
|
235
|
-
}),
|
|
236
|
-
];
|
|
237
|
-
return [];
|
|
238
|
-
});
|
|
239
|
-
return canonicalJson(signatures.sort(compareCodePoints));
|
|
249
|
+
const signatures = (adjacency.get(node.node_id) ?? []).map((relationship) => edgeSignature({ ...relationship, paired, nodeById }));
|
|
250
|
+
return canonicalJson(signatures.sort(compareUnicodeCodePoints));
|
|
240
251
|
};
|
|
241
252
|
const edgeSignature = (context) => {
|
|
242
253
|
const mapped = context.paired.get(context.neighborId);
|
|
@@ -250,7 +261,7 @@ const itemEvidenceLinks = (left, right, context) => [
|
|
|
250
261
|
...nativeLinks(left, context.leftNativeEvidence),
|
|
251
262
|
...nativeLinks(right, context.rightNativeEvidence),
|
|
252
263
|
]),
|
|
253
|
-
].sort(
|
|
264
|
+
].sort(compareUnicodeCodePoints);
|
|
254
265
|
const nativeLinks = (node, evidence) => {
|
|
255
266
|
const digest = node === undefined
|
|
256
267
|
? null
|
|
@@ -283,7 +294,7 @@ const pairLimitations = (pair, status) => [
|
|
|
283
294
|
];
|
|
284
295
|
const itemWithId = (semantic) => ({
|
|
285
296
|
...semantic,
|
|
286
|
-
item_id: `javc_item_${
|
|
297
|
+
item_id: `javc_item_${digestCanonicalValue(semantic, "Application version item")}`,
|
|
287
298
|
});
|
|
288
299
|
const stringProperty = (node, key) => {
|
|
289
300
|
const values = [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { canonicalJson } from "../comparisonSemantics.js";
|
|
2
|
-
import {
|
|
2
|
+
import { compareUnicodeCodePoints, compositeKey, } from "../unicodeCodePointOrder.js";
|
|
3
3
|
const matchTiers = () => [
|
|
4
4
|
{
|
|
5
5
|
match: { basis: "exact-content-digest", confidence: "exact" },
|
|
@@ -40,7 +40,7 @@ export const matchJavaScriptApplicationVersions = (leftNodes, rightNodes) => {
|
|
|
40
40
|
const leftIds = new Set(remainingLeft.map(({ node_id: id }) => id));
|
|
41
41
|
const rightIds = new Set(remainingRight.map(({ node_id: id }) => id));
|
|
42
42
|
return {
|
|
43
|
-
pairs: pairs.sort((a, b) =>
|
|
43
|
+
pairs: pairs.sort((a, b) => compareUnicodeCodePoints(`${a.left.node_id}\0${a.right.node_id}`, `${b.left.node_id}\0${b.right.node_id}`)),
|
|
44
44
|
unmatchedLeft: remainingLeft,
|
|
45
45
|
unmatchedRight: remainingRight,
|
|
46
46
|
candidatesForLeft: filteredCandidates(leftCandidates, rightIds),
|
|
@@ -50,7 +50,7 @@ export const matchJavaScriptApplicationVersions = (leftNodes, rightNodes) => {
|
|
|
50
50
|
const applyTier = (context) => {
|
|
51
51
|
const leftByKey = nodesByKey(context.left.values(), context.tier.key);
|
|
52
52
|
const rightByKey = nodesByKey(context.right.values(), context.tier.key);
|
|
53
|
-
for (const key of [...leftByKey.keys()].sort(
|
|
53
|
+
for (const key of [...leftByKey.keys()].sort(compareUnicodeCodePoints)) {
|
|
54
54
|
const leftGroup = leftByKey.get(key) ?? [];
|
|
55
55
|
const rightGroup = rightByKey.get(key) ?? [];
|
|
56
56
|
if (rightGroup.length === 0)
|
|
@@ -98,7 +98,7 @@ const recordCandidates = (left, right, leftCandidates, rightCandidates) => {
|
|
|
98
98
|
const filteredCandidates = (candidates, retained) => new Map([...candidates.entries()].flatMap(([nodeId, values]) => {
|
|
99
99
|
const filtered = [...values]
|
|
100
100
|
.filter((value) => retained.has(value))
|
|
101
|
-
.sort(
|
|
101
|
+
.sort(compareUnicodeCodePoints);
|
|
102
102
|
return filtered.length === 0 ? [] : [[nodeId, filtered]];
|
|
103
103
|
}));
|
|
104
104
|
const nodeIdentityKey = (node) => `node\0${node.kind}\0${node.node_id}`;
|
|
@@ -178,7 +178,7 @@ const uniqueStringProperty = (node, name) => {
|
|
|
178
178
|
};
|
|
179
179
|
const joined = (...values) => {
|
|
180
180
|
const strings = values.map(nonEmptyString);
|
|
181
|
-
return strings.some((value) => value === null) ? null : strings
|
|
181
|
+
return strings.some((value) => value === null) ? null : compositeKey(strings);
|
|
182
182
|
};
|
|
183
183
|
const nonEmptyString = (value) => typeof value === "string" && value !== "" ? value : null;
|
|
184
184
|
/** A literal value such as `ipcMain.handle("")` keeps its exact empty text. */
|
|
@@ -186,6 +186,6 @@ const exactString = (value) => typeof value === "string" ? value : null;
|
|
|
186
186
|
const stringList = (value) => Array.isArray(value)
|
|
187
187
|
? value
|
|
188
188
|
.filter((item) => typeof item === "string")
|
|
189
|
-
.sort(
|
|
189
|
+
.sort(compareUnicodeCodePoints)
|
|
190
190
|
: [];
|
|
191
|
-
const sortedNodes = (nodes) => [...nodes].sort((left, right) =>
|
|
191
|
+
const sortedNodes = (nodes) => [...nodes].sort((left, right) => compareUnicodeCodePoints(left.node_id, right.node_id));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import * as t from "@babel/types";
|
|
3
3
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
4
|
-
import {
|
|
4
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
5
5
|
import { propertyName } from "./javascriptAstValues.js";
|
|
6
6
|
import { stringValue } from "./javascriptStaticAnalysisHelpers.js";
|
|
7
7
|
/** Derive a rename-resistant syntax fingerprint without code execution. */
|
|
@@ -28,7 +28,7 @@ export const collectJavaScriptExports = (node) => {
|
|
|
28
28
|
},
|
|
29
29
|
});
|
|
30
30
|
return {
|
|
31
|
-
values: [...exports].sort(
|
|
31
|
+
values: [...exports].sort(compareUnicodeCodePoints),
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
34
|
const semanticTokens = (node) => {
|
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
|
+
/**
|
|
3
|
+
* Remove wrappers that affect TypeScript or Flow checking but not runtime
|
|
4
|
+
* expression identity. The returned depth lets bounded evaluators account for
|
|
5
|
+
* syntax that normalization would otherwise skip.
|
|
6
|
+
*/
|
|
7
|
+
export const unwrapJavaScriptExpression = (node) => {
|
|
8
|
+
let current = node;
|
|
9
|
+
let depth = 0;
|
|
10
|
+
while (t.isParenthesizedExpression(current) ||
|
|
11
|
+
t.isTSAsExpression(current) ||
|
|
12
|
+
t.isTSTypeAssertion(current) ||
|
|
13
|
+
t.isTSNonNullExpression(current) ||
|
|
14
|
+
t.isTSSatisfiesExpression(current) ||
|
|
15
|
+
t.isTSInstantiationExpression(current) ||
|
|
16
|
+
t.isTypeCastExpression(current)) {
|
|
17
|
+
current = current.expression;
|
|
18
|
+
depth += 1;
|
|
19
|
+
}
|
|
20
|
+
return { node: current, depth };
|
|
21
|
+
};
|
|
2
22
|
/** Read one syntax-level primitive only when its value is exact. */
|
|
3
23
|
export const readExactJavaScriptLiteral = (node) => {
|
|
24
|
+
node = unwrapJavaScriptExpression(node).node;
|
|
4
25
|
if (t.isStringLiteral(node))
|
|
5
26
|
return { found: true, value: node.value };
|
|
6
27
|
if (t.isNumericLiteral(node) && Number.isFinite(node.value))
|
|
@@ -31,6 +52,7 @@ export const propertyName = (node) => {
|
|
|
31
52
|
export const semanticStaticPropertyName = (property, computed) => semanticStaticPropertyKey(property, computed) ?? "";
|
|
32
53
|
/** Read an exact property key, preserving the legal empty-string key. */
|
|
33
54
|
export const semanticStaticPropertyKey = (property, computed) => {
|
|
55
|
+
property = unwrapJavaScriptExpression(property).node;
|
|
34
56
|
if (t.isStringLiteral(property) || t.isNumericLiteral(property))
|
|
35
57
|
return String(property.value);
|
|
36
58
|
return !computed && t.isIdentifier(property) ? property.name : null;
|