rea-agents 1.7.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/README.md +112 -59
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +42 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +11 -29
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +165 -197
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +112 -0
  26. package/dist/application/ElectronBoundaryGraph.js +9 -0
  27. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  28. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  29. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  30. package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
  31. package/dist/application/EnhancedToolPagination.js +22 -0
  32. package/dist/application/EnhancedToolTypes.js +4 -0
  33. package/dist/application/EnhancedTools.js +58 -50
  34. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  35. package/dist/application/InvestigationProviders.js +30 -0
  36. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  37. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  38. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  39. package/dist/application/JavaScriptApplicationService.js +74 -0
  40. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  41. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  42. package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
  43. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  44. package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
  45. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  46. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  47. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  48. package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
  49. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  50. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  51. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  52. package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
  53. package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
  54. package/dist/application/JavaScriptJsonModules.js +39 -0
  55. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  56. package/dist/application/JavaScriptReplayPermission.js +16 -0
  57. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  58. package/dist/application/JavaScriptReplayService.js +292 -0
  59. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  60. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  61. package/dist/application/LinuxHopper.js +10 -0
  62. package/dist/application/MacHopper.js +22 -11
  63. package/dist/application/ManagedApplicationGraphService.js +55 -0
  64. package/dist/application/ManagedMemberComparisonService.js +122 -0
  65. package/dist/application/ManagedNativeVerificationService.js +39 -0
  66. package/dist/application/ManagedReconstructionService.js +58 -0
  67. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  68. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  69. package/dist/application/PermissionAuthority.js +106 -63
  70. package/dist/application/ProcessCaptureCapability.js +1 -1
  71. package/dist/application/ProcessCapturePermission.js +13 -0
  72. package/dist/application/ProcessCli.js +2 -12
  73. package/dist/application/ProcessHarness.js +1 -1
  74. package/dist/application/ProcessSampling.js +15 -11
  75. package/dist/application/ProjectPermissionStore.js +49 -9
  76. package/dist/application/RealHopperAssertions.js +76 -0
  77. package/dist/application/ReconstructionCoverageService.js +69 -0
  78. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  79. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  80. package/dist/application/Setup.js +147 -259
  81. package/dist/application/SetupClientConfiguration.js +220 -0
  82. package/dist/application/SetupClients.js +24 -2
  83. package/dist/application/SetupPlan.js +123 -12
  84. package/dist/application/SetupSkill.js +26 -12
  85. package/dist/application/SupportedClients.js +1 -0
  86. package/dist/application/Uninstall.js +6 -3
  87. package/dist/application/WindowsCapabilities.js +86 -0
  88. package/dist/application/runtime.js +2 -0
  89. package/dist/artifacts/AsarArtifactReader.js +11 -0
  90. package/dist/browser/BrowserProcessStartup.js +88 -0
  91. package/dist/browser/CdpCaptureDocuments.js +12 -8
  92. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  93. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  94. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  95. package/dist/browser/CdpCaptureEventState.js +1 -0
  96. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  97. package/dist/browser/CdpCaptureEvents.js +46 -464
  98. package/dist/browser/CdpElectronInspection.js +106 -162
  99. package/dist/browser/CdpElectronProvider.js +5 -1
  100. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  101. package/dist/browser/CdpElectronScripts.js +94 -0
  102. package/dist/browser/CdpElectronWorkers.js +56 -0
  103. package/dist/browser/CdpObservationSession.js +51 -8
  104. package/dist/browser/CdpPageCapture.js +12 -129
  105. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  106. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  107. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  108. package/dist/browser/PngVisualDiff.js +9 -2
  109. package/dist/catalogIdentity.js +8 -1
  110. package/dist/cli/artifactCommands.js +82 -0
  111. package/dist/cli/coreAnalysisCommands.js +232 -0
  112. package/dist/cli/managedCommands.js +397 -0
  113. package/dist/cli/managedProjectGraphCommand.js +24 -0
  114. package/dist/cli/options.js +9 -0
  115. package/dist/cli/setupCommands.js +108 -0
  116. package/dist/cli/types.js +1 -0
  117. package/dist/cli/utilityCommands.js +122 -0
  118. package/dist/cli.js +13 -383
  119. package/dist/cliApplicationCommands.js +176 -0
  120. package/dist/cliBrowserAdvancedCommands.js +73 -16
  121. package/dist/cliBrowserCommands.js +39 -115
  122. package/dist/cliCommandNames.js +17 -0
  123. package/dist/cliElectronCommands.js +100 -27
  124. package/dist/cliEvidenceCommands.js +13 -2
  125. package/dist/cliInvestigationCommands.js +53 -10
  126. package/dist/cliJsonInput.js +54 -0
  127. package/dist/cliObservationOptions.js +137 -0
  128. package/dist/cliPolicyCommands.js +80 -46
  129. package/dist/cliSetup.js +289 -0
  130. package/dist/config/environment.js +107 -0
  131. package/dist/config/parseConfig.js +228 -0
  132. package/dist/config/parsers.js +68 -0
  133. package/dist/config/permissions.js +30 -0
  134. package/dist/config/types.js +1 -0
  135. package/dist/config.js +1 -292
  136. package/dist/contracts/applicationToolContracts.js +225 -0
  137. package/dist/contracts/artifactToolContracts.js +5 -9
  138. package/dist/contracts/browserToolContracts.js +14 -62
  139. package/dist/contracts/electronToolContracts.js +45 -19
  140. package/dist/contracts/errorSchemas.js +1 -0
  141. package/dist/contracts/investigationExamples.js +0 -6
  142. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  143. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  144. package/dist/contracts/managedToolContracts.js +153 -0
  145. package/dist/contracts/managedWorkflowExamples.js +346 -0
  146. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  147. package/dist/contracts/nativeToolContracts.js +2 -6
  148. package/dist/contracts/promptContracts.js +18 -2
  149. package/dist/contracts/providerSelection.js +2 -0
  150. package/dist/contracts/toolContractExamples.js +10 -25
  151. package/dist/contracts/toolContracts.js +49 -47
  152. package/dist/contracts/toolEffects.js +174 -0
  153. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  154. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  155. package/dist/contracts/toolOutputSchemas.js +2 -535
  156. package/dist/doctorRuntime.js +42 -1
  157. package/dist/domain/analysisErrorPresentation.js +234 -0
  158. package/dist/domain/analysisErrorProjection.js +284 -0
  159. package/dist/domain/artifactComparison.js +37 -19
  160. package/dist/domain/binaryTarget.js +87 -37
  161. package/dist/domain/browserObservation.js +1 -282
  162. package/dist/domain/browserObservationSchemas.js +286 -0
  163. package/dist/domain/bundleComparison.js +4 -4
  164. package/dist/domain/electronObservation.js +13 -0
  165. package/dist/domain/electronStaticAnalysis.js +9 -0
  166. package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
  167. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  168. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  169. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  170. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  171. package/dist/domain/errors.js +32 -448
  172. package/dist/domain/functionComparison.js +4 -165
  173. package/dist/domain/functionComparisonDimensions.js +164 -0
  174. package/dist/domain/functionComparisonSchemas.js +3 -8
  175. package/dist/domain/inputIssueProjection.js +52 -0
  176. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  177. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  178. package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
  179. package/dist/domain/javascriptApplicationGraph.js +2 -1
  180. package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
  181. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  182. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  183. package/dist/domain/javascriptApplicationVersionItems.js +233 -0
  184. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  185. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  186. package/dist/domain/javascriptFeatureSeed.js +140 -0
  187. package/dist/domain/javascriptFeatureTrace.js +232 -0
  188. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  189. package/dist/domain/javascriptFeatureTraversal.js +100 -0
  190. package/dist/domain/javascriptNativeHandoff.js +85 -0
  191. package/dist/domain/javascriptReplay.js +361 -0
  192. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  193. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  194. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  195. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  196. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  197. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  198. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  199. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  200. package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
  201. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  202. package/dist/domain/javascriptSemanticIr.js +30 -0
  203. package/dist/domain/javascriptSemanticProjection.js +366 -0
  204. package/dist/domain/javascriptSemanticState.js +40 -0
  205. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  206. package/dist/domain/javascriptSemanticValues.js +352 -0
  207. package/dist/domain/javascriptStaticAnalysis.js +26 -254
  208. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  209. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  210. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  211. package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
  212. package/dist/domain/javascriptStaticAnalysisState.js +6 -0
  213. package/dist/domain/knownPageCoverage.js +21 -0
  214. package/dist/domain/managedApplicationGraph.js +206 -0
  215. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  216. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  217. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  218. package/dist/domain/managedArtifact.js +452 -0
  219. package/dist/domain/managedMemberComparison.js +211 -0
  220. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  221. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  222. package/dist/domain/managedNativeVerification.js +46 -0
  223. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  224. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  225. package/dist/domain/managedReconstruction.js +196 -0
  226. package/dist/domain/managedRuntimeCorrelation.js +184 -0
  227. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  228. package/dist/domain/permissionPolicy.js +2 -0
  229. package/dist/domain/reconstructionCoverage.js +387 -0
  230. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  231. package/dist/domain/reconstructionVerificationSchemas.js +9 -3
  232. package/dist/domain/runtimeCharacterization.js +85 -0
  233. package/dist/domain/webBundleAnalyzer.js +3 -409
  234. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  235. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  236. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  237. package/dist/dotnet/ManagedArtifactInspector.js +339 -0
  238. package/dist/dotnet/ManagedMemberInspector.js +153 -0
  239. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  240. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  241. package/dist/dotnet/ManagedMemberRows.js +120 -0
  242. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  243. package/dist/dotnet/ManagedMetadataInventory.js +104 -0
  244. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  245. package/dist/dotnet/ManagedMetadataLayout.js +259 -0
  246. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  247. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  248. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  249. package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
  250. package/dist/dotnet/ManagedPeReader.js +188 -0
  251. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  252. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  253. package/dist/generatedPackageMetadata.js +2 -2
  254. package/dist/ghidra/GhidraClient.js +76 -91
  255. package/dist/ghidra/GhidraClientStartup.js +29 -0
  256. package/dist/ghidra/GhidraClientWire.js +34 -0
  257. package/dist/ghidra/GhidraDefaults.js +1 -1
  258. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  259. package/dist/ghidra/GhidraInstallation.js +20 -15
  260. package/dist/ghidra/GhidraLauncher.js +93 -29
  261. package/dist/ghidra/GhidraProvider.js +67 -161
  262. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  263. package/dist/ghidra/GhidraSessionValues.js +2 -0
  264. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  265. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  266. package/dist/ghidra/GhidraTransport.js +71 -0
  267. package/dist/identity.js +3 -2
  268. package/dist/main/messages.js +5 -0
  269. package/dist/main/reload.js +49 -0
  270. package/dist/main/shutdown.js +25 -0
  271. package/dist/main/startup.js +14 -0
  272. package/dist/main/state.js +26 -0
  273. package/dist/main/transport.js +61 -0
  274. package/dist/main/types.js +1 -0
  275. package/dist/main.js +35 -132
  276. package/dist/process/PrivateRuntimeRoot.js +3 -2
  277. package/dist/process/ProcessOwnership.js +35 -0
  278. package/dist/process/ProviderProcess.js +2 -0
  279. package/dist/replay/JavaScriptReplayWorker.js +300 -0
  280. package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
  281. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  282. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  283. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  284. package/dist/replay/ReplayOutcome.js +95 -0
  285. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  286. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  287. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  288. package/dist/server/ProcessCaptureElicitation.js +157 -0
  289. package/dist/server/createServer.js +158 -41
  290. package/dist/server/registerApplicationTools/characterization.js +57 -0
  291. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  292. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  293. package/dist/server/registerApplicationTools/coverage.js +84 -0
  294. package/dist/server/registerApplicationTools/helpers.js +42 -0
  295. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  296. package/dist/server/registerApplicationTools/types.js +1 -0
  297. package/dist/server/registerApplicationTools.js +13 -0
  298. package/dist/server/registerArtifactComparisonTool.js +16 -9
  299. package/dist/server/registerBrowserTools.js +61 -60
  300. package/dist/server/registerBundleComparisonTool.js +17 -20
  301. package/dist/server/registerElectronTools.js +39 -12
  302. package/dist/server/registerEnhancedTools.js +52 -15
  303. package/dist/server/registerEvidenceResources.js +54 -0
  304. package/dist/server/registerEvidenceTools.js +5 -1
  305. package/dist/server/registerFunctionComparisonTool.js +14 -7
  306. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  307. package/dist/server/registerInvestigationTools/types.js +1 -0
  308. package/dist/server/registerInvestigationTools.js +103 -132
  309. package/dist/server/registerManagedTools.js +6 -0
  310. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  311. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  312. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  313. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  314. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  315. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  316. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  317. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  318. package/dist/server/registerManagedWorkflowTools.js +13 -0
  319. package/dist/server/registerOfficialTools.js +81 -67
  320. package/dist/server/registerProcessComparisonTool.js +25 -47
  321. package/dist/server/registerSessionRecordTools.js +137 -0
  322. package/dist/server/registerSessionStatusTool.js +9 -8
  323. package/dist/server/registerSessionTools.js +77 -216
  324. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  325. package/dist/server/sessionEvidence.js +14 -19
  326. package/dist/server/toolInputValidation.js +77 -0
  327. package/dist/server/toolRegistrationOptions.js +177 -2
  328. package/dist/server/toolResult.js +30 -17
  329. package/package.json +21 -14
  330. package/scripts/rea.mjs +1 -1
  331. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
  332. package/scripts/prepare-node-pty.mjs +0 -35
  333. package/scripts/rebuild-native.mjs +0 -22
@@ -0,0 +1,352 @@
1
+ import * as t from "@babel/types";
2
+ import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
3
+ import { compareCodePoints, propertyName, stringValue, } from "./javascriptStaticAnalysisHelpers.js";
4
+ /** Evaluate one binding in the bounded constant-value lattice. */
5
+ export const evaluateSemanticBinding = (binding, state) => evaluateBinding(binding, { state, bindings: new Set(), depth: 0 });
6
+ /** Follow module provenance through destructuring, members, and aliases. */
7
+ export const evaluateSemanticProvenance = (binding, state) => provenanceForBinding(binding, { state, bindings: new Set(), depth: 0 });
8
+ const evaluateBinding = (binding, context) => {
9
+ if (context.bindings.has(binding.bindingId))
10
+ return { status: "cycle", reason: `Alias cycle at ${binding.name}.` };
11
+ if (context.depth >= context.state.limits.maxValueDepth)
12
+ return limitValue(context.state, "maxValueDepth");
13
+ if (binding.initializers.length === 0)
14
+ return {
15
+ status: "unknown",
16
+ reason: `Binding ${binding.name} has no constant initializer.`,
17
+ };
18
+ if (binding.initializers.length > 1)
19
+ return {
20
+ status: "ambiguous",
21
+ reason: `Binding ${binding.name} has multiple possible assignments.`,
22
+ };
23
+ const initializer = binding.initializers[0];
24
+ if (initializer === undefined)
25
+ return { status: "unknown", reason: "Missing binding initializer." };
26
+ const nested = nestedContext(context, binding.bindingId);
27
+ return projectValue(evaluateExpression(initializer.node, nested), initializer.projection);
28
+ };
29
+ const evaluateExpression = (node, context) => {
30
+ if (context.depth >= context.state.limits.maxValueDepth)
31
+ return limitValue(context.state, "maxValueDepth");
32
+ const literal = primitiveValue(node);
33
+ if (literal.found)
34
+ return { status: "literal", value: literal.value };
35
+ if (t.isIdentifier(node)) {
36
+ const binding = resolveSemanticBindingState(context.state, node, node.name);
37
+ return binding === undefined
38
+ ? { status: "unknown", reason: `Unbound identifier ${node.name}.` }
39
+ : evaluateBinding(binding, nestedContext(context));
40
+ }
41
+ if (t.isTemplateLiteral(node))
42
+ return evaluateTemplate(node, context);
43
+ if (t.isConditionalExpression(node))
44
+ return mergeValues([
45
+ evaluateExpression(node.consequent, nestedContext(context)),
46
+ evaluateExpression(node.alternate, nestedContext(context)),
47
+ ], context.state);
48
+ if (t.isLogicalExpression(node))
49
+ return mergeValues([
50
+ evaluateExpression(node.left, nestedContext(context)),
51
+ evaluateExpression(node.right, nestedContext(context)),
52
+ ], context.state);
53
+ if (t.isObjectExpression(node))
54
+ return evaluateObject(node, context);
55
+ if (t.isArrayExpression(node))
56
+ return evaluateArray(node, context);
57
+ if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node))
58
+ return evaluateMember(node, context);
59
+ if (t.isBinaryExpression(node, { operator: "+" }))
60
+ return evaluateAddition(node, context);
61
+ if (t.isUnaryExpression(node))
62
+ return evaluateUnary(node, context);
63
+ if ((t.isTSAsExpression(node) ||
64
+ t.isTSTypeAssertion(node) ||
65
+ t.isTSNonNullExpression(node)) &&
66
+ t.isExpression(node.expression))
67
+ return evaluateExpression(node.expression, nestedContext(context));
68
+ return { status: "unknown", reason: `Unsupported ${node.type} value.` };
69
+ };
70
+ const evaluateTemplate = (node, context) => {
71
+ let candidates = [""];
72
+ for (let index = 0; index < node.quasis.length; index += 1) {
73
+ const quasi = node.quasis[index];
74
+ const text = quasi?.value.cooked ?? quasi?.value.raw ?? "";
75
+ candidates = candidates.map((prefix) => `${prefix}${text}`);
76
+ const expression = node.expressions[index];
77
+ if (expression === undefined)
78
+ continue;
79
+ const values = primitiveCandidates(evaluateExpression(expression, nestedContext(context)));
80
+ if (values === null)
81
+ return {
82
+ status: "unknown",
83
+ reason: "Template expression is not a bounded primitive.",
84
+ };
85
+ candidates = candidates.flatMap((prefix) => values.map((value) => `${prefix}${String(value)}`));
86
+ if (candidates.length > context.state.limits.maxUnionValues)
87
+ return limitValue(context.state, "maxUnionValues");
88
+ }
89
+ return primitiveSet(candidates, context.state);
90
+ };
91
+ const evaluateObject = (node, context) => {
92
+ const properties = [];
93
+ let unknownProperties = false;
94
+ for (const property of node.properties) {
95
+ if (t.isSpreadElement(property) || property.computed) {
96
+ unknownProperties = true;
97
+ continue;
98
+ }
99
+ const name = propertyName(property.key);
100
+ if (name === "" || !t.isObjectProperty(property)) {
101
+ unknownProperties = true;
102
+ continue;
103
+ }
104
+ if (properties.length >= context.state.limits.maxObjectProperties) {
105
+ markLimit(context.state, "maxObjectProperties");
106
+ unknownProperties = true;
107
+ continue;
108
+ }
109
+ properties.push({
110
+ name,
111
+ value: evaluateExpression(property.value, nestedContext(context)),
112
+ });
113
+ }
114
+ properties.sort((left, right) => compareCodePoints(left.name, right.name));
115
+ return { status: "object", properties, unknownProperties };
116
+ };
117
+ const evaluateArray = (node, context) => {
118
+ const items = [];
119
+ let unknownItems = false;
120
+ for (const element of node.elements) {
121
+ if (element === null || t.isSpreadElement(element)) {
122
+ unknownItems = true;
123
+ continue;
124
+ }
125
+ if (items.length >= context.state.limits.maxObjectProperties) {
126
+ markLimit(context.state, "maxObjectProperties");
127
+ unknownItems = true;
128
+ continue;
129
+ }
130
+ items.push(evaluateExpression(element, nestedContext(context)));
131
+ }
132
+ return { status: "array", items, unknownItems };
133
+ };
134
+ const evaluateMember = (node, context) => {
135
+ if (!t.isNode(node.object))
136
+ return { status: "unknown", reason: "Unsupported member base." };
137
+ const key = memberKey(node);
138
+ if (key === undefined)
139
+ return { status: "unknown", reason: "Dynamic member key." };
140
+ return projectValue(evaluateExpression(node.object, nestedContext(context)), [
141
+ key,
142
+ ]);
143
+ };
144
+ const evaluateAddition = (node, context) => {
145
+ const left = primitiveCandidates(evaluateExpression(node.left, nestedContext(context)));
146
+ const right = primitiveCandidates(evaluateExpression(node.right, nestedContext(context)));
147
+ if (left === null || right === null)
148
+ return { status: "unknown", reason: "Non-primitive addition." };
149
+ const values = left.flatMap((leftValue) => right.map((rightValue) => typeof leftValue === "number" && typeof rightValue === "number"
150
+ ? leftValue + rightValue
151
+ : `${String(leftValue)}${String(rightValue)}`));
152
+ return primitiveSet(values, context.state);
153
+ };
154
+ const evaluateUnary = (node, context) => {
155
+ const argument = primitiveCandidates(evaluateExpression(node.argument, nestedContext(context)));
156
+ if (argument === null)
157
+ return { status: "unknown", reason: "Non-primitive unary operand." };
158
+ if (node.operator === "!")
159
+ return primitiveSet(argument.map((value) => !value), context.state);
160
+ if (node.operator === "+")
161
+ return primitiveSet(argument.map((value) => Number(value)), context.state);
162
+ if (node.operator === "-")
163
+ return primitiveSet(argument.map((value) => -Number(value)), context.state);
164
+ return { status: "unknown", reason: `Unsupported unary ${node.operator}.` };
165
+ };
166
+ const projectValue = (value, projection) => {
167
+ let current = value;
168
+ for (const key of projection) {
169
+ if (key === null)
170
+ return {
171
+ status: "unknown",
172
+ reason: "Cannot project a dynamic property.",
173
+ };
174
+ if (current.status === "object" && typeof key === "string") {
175
+ const property = current.properties.find(({ name }) => name === key);
176
+ if (property === undefined)
177
+ return {
178
+ status: current.unknownProperties ? "unknown" : "unknown",
179
+ reason: `Object property ${key} was not observed.`,
180
+ };
181
+ current = property.value;
182
+ }
183
+ else if (current.status === "array" && typeof key === "number") {
184
+ const item = current.items[key];
185
+ if (item === undefined)
186
+ return {
187
+ status: "unknown",
188
+ reason: `Array item ${String(key)} missing.`,
189
+ };
190
+ current = item;
191
+ }
192
+ else
193
+ return {
194
+ status: "unknown",
195
+ reason: `Cannot project ${String(key)} from ${current.status}.`,
196
+ };
197
+ }
198
+ return current;
199
+ };
200
+ const provenanceForBinding = (binding, context) => {
201
+ if (context.bindings.has(binding.bindingId))
202
+ return provenance("cycle", [], `Alias cycle at ${binding.name}.`);
203
+ if (context.depth >= context.state.limits.maxValueDepth)
204
+ return limitProvenance(context.state, "maxValueDepth");
205
+ if (binding.directOrigins.length > 0)
206
+ return originsProvenance(binding.directOrigins, context.state);
207
+ if (binding.initializers.length === 0)
208
+ return provenance("local", [], null);
209
+ if (binding.initializers.length > 1)
210
+ return provenance("ambiguous", [], `Binding ${binding.name} has multiple possible assignments.`);
211
+ const initializer = binding.initializers[0];
212
+ if (initializer === undefined)
213
+ return provenance("unknown", [], "Missing binding initializer.");
214
+ if (initializer.projection.includes(null))
215
+ return provenance("unknown", [], "Dynamic provenance projection.");
216
+ const resolved = provenanceForExpression(initializer.node, nestedContext(context, binding.bindingId));
217
+ if (resolved.status !== "module" || initializer.projection.length === 0)
218
+ return resolved;
219
+ return originsProvenance(resolved.origins.map((origin) => ({
220
+ ...origin,
221
+ importedPath: [
222
+ ...origin.importedPath,
223
+ ...initializer.projection.map((segment) => String(segment)),
224
+ ],
225
+ })), context.state);
226
+ };
227
+ const provenanceForExpression = (node, context) => {
228
+ const required = requireOrigin(node);
229
+ if (required !== undefined)
230
+ return originsProvenance([required], context.state);
231
+ if (t.isIdentifier(node)) {
232
+ const binding = resolveSemanticBindingState(context.state, node, node.name);
233
+ return binding === undefined
234
+ ? provenance("unknown", [], `Unbound identifier ${node.name}.`)
235
+ : provenanceForBinding(binding, nestedContext(context));
236
+ }
237
+ if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
238
+ if (!t.isNode(node.object))
239
+ return provenance("unknown", [], "Unsupported member base.");
240
+ const member = memberKey(node);
241
+ if (typeof member !== "string")
242
+ return provenance("unknown", [], "Dynamic provenance member.");
243
+ const base = provenanceForExpression(node.object, nestedContext(context));
244
+ return base.status !== "module"
245
+ ? base
246
+ : originsProvenance(base.origins.map((origin) => ({
247
+ ...origin,
248
+ importedPath: [...origin.importedPath, member],
249
+ })), context.state);
250
+ }
251
+ if (t.isConditionalExpression(node) || t.isLogicalExpression(node)) {
252
+ const left = t.isConditionalExpression(node) ? node.consequent : node.left;
253
+ const right = t.isConditionalExpression(node) ? node.alternate : node.right;
254
+ const candidates = [
255
+ provenanceForExpression(left, nestedContext(context)),
256
+ provenanceForExpression(right, nestedContext(context)),
257
+ ];
258
+ const origins = candidates.flatMap((candidate) => candidate.origins);
259
+ return origins.length > 0
260
+ ? provenance("ambiguous", uniqueOrigins(origins), "Multiple module origins.")
261
+ : provenance("unknown", [], "Conditional provenance is unresolved.");
262
+ }
263
+ return provenance("local", [], null);
264
+ };
265
+ const requireOrigin = (node) => {
266
+ if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
267
+ if (!t.isNode(node.object))
268
+ return undefined;
269
+ const nested = requireOrigin(node.object);
270
+ const member = memberKey(node);
271
+ return nested === undefined || typeof member !== "string"
272
+ ? undefined
273
+ : { ...nested, importedPath: [...nested.importedPath, member] };
274
+ }
275
+ if (!t.isCallExpression(node) ||
276
+ !t.isIdentifier(node.callee, { name: "require" }))
277
+ return undefined;
278
+ const specifier = stringValue(node.arguments[0]);
279
+ return specifier === undefined ? undefined : { specifier, importedPath: [] };
280
+ };
281
+ const mergeValues = (values, state) => {
282
+ const primitives = values.flatMap((value) => primitiveCandidates(value) ?? []);
283
+ return primitives.length === values.length ||
284
+ values.every((value) => value.status === "union" || value.status === "literal")
285
+ ? primitiveSet(primitives, state)
286
+ : { status: "ambiguous", reason: "Branches have incompatible values." };
287
+ };
288
+ const primitiveSet = (values, state) => {
289
+ const unique = [
290
+ ...new Map(values.map((value) => [primitiveKey(value), value])).values(),
291
+ ].sort((left, right) => compareCodePoints(primitiveKey(left), primitiveKey(right)));
292
+ if (unique.length > state.limits.maxUnionValues)
293
+ return limitValue(state, "maxUnionValues");
294
+ const only = unique[0];
295
+ return unique.length === 1 && only !== undefined
296
+ ? { status: "literal", value: only }
297
+ : { status: "union", values: unique };
298
+ };
299
+ const primitiveCandidates = (value) => value.status === "literal"
300
+ ? [value.value]
301
+ : value.status === "union"
302
+ ? value.values
303
+ : null;
304
+ const primitiveValue = (node) => {
305
+ if (t.isStringLiteral(node) || t.isNumericLiteral(node))
306
+ return { found: true, value: node.value };
307
+ if (t.isBooleanLiteral(node))
308
+ return { found: true, value: node.value };
309
+ if (t.isNullLiteral(node))
310
+ return { found: true, value: null };
311
+ return { found: false };
312
+ };
313
+ const memberKey = (node) => {
314
+ if (!node.computed)
315
+ return propertyName(node.property) || undefined;
316
+ if (t.isStringLiteral(node.property) || t.isNumericLiteral(node.property))
317
+ return node.property.value;
318
+ return undefined;
319
+ };
320
+ const originsProvenance = (origins, state) => {
321
+ const unique = uniqueOrigins(origins);
322
+ if (unique.length > state.limits.maxUnionValues)
323
+ return limitProvenance(state, "maxUnionValues");
324
+ return unique.length === 1
325
+ ? provenance("module", unique, null)
326
+ : provenance("ambiguous", unique, "Multiple module origins.");
327
+ };
328
+ const uniqueOrigins = (origins) => [
329
+ ...new Map(origins.map((origin) => [originKey(origin), origin])).values(),
330
+ ].sort((left, right) => compareCodePoints(originKey(left), originKey(right)));
331
+ const provenance = (status, origins, reason) => ({ status, origins, reason });
332
+ const limitValue = (state, limit) => {
333
+ markLimit(state, limit);
334
+ return { status: "limit-reached", reason: `${limit} reached.` };
335
+ };
336
+ const limitProvenance = (state, limit) => {
337
+ markLimit(state, limit);
338
+ return provenance("limit-reached", [], `${limit} reached.`);
339
+ };
340
+ const markLimit = (state, limit) => {
341
+ state.limitsReached.add(limit);
342
+ state.omittedCount += 1;
343
+ };
344
+ const nestedContext = (context, bindingId) => ({
345
+ state: context.state,
346
+ depth: context.depth + 1,
347
+ bindings: bindingId === undefined
348
+ ? context.bindings
349
+ : new Set([...context.bindings, bindingId]),
350
+ });
351
+ const primitiveKey = (value) => `${value === null ? "null" : typeof value}:${JSON.stringify(value)}`;
352
+ const originKey = (origin) => `${origin.specifier}\0${origin.importedPath.join("\0")}`;
@@ -1,7 +1,10 @@
1
1
  import { parse } from "@babel/parser";
2
2
  import * as t from "@babel/types";
3
- import { collectJavaScriptExports, fingerprintJavaScriptAst, } from "./javascriptAstFingerprint.js";
4
- import { STATIC_ROUTE_CALL_NAMES, argumentValue, calleeName, chunkRuntime, compareCodePoints, detectVendors, endpointArgument, failedJavaScriptStaticAnalysis, factoryRequireName, moduleFactory, modulePropertyName, prefixedArgument, propertyName, range, rangeForOffsets, registrationKey, sanitizeCandidate, sha256Text, sortedUnique, sourceSlice, staticArrayValues, staticPath, storageKind, stringValue, } from "./javascriptStaticAnalysisHelpers.js";
3
+ import { inspectElectronStaticNode } from "./electronStaticAnalysis.js";
4
+ import { detectVendors, failedJavaScriptStaticAnalysis, registrationKey, sortedUnique, stringValue, } from "./javascriptStaticAnalysisHelpers.js";
5
+ import { addReference, addSourceMapDirectives, inspectCall, inspectRouteProperty, inspectRoleProperty, } from "./javascriptStaticAnalysisCalls.js";
6
+ import { inspectBundlerRegistration } from "./javascriptStaticAnalysisBundler.js";
7
+ import { finalizeLocatedFindings } from "./javascriptStaticAnalysisFindings.js";
5
8
  import { createJavaScriptAnalysisAccumulator, } from "./javascriptStaticAnalysisState.js";
6
9
  /** Parse one bounded JavaScript artifact and recover static structure only. */
7
10
  export const analyzeJavaScriptStaticSource = (source, limits) => {
@@ -17,6 +20,11 @@ export const analyzeJavaScriptStaticSource = (source, limits) => {
17
20
  return failedJavaScriptStaticAnalysis();
18
21
  }
19
22
  const accumulator = createJavaScriptAnalysisAccumulator();
23
+ traverseStaticSource(source, file, accumulator, limits);
24
+ addSourceMapDirectives(source, accumulator, limits.maxFindings);
25
+ return finalizeStaticAnalysis(source, file, accumulator, limits);
26
+ };
27
+ const traverseStaticSource = (source, file, accumulator, limits) => {
20
28
  if (limits.now() > limits.deadline)
21
29
  accumulator.truncated = true;
22
30
  if (!accumulator.truncated)
@@ -31,7 +39,8 @@ export const analyzeJavaScriptStaticSource = (source, limits) => {
31
39
  inspectNode(source, node, accumulator, limits);
32
40
  return undefined;
33
41
  });
34
- addSourceMapDirectives(source, accumulator, limits.maxFindings);
42
+ };
43
+ const finalizeStaticAnalysis = (source, file, accumulator, limits) => {
35
44
  const parserErrors = file.errors.length;
36
45
  const limitations = [
37
46
  ...(parserErrors === 0
@@ -51,7 +60,7 @@ export const analyzeJavaScriptStaticSource = (source, limits) => {
51
60
  ...(accumulator.unknownFindings === 0
52
61
  ? []
53
62
  : [
54
- "One or more bundler registration keys were dynamic and remain unknown.",
63
+ "One or more static keys, expressions, or Electron boundary values were dynamic and remain unknown.",
55
64
  ]),
56
65
  "JavaScript syntax was parsed as data and was never evaluated.",
57
66
  ];
@@ -64,13 +73,21 @@ export const analyzeJavaScriptStaticSource = (source, limits) => {
64
73
  parse_error_count: parserErrors,
65
74
  visited_ast_nodes: Math.min(accumulator.visitedNodes, limits.maxAstNodes),
66
75
  dropped_findings: accumulator.droppedFindings,
67
- references: finalizeLocated(accumulator.references, accumulator.modules),
68
- endpoints: finalizeLocated(accumulator.endpoints, accumulator.modules),
69
- storage: finalizeLocated(accumulator.storage, accumulator.modules),
76
+ references: finalizeLocatedFindings(accumulator.references, accumulator.modules),
77
+ endpoints: finalizeLocatedFindings(accumulator.endpoints, accumulator.modules),
78
+ storage: finalizeLocatedFindings(accumulator.storage, accumulator.modules),
70
79
  bundler_registrations: sortedUnique(accumulator.registrations, registrationKey),
71
- role_paths: finalizeLocated(accumulator.roles, accumulator.modules),
80
+ role_paths: finalizeLocatedFindings(accumulator.roles, accumulator.modules),
72
81
  source_map_urls: accumulator.sourceMaps,
73
82
  vendors: detectVendors(source),
83
+ electron: {
84
+ browser_windows: finalizeLocatedFindings(accumulator.browserWindows, accumulator.modules),
85
+ context_bridge_apis: finalizeLocatedFindings(accumulator.contextBridgeApis, accumulator.modules),
86
+ ipc: finalizeLocatedFindings(accumulator.ipc, accumulator.modules),
87
+ sender_validations: finalizeLocatedFindings(accumulator.senderValidations, accumulator.modules),
88
+ utility_processes: finalizeLocatedFindings(accumulator.utilityProcesses, accumulator.modules),
89
+ native_addon_bindings: finalizeLocatedFindings(accumulator.nativeAddonBindings, accumulator.modules),
90
+ },
74
91
  limitations,
75
92
  };
76
93
  };
@@ -80,6 +97,7 @@ const inspectNode = (source, node, accumulator, limits) => {
80
97
  accumulator,
81
98
  maximum: limits.maxFindings,
82
99
  };
100
+ inspectElectronStaticNode(node, findings);
83
101
  if (t.isCallExpression(node)) {
84
102
  inspectBundlerRegistration(source, node, accumulator, limits);
85
103
  inspectCall(node, findings);
@@ -110,249 +128,3 @@ const inspectNode = (source, node, accumulator, limits) => {
110
128
  inspectRoleProperty(node, findings);
111
129
  }
112
130
  };
113
- const inspectCall = (node, context) => {
114
- const { accumulator } = context;
115
- const name = calleeName(node.callee);
116
- const first = stringValue(node.arguments[0]);
117
- const module = moduleAt(node.start, accumulator.modules);
118
- const moduleRequire = module?.requireName !== null && name === module?.requireName;
119
- if (name === "require" ||
120
- name.endsWith(".require") ||
121
- name.includes("__webpack_require__") ||
122
- moduleRequire)
123
- addReference(context, {
124
- node,
125
- kind: "require",
126
- specifier: argumentValue(node.arguments[0]),
127
- });
128
- if (name.endsWith(".e") && name.includes("require"))
129
- addReference(context, {
130
- node,
131
- kind: "dynamic-import",
132
- specifier: prefixedArgument("chunk:", node.arguments[0]),
133
- });
134
- if (name === "Worker" || name.endsWith(".Worker"))
135
- addReference(context, { node, kind: "worker", specifier: first });
136
- if (name.endsWith("serviceWorker.register"))
137
- addReference(context, { node, kind: "service-worker", specifier: first });
138
- inspectEndpointCall(node, name, first, context);
139
- inspectStorageCall(node, name, first, context);
140
- if (name.endsWith("loadFile") && first !== undefined)
141
- addLocated(context, {
142
- collection: accumulator.roles,
143
- key: `role\0renderer\0${first}`,
144
- node,
145
- value: {
146
- role: "renderer",
147
- path: first,
148
- mechanism: `call:${name}`,
149
- module_key: null,
150
- location: range(node),
151
- },
152
- });
153
- };
154
- const inspectBundlerRegistration = (source, call, accumulator, limits) => {
155
- const runtime = chunkRuntime(call);
156
- const entry = call.arguments[0];
157
- if (runtime === undefined || !t.isArrayExpression(entry))
158
- return;
159
- const chunkIds = entry.elements[0];
160
- const table = entry.elements[1];
161
- if (!t.isArrayExpression(chunkIds) || !t.isObjectExpression(table))
162
- return;
163
- const modules = [];
164
- for (const property of table.properties) {
165
- const factory = moduleFactory(property);
166
- if (factory === undefined)
167
- continue;
168
- if (accumulator.moduleCount >= limits.maxModules) {
169
- accumulator.droppedFindings += 1;
170
- continue;
171
- }
172
- accumulator.moduleCount += 1;
173
- const key = modulePropertyName(property);
174
- if (key.startsWith("[computed@") || key.startsWith("[unknown@"))
175
- accumulator.unknownFindings += 1;
176
- const exactSource = sourceSlice(source, factory);
177
- const fingerprint = fingerprintJavaScriptAst(factory, Math.min(limits.maxAstNodes, 100_000));
178
- const exportsValue = collectJavaScriptExports(factory, 256);
179
- if (fingerprint.truncated || exportsValue.truncated) {
180
- accumulator.droppedFindings += 1;
181
- accumulator.structuralTruncation = true;
182
- }
183
- modules.push({
184
- module_key: key,
185
- source_sha256: sha256Text(exactSource),
186
- structural_fingerprint_sha256: fingerprint.truncated
187
- ? null
188
- : fingerprint.sha256,
189
- structural_fingerprint_algorithm: fingerprint.truncated
190
- ? null
191
- : "babel-ast-v1",
192
- structural_fingerprint_status: fingerprint.truncated
193
- ? "truncated"
194
- : "complete",
195
- exports: exportsValue.values,
196
- exports_truncated: exportsValue.truncated,
197
- location: range(factory),
198
- });
199
- if (typeof factory.start === "number" && typeof factory.end === "number")
200
- accumulator.modules.push({
201
- start: factory.start,
202
- end: factory.end,
203
- key,
204
- requireName: factoryRequireName(factory),
205
- });
206
- }
207
- const chunkKeys = staticArrayValues(chunkIds, Math.min(256, limits.maxFindings));
208
- if (chunkKeys.omitted > 0) {
209
- accumulator.droppedFindings += chunkKeys.omitted;
210
- accumulator.structuralTruncation = true;
211
- }
212
- accumulator.unknownFindings += chunkKeys.unknown;
213
- const registration = {
214
- bundler: runtime.toLowerCase().includes("rspack")
215
- ? "rspack"
216
- : "webpack",
217
- runtime,
218
- chunk_keys: chunkKeys.values,
219
- omitted_chunk_keys: chunkKeys.omitted,
220
- unknown_chunk_keys: chunkKeys.unknown,
221
- modules: modules.sort((left, right) => compareCodePoints(left.module_key, right.module_key)),
222
- location: range(call),
223
- };
224
- addBounded(accumulator, `registration\0${registrationKey(registration)}`, limits.maxFindings, () => accumulator.registrations.push(registration));
225
- };
226
- const inspectEndpointCall = (node, name, first, context) => {
227
- const route = STATIC_ROUTE_CALL_NAMES.some((candidate) => name === candidate || name.endsWith(`.${candidate}`));
228
- if (route && first !== undefined)
229
- addEndpoint(context, {
230
- node,
231
- kind: "route",
232
- value: first,
233
- mechanism: `call:${name}`,
234
- });
235
- const endpoint = endpointArgument(name, node.arguments);
236
- if (endpoint !== undefined)
237
- addEndpoint(context, {
238
- node,
239
- kind: "network",
240
- value: endpoint,
241
- mechanism: `call:${name}`,
242
- });
243
- };
244
- const inspectRouteProperty = (node, context) => {
245
- const key = propertyName(node.key);
246
- if ((key === "path" || key === "route") && t.isStringLiteral(node.value))
247
- addEndpoint(context, {
248
- node,
249
- kind: "route",
250
- value: node.value.value,
251
- mechanism: `property:${key}`,
252
- });
253
- };
254
- const inspectRoleProperty = (node, context) => {
255
- if (propertyName(node.key) !== "preload")
256
- return;
257
- const path = staticPath(node.value);
258
- if (path === undefined)
259
- return;
260
- addLocated(context, {
261
- collection: context.accumulator.roles,
262
- key: `role\0preload\0${path}`,
263
- node,
264
- value: {
265
- role: "preload",
266
- path,
267
- mechanism: "property:preload",
268
- module_key: null,
269
- location: range(node),
270
- },
271
- });
272
- };
273
- const inspectStorageCall = (node, name, first, context) => {
274
- const storage = storageKind(name);
275
- if (storage === undefined)
276
- return;
277
- addLocated(context, {
278
- collection: context.accumulator.storage,
279
- key: `storage\0${storage}\0${first ?? ""}`,
280
- node,
281
- value: {
282
- kind: storage,
283
- name: first ?? null,
284
- mechanism: `call:${name}`,
285
- module_key: null,
286
- location: range(node),
287
- },
288
- });
289
- };
290
- const addReference = (context, input) => {
291
- const boundedSpecifier = input.specifier?.slice(0, 4_096) ?? null;
292
- const expression = boundedSpecifier === null
293
- ? sourceSlice(context.source, input.node).slice(0, 4_096)
294
- : null;
295
- addLocated(context, {
296
- collection: context.accumulator.references,
297
- key: `reference\0${input.kind}\0${boundedSpecifier ?? expression}`,
298
- node: input.node,
299
- value: {
300
- kind: input.kind,
301
- specifier: boundedSpecifier,
302
- expression,
303
- module_key: null,
304
- location: range(input.node),
305
- },
306
- });
307
- };
308
- const addEndpoint = (context, input) => addLocated(context, {
309
- collection: context.accumulator.endpoints,
310
- key: `endpoint\0${input.kind}\0${input.value}`,
311
- node: input.node,
312
- value: {
313
- kind: input.kind,
314
- value: sanitizeCandidate(input.value),
315
- mechanism: input.mechanism,
316
- module_key: null,
317
- location: range(input.node),
318
- },
319
- });
320
- const addLocated = (context, input) => addBounded(context.accumulator, `${input.key}\0${String(input.node.start)}`, context.maximum, () => input.collection.push({
321
- offset: input.node.start ?? -1,
322
- value: input.value,
323
- }));
324
- const addBounded = (accumulator, key, maximum, add) => {
325
- if (accumulator.seen.has(key))
326
- return;
327
- const count = accumulator.references.length +
328
- accumulator.endpoints.length +
329
- accumulator.storage.length +
330
- accumulator.roles.length +
331
- accumulator.sourceMaps.length +
332
- accumulator.registrations.length;
333
- if (count >= maximum) {
334
- accumulator.droppedFindings += 1;
335
- return;
336
- }
337
- accumulator.seen.add(key);
338
- add();
339
- };
340
- const finalizeLocated = (values, modules) => values.map(({ offset, value }) => ({
341
- ...value,
342
- module_key: moduleAt(offset, modules)?.key ?? null,
343
- }));
344
- const moduleAt = (offset, modules) => {
345
- if (offset === null || offset === undefined)
346
- return undefined;
347
- return modules.find(({ start, end }) => offset >= start && offset <= end);
348
- };
349
- const addSourceMapDirectives = (source, accumulator, maximum) => {
350
- for (const match of source.matchAll(/\/\/[#@]\s*sourceMappingURL\s*=\s*([^\s]+)/gu)) {
351
- const declared = match[1]?.slice(0, 4_096);
352
- if (declared === undefined)
353
- continue;
354
- const start = match.index;
355
- const location = rangeForOffsets(source, start, start + match[0].length);
356
- addBounded(accumulator, `source-map\0${declared}`, maximum, () => accumulator.sourceMaps.push({ declared_url: declared, location }));
357
- }
358
- };