rea-agents 2.0.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 (246) hide show
  1. package/README.md +78 -32
  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 +24 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +1 -23
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +156 -238
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  26. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  27. package/dist/application/EnhancedToolPagination.js +22 -0
  28. package/dist/application/EnhancedToolTypes.js +4 -0
  29. package/dist/application/EnhancedTools.js +20 -37
  30. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  31. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  32. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  33. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  34. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  35. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  36. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  37. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  38. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  39. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  40. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  41. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  42. package/dist/application/JavaScriptJsonModules.js +39 -0
  43. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  44. package/dist/application/JavaScriptReplayPermission.js +16 -0
  45. package/dist/application/JavaScriptReplayService.js +182 -156
  46. package/dist/application/LinuxHopper.js +10 -0
  47. package/dist/application/MacHopper.js +22 -11
  48. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  49. package/dist/application/PermissionAuthority.js +106 -63
  50. package/dist/application/ProcessCaptureCapability.js +1 -1
  51. package/dist/application/ProcessCapturePermission.js +13 -0
  52. package/dist/application/ProcessCli.js +2 -12
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProjectPermissionStore.js +48 -9
  55. package/dist/application/RealHopperAssertions.js +76 -0
  56. package/dist/application/ReconstructionCoverageService.js +69 -0
  57. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  58. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  59. package/dist/application/Setup.js +147 -259
  60. package/dist/application/SetupClientConfiguration.js +220 -0
  61. package/dist/application/SetupClients.js +24 -2
  62. package/dist/application/SetupPlan.js +123 -12
  63. package/dist/application/SetupSkill.js +26 -12
  64. package/dist/application/SupportedClients.js +1 -0
  65. package/dist/application/Uninstall.js +6 -3
  66. package/dist/application/WindowsCapabilities.js +86 -0
  67. package/dist/artifacts/AsarArtifactReader.js +11 -0
  68. package/dist/browser/BrowserProcessStartup.js +88 -0
  69. package/dist/browser/CdpCaptureDocuments.js +12 -8
  70. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  71. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  72. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  73. package/dist/browser/CdpCaptureEventState.js +1 -0
  74. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  75. package/dist/browser/CdpCaptureEvents.js +29 -496
  76. package/dist/browser/CdpObservationSession.js +51 -8
  77. package/dist/browser/CdpPageCapture.js +12 -133
  78. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  79. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  80. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  81. package/dist/browser/PngVisualDiff.js +9 -2
  82. package/dist/catalogIdentity.js +4 -0
  83. package/dist/cli/artifactCommands.js +82 -0
  84. package/dist/cli/coreAnalysisCommands.js +232 -0
  85. package/dist/cli/managedCommands.js +397 -0
  86. package/dist/cli/managedProjectGraphCommand.js +24 -0
  87. package/dist/cli/options.js +9 -0
  88. package/dist/cli/setupCommands.js +108 -0
  89. package/dist/cli/types.js +1 -0
  90. package/dist/cli/utilityCommands.js +122 -0
  91. package/dist/cli.js +10 -768
  92. package/dist/cliApplicationCommands.js +118 -4
  93. package/dist/cliBrowserAdvancedCommands.js +73 -16
  94. package/dist/cliBrowserCommands.js +39 -115
  95. package/dist/cliCommandNames.js +4 -0
  96. package/dist/cliElectronCommands.js +33 -62
  97. package/dist/cliEvidenceCommands.js +13 -2
  98. package/dist/cliInvestigationCommands.js +53 -10
  99. package/dist/cliObservationOptions.js +137 -0
  100. package/dist/cliPolicyCommands.js +80 -46
  101. package/dist/cliSetup.js +289 -0
  102. package/dist/config/environment.js +107 -0
  103. package/dist/config/parseConfig.js +228 -0
  104. package/dist/config/parsers.js +68 -0
  105. package/dist/config/permissions.js +30 -0
  106. package/dist/config/types.js +1 -0
  107. package/dist/config.js +1 -375
  108. package/dist/contracts/applicationToolContracts.js +134 -0
  109. package/dist/contracts/managedToolContracts.js +1 -1
  110. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  111. package/dist/contracts/providerSelection.js +2 -0
  112. package/dist/contracts/toolContracts.js +2 -2
  113. package/dist/contracts/toolEffects.js +14 -0
  114. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  115. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  116. package/dist/contracts/toolOutputSchemas.js +2 -550
  117. package/dist/domain/analysisErrorPresentation.js +234 -0
  118. package/dist/domain/analysisErrorProjection.js +284 -0
  119. package/dist/domain/artifactComparison.js +34 -15
  120. package/dist/domain/binaryTarget.js +87 -37
  121. package/dist/domain/browserObservation.js +1 -285
  122. package/dist/domain/browserObservationSchemas.js +286 -0
  123. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  124. package/dist/domain/errors.js +4 -486
  125. package/dist/domain/functionComparison.js +4 -165
  126. package/dist/domain/functionComparisonDimensions.js +164 -0
  127. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  128. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  129. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  130. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  131. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  132. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  133. package/dist/domain/javascriptSemanticIr.js +30 -0
  134. package/dist/domain/javascriptSemanticProjection.js +366 -0
  135. package/dist/domain/javascriptSemanticState.js +40 -0
  136. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  137. package/dist/domain/javascriptSemanticValues.js +352 -0
  138. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  139. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  140. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  141. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  142. package/dist/domain/knownPageCoverage.js +21 -0
  143. package/dist/domain/managedApplicationGraph.js +14 -364
  144. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  145. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  146. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  147. package/dist/domain/managedArtifact.js +16 -8
  148. package/dist/domain/managedMemberComparison.js +37 -391
  149. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  150. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  151. package/dist/domain/managedNativeVerification.js +27 -389
  152. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  153. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  154. package/dist/domain/managedReconstruction.js +82 -69
  155. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  156. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  157. package/dist/domain/permissionPolicy.js +2 -0
  158. package/dist/domain/reconstructionCoverage.js +387 -0
  159. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  160. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  161. package/dist/domain/runtimeCharacterization.js +85 -0
  162. package/dist/domain/webBundleAnalyzer.js +3 -409
  163. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  164. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  165. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  166. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  167. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  168. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  169. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  170. package/dist/dotnet/ManagedMemberRows.js +120 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  172. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  173. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  174. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  175. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  176. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  177. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  178. package/dist/dotnet/ManagedPeReader.js +59 -28
  179. package/dist/generatedPackageMetadata.js +2 -2
  180. package/dist/ghidra/GhidraClient.js +76 -91
  181. package/dist/ghidra/GhidraClientStartup.js +29 -0
  182. package/dist/ghidra/GhidraClientWire.js +34 -0
  183. package/dist/ghidra/GhidraDefaults.js +1 -1
  184. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  185. package/dist/ghidra/GhidraInstallation.js +20 -15
  186. package/dist/ghidra/GhidraLauncher.js +93 -29
  187. package/dist/ghidra/GhidraProvider.js +61 -161
  188. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  189. package/dist/ghidra/GhidraSessionValues.js +2 -0
  190. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  191. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  192. package/dist/ghidra/GhidraTransport.js +71 -0
  193. package/dist/identity.js +3 -2
  194. package/dist/main/messages.js +5 -0
  195. package/dist/main/reload.js +49 -0
  196. package/dist/main/shutdown.js +25 -0
  197. package/dist/main/startup.js +14 -0
  198. package/dist/main/state.js +26 -0
  199. package/dist/main/transport.js +61 -0
  200. package/dist/main/types.js +1 -0
  201. package/dist/main.js +35 -146
  202. package/dist/process/PrivateRuntimeRoot.js +3 -2
  203. package/dist/process/ProcessOwnership.js +35 -0
  204. package/dist/process/ProviderProcess.js +2 -0
  205. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  206. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  207. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  208. package/dist/replay/ReplayOutcome.js +95 -0
  209. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  210. package/dist/server/ProcessCaptureElicitation.js +157 -0
  211. package/dist/server/createServer.js +119 -54
  212. package/dist/server/registerApplicationTools/characterization.js +57 -0
  213. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  214. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  215. package/dist/server/registerApplicationTools/coverage.js +84 -0
  216. package/dist/server/registerApplicationTools/helpers.js +42 -0
  217. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  218. package/dist/server/registerApplicationTools/types.js +1 -0
  219. package/dist/server/registerApplicationTools.js +10 -112
  220. package/dist/server/registerBrowserTools.js +59 -83
  221. package/dist/server/registerElectronTools.js +31 -46
  222. package/dist/server/registerEnhancedTools.js +34 -42
  223. package/dist/server/registerEvidenceResources.js +54 -0
  224. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  225. package/dist/server/registerInvestigationTools/types.js +1 -0
  226. package/dist/server/registerInvestigationTools.js +83 -116
  227. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  228. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  229. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  230. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  231. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  232. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  233. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  234. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  235. package/dist/server/registerManagedWorkflowTools.js +10 -274
  236. package/dist/server/registerOfficialTools.js +73 -59
  237. package/dist/server/registerSessionRecordTools.js +137 -0
  238. package/dist/server/registerSessionStatusTool.js +2 -1
  239. package/dist/server/registerSessionTools.js +60 -164
  240. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  241. package/dist/server/toolRegistrationOptions.js +101 -3
  242. package/dist/server/toolResult.js +5 -0
  243. package/package.json +10 -11
  244. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +20 -7
  245. package/scripts/prepare-node-pty.mjs +0 -35
  246. package/scripts/rebuild-native.mjs +0 -22
@@ -1,295 +1,7 @@
1
- import { METADATA_TABLE_NAMES, metadataRowOffset, } from "./ManagedMetadataLayout.js";
2
- import { MetadataRowCursor, metadataToken, readMetadataBlob, readMetadataGuid, readMetadataString, sha256Bytes, strongNameToken, } from "./ManagedMetadataHeaps.js";
3
- import { ManagedReaderFailure, managedFailure, } from "./ManagedReaderFailure.js";
4
- const rowCursor = (bytes, layout, table, row) => {
5
- const descriptor = layout.table(table);
6
- const start = metadataRowOffset(layout, table, row);
7
- if (descriptor === undefined)
8
- throw managedFailure("invalid-row", `metadata.${String(table)}`, "Metadata table is absent", start);
9
- return new MetadataRowCursor(bytes, start, start + descriptor.rowSize, `metadata.${descriptor.name}`);
10
- };
11
- const publicKeyIdentity = (bytes, kind) => ({
12
- kind: bytes.length === 0 ? "none" : kind,
13
- byte_length: bytes.length,
14
- sha256: bytes.length === 0 ? null : sha256Bytes(bytes),
15
- token: bytes.length === 0
16
- ? null
17
- : kind === "public-key"
18
- ? strongNameToken(bytes)
19
- : bytes.length === 8
20
- ? bytes.toString("hex")
21
- : null,
22
- });
23
- const readModule = (bytes, layout, maxBytes) => {
24
- const table = layout.table(0);
25
- if (table === undefined || table.rowCount === 0)
26
- return null;
27
- const cursor = rowCursor(bytes, layout, 0, 1);
28
- const generation = cursor.readUInt16();
29
- const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
30
- const mvid = readMetadataGuid(bytes, layout, cursor.readIndex(layout.guidIndexSize));
31
- const encId = readMetadataGuid(bytes, layout, cursor.readIndex(layout.guidIndexSize));
32
- const encBaseId = readMetadataGuid(bytes, layout, cursor.readIndex(layout.guidIndexSize));
33
- return {
34
- name,
35
- generation,
36
- mvid,
37
- enc_id: encId,
38
- enc_base_id: encBaseId,
39
- token: metadataToken(0, 1),
40
- row_offset: table.offset,
41
- };
42
- };
43
- const readAssembly = (bytes, layout, maxBytes) => {
44
- const table = layout.table(32);
45
- if (table === undefined || table.rowCount === 0)
46
- return null;
47
- const cursor = rowCursor(bytes, layout, 32, 1);
48
- const hashAlgorithm = cursor.readUInt32();
49
- const version = [
50
- cursor.readUInt16(),
51
- cursor.readUInt16(),
52
- cursor.readUInt16(),
53
- cursor.readUInt16(),
54
- ].join(".");
55
- const flags = cursor.readUInt32();
56
- const key = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
57
- const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
58
- const culture = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
59
- return {
60
- name,
61
- version,
62
- culture: culture.length === 0 ? null : culture,
63
- flags,
64
- hash_algorithm: hashAlgorithm,
65
- public_key: publicKeyIdentity(key, (flags & 1) === 0 ? "public-key-token" : "public-key"),
66
- token: metadataToken(32, 1),
67
- row_offset: table.offset,
68
- };
69
- };
70
- const readAssemblyReference = (bytes, layout, row, maxBytes) => {
71
- const cursor = rowCursor(bytes, layout, 35, row);
72
- const version = [
73
- cursor.readUInt16(),
74
- cursor.readUInt16(),
75
- cursor.readUInt16(),
76
- cursor.readUInt16(),
77
- ].join(".");
78
- const flags = cursor.readUInt32();
79
- const keyOrToken = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
80
- const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
81
- const culture = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
82
- const hashValue = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
83
- return {
84
- name,
85
- version,
86
- culture: culture.length === 0 ? null : culture,
87
- flags,
88
- public_key_or_token: publicKeyIdentity(keyOrToken, (flags & 1) === 0 ? "public-key-token" : "public-key"),
89
- hash_value_sha256: hashValue.length === 0 ? null : sha256Bytes(hashValue),
90
- hash_value_length: hashValue.length,
91
- token: metadataToken(35, row),
92
- row_offset: metadataRowOffset(layout, 35, row),
93
- };
94
- };
95
- const codedToken = (raw, bits, tables) => {
96
- if (raw === 0)
97
- return null;
98
- const tag = raw & (2 ** bits - 1);
99
- const row = Math.floor(raw / 2 ** bits);
100
- const table = tables[tag];
101
- return table === undefined || row === 0 ? null : metadataToken(table, row);
102
- };
103
- const readTypeName = (bytes, layout, table, row, maxBytes) => {
104
- const descriptor = layout.table(table);
105
- if (descriptor === undefined || row < 1 || row > descriptor.rowCount)
106
- return null;
107
- const cursor = rowCursor(bytes, layout, table, row);
108
- if (table === 1)
109
- cursor.readIndex(layout.codedIndexSize("ResolutionScope"));
110
- else
111
- cursor.readUInt32();
112
- const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
113
- const namespace = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
114
- return namespace.length === 0 ? name : `${namespace}.${name}`;
115
- };
116
- const declaringTypeForMethod = (bytes, layout, methodRow, maxBytes) => {
117
- const types = layout.table(2);
118
- const methods = layout.table(6);
119
- if (types === undefined || methods === undefined)
120
- return null;
121
- for (let row = 1; row <= types.rowCount; row += 1) {
122
- const cursor = rowCursor(bytes, layout, 2, row);
123
- cursor.readUInt32();
124
- const nameIndex = cursor.readIndex(layout.stringIndexSize);
125
- const namespaceIndex = cursor.readIndex(layout.stringIndexSize);
126
- cursor.readIndex(layout.codedIndexSize("TypeDefOrRef"));
127
- cursor.readIndex(layout.tableIndexSize(4));
128
- const methodStart = cursor.readIndex(layout.tableIndexSize(6));
129
- const methodEnd = row === types.rowCount
130
- ? methods.rowCount + 1
131
- : methodListForType(bytes, layout, row + 1);
132
- if (methodRow < methodStart || methodRow >= methodEnd)
133
- continue;
134
- const name = readMetadataString(bytes, layout, nameIndex, maxBytes);
135
- const namespace = readMetadataString(bytes, layout, namespaceIndex, maxBytes);
136
- return namespace.length === 0 ? name : `${namespace}.${name}`;
137
- }
138
- return null;
139
- };
140
- const methodListForType = (bytes, layout, row) => {
141
- const cursor = rowCursor(bytes, layout, 2, row);
142
- cursor.readUInt32();
143
- cursor.readIndex(layout.stringIndexSize);
144
- cursor.readIndex(layout.stringIndexSize);
145
- cursor.readIndex(layout.codedIndexSize("TypeDefOrRef"));
146
- cursor.readIndex(layout.tableIndexSize(4));
147
- return cursor.readIndex(layout.tableIndexSize(6));
148
- };
149
- const attributeTypeName = (bytes, layout, rawType, maxBytes) => {
150
- const tag = rawType & 7;
151
- const row = Math.floor(rawType / 8);
152
- if (row === 0)
153
- return null;
154
- if (tag === 2)
155
- return declaringTypeForMethod(bytes, layout, row, maxBytes);
156
- if (tag !== 3)
157
- return null;
158
- const memberRefs = layout.table(10);
159
- if (memberRefs === undefined || row > memberRefs.rowCount)
160
- return null;
161
- const cursor = rowCursor(bytes, layout, 10, row);
162
- const parent = cursor.readIndex(layout.codedIndexSize("MemberRefParent"));
163
- const parentTag = parent & 7;
164
- const parentRow = Math.floor(parent / 8);
165
- if (parentTag === 0)
166
- return readTypeName(bytes, layout, 2, parentRow, maxBytes);
167
- if (parentTag === 1)
168
- return readTypeName(bytes, layout, 1, parentRow, maxBytes);
169
- if (parentTag === 3)
170
- return declaringTypeForMethod(bytes, layout, parentRow, maxBytes);
171
- return null;
172
- };
173
- const decodeCompressedLength = (blob, offset) => {
174
- const first = blob[offset];
175
- if (first === undefined)
176
- return undefined;
177
- if ((first & 0x80) === 0)
178
- return { length: first, prefix: 1 };
179
- if ((first & 0xc0) === 0x80 && blob[offset + 1] !== undefined)
180
- return {
181
- length: ((first & 0x3f) << 8) | (blob[offset + 1] ?? 0),
182
- prefix: 2,
183
- };
184
- if ((first & 0xe0) === 0xc0 &&
185
- blob[offset + 1] !== undefined &&
186
- blob[offset + 2] !== undefined &&
187
- blob[offset + 3] !== undefined)
188
- return {
189
- length: (first & 0x1f) * 0x01_00_00_00 +
190
- (blob[offset + 1] ?? 0) * 0x01_00_00 +
191
- (blob[offset + 2] ?? 0) * 0x0100 +
192
- (blob[offset + 3] ?? 0),
193
- prefix: 4,
194
- };
195
- return undefined;
196
- };
197
- const decodeFixedString = (blob) => {
198
- if (blob.length < 3 || blob.readUInt16LE(0) !== 1 || blob[2] === 0xff)
199
- return null;
200
- const length = decodeCompressedLength(blob, 2);
201
- if (length === undefined)
202
- return null;
203
- const start = 2 + length.prefix;
204
- if (start > blob.length - length.length)
205
- return null;
206
- try {
207
- return new TextDecoder("utf-8", { fatal: true }).decode(blob.subarray(start, start + length.length));
208
- }
209
- catch {
210
- return null;
211
- }
212
- };
213
- const readCustomAttribute = (bytes, layout, row, maxBytes) => {
214
- const cursor = rowCursor(bytes, layout, 12, row);
215
- const parentRaw = cursor.readIndex(layout.codedIndexSize("HasCustomAttribute"));
216
- const typeRaw = cursor.readIndex(layout.codedIndexSize("CustomAttributeType"));
217
- const value = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
218
- const parent = codedToken(parentRaw, 5, [
219
- 6, 4, 1, 2, 8, 9, 10, 0, 14, 23, 20, 17, 26, 27, 32, 35, 38, 39, 40, 42,
220
- 44, 43,
221
- ]);
222
- if (parent === null)
223
- throw managedFailure("invalid-row", "metadata.CustomAttribute", "CustomAttribute parent coded index is invalid", cursor.start);
224
- const typeName = attributeTypeName(bytes, layout, typeRaw, maxBytes);
225
- return {
226
- parent_token: parent,
227
- constructor_token: codedToken(typeRaw, 3, [undefined, undefined, 6, 10]),
228
- type_name: typeName,
229
- value_length: value.length,
230
- value_sha256: sha256Bytes(value),
231
- decoded_fixed_string: typeName === "System.Runtime.Versioning.TargetFrameworkAttribute"
232
- ? decodeFixedString(value)
233
- : null,
234
- token: metadataToken(12, row),
235
- row_offset: cursor.start,
236
- };
237
- };
238
- const readResource = (bytes, layout, row, maxBytes, directory, issues) => {
239
- const cursor = rowCursor(bytes, layout, 40, row);
240
- const declaredOffset = cursor.readUInt32();
241
- const flags = cursor.readUInt32();
242
- const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
243
- const implementationRaw = cursor.readIndex(layout.codedIndexSize("Implementation"));
244
- const implementationToken = codedToken(implementationRaw, 2, [38, 35, 39]);
245
- let dataLength = null;
246
- let dataSha256 = null;
247
- if (implementationRaw === 0) {
248
- if (directory === null || declaredOffset > directory.size - 4) {
249
- issues.push({
250
- code: "invalid-resource",
251
- scope: `metadata.ManifestResource:${metadataToken(40, row)}`,
252
- offset: directory?.offset ?? null,
253
- detail: "Embedded resource offset leaves the CLI resources directory",
254
- });
255
- }
256
- else {
257
- const start = directory.offset + declaredOffset;
258
- dataLength = bytes.readUInt32LE(start);
259
- if (dataLength > directory.size - declaredOffset - 4) {
260
- issues.push({
261
- code: "invalid-resource",
262
- scope: `metadata.ManifestResource:${metadataToken(40, row)}`,
263
- offset: start,
264
- detail: "Embedded resource length leaves the CLI resources directory",
265
- });
266
- }
267
- else if (dataLength > maxBytes) {
268
- issues.push({
269
- code: "limit-exceeded",
270
- scope: `metadata.ManifestResource:${metadataToken(40, row)}`,
271
- offset: start + 4,
272
- detail: `Embedded resource exceeds max_heap_item_bytes ${String(maxBytes)}; digest omitted`,
273
- });
274
- }
275
- else {
276
- dataSha256 = sha256Bytes(bytes.subarray(start + 4, start + 4 + dataLength));
277
- }
278
- }
279
- }
280
- return {
281
- name,
282
- flags,
283
- visibility: (flags & 7) === 1 ? "public" : (flags & 7) === 2 ? "private" : "unknown",
284
- implementation_token: implementationToken,
285
- embedded: implementationRaw === 0,
286
- declared_offset: declaredOffset,
287
- data_length: dataLength,
288
- data_sha256: dataSha256,
289
- token: metadataToken(40, row),
290
- row_offset: cursor.start,
291
- };
292
- };
1
+ import { METADATA_TABLE_NAMES, } from "./ManagedMetadataLayout.js";
2
+ import { readAssembly, readAssemblyReference, readCustomAttribute, readModule, readResource, } from "./ManagedMetadataInventoryRows.js";
3
+ import { metadataToken } from "./ManagedMetadataHeaps.js";
4
+ import { ManagedReaderFailure } from "./ManagedReaderFailure.js";
293
5
  const safeRead = (operation, issues) => {
294
6
  try {
295
7
  return operation();
@@ -323,26 +35,31 @@ const pageRows = (descriptor, offset, limit, read) => {
323
35
  const uniqueIssues = (issues) => [
324
36
  ...new Map(issues.map((issue) => [JSON.stringify(issue), issue])).values(),
325
37
  ];
326
- /** Inventory bounded identity tables without CLR reflection or execution. */
327
- export const readManagedMetadataInventory = (bytes, layout, input, resourceDirectory) => {
328
- const issues = [];
329
- const module = safeRead(() => readModule(bytes, layout, input.maxHeapItemBytes), issues) ??
330
- null;
331
- const assembly = safeRead(() => readAssembly(bytes, layout, input.maxHeapItemBytes), issues) ?? null;
332
- const references = pageRows(layout.table(35), input.referenceOffset, input.referenceLimit, (row) => safeRead(() => readAssemblyReference(bytes, layout, row, input.maxHeapItemBytes), issues));
333
- const resources = pageRows(layout.table(40), input.resourceOffset, input.resourceLimit, (row) => safeRead(() => readResource(bytes, layout, row, input.maxHeapItemBytes, resourceDirectory, issues), issues));
334
- const attributes = pageRows(layout.table(12), input.attributeOffset, input.attributeLimit, (row) => safeRead(() => readCustomAttribute(bytes, layout, row, input.maxHeapItemBytes), issues));
335
- const referenceNames = [];
38
+ const readPagedReferences = (bytes, layout, input, issues) => pageRows(layout.table(35), input.referenceOffset, input.referenceLimit, (row) => safeRead(() => readAssemblyReference(bytes, layout, row, input.maxHeapItemBytes), issues));
39
+ const readPagedResources = ({ bytes, layout, input, resourceDirectory, issues, }) => pageRows(layout.table(40), input.resourceOffset, input.resourceLimit, (row) => safeRead(() => readResource({
40
+ bytes,
41
+ layout,
42
+ row,
43
+ maxBytes: input.maxHeapItemBytes,
44
+ directory: resourceDirectory,
45
+ issues,
46
+ }), issues));
47
+ const readPagedAttributes = (bytes, layout, input, issues) => pageRows(layout.table(12), input.attributeOffset, input.attributeLimit, (row) => safeRead(() => readCustomAttribute(bytes, layout, row, input.maxHeapItemBytes), issues));
48
+ const collectReferenceNames = (bytes, layout, maxBytes, issues) => {
49
+ const names = [];
336
50
  const referenceTable = layout.table(35);
337
51
  for (let row = 1; row <= (referenceTable?.rowCount ?? 0); row += 1) {
338
- const reference = safeRead(() => readAssemblyReference(bytes, layout, row, input.maxHeapItemBytes), issues);
52
+ const reference = safeRead(() => readAssemblyReference(bytes, layout, row, maxBytes), issues);
339
53
  if (reference !== undefined)
340
- referenceNames.push(reference.name);
54
+ names.push(reference.name);
341
55
  }
56
+ return names;
57
+ };
58
+ const collectTargetFrameworks = (bytes, layout, maxBytes, issues) => {
342
59
  const targetFrameworks = [];
343
60
  const attributeTable = layout.table(12);
344
61
  for (let row = 1; row <= (attributeTable?.rowCount ?? 0); row += 1) {
345
- const attribute = safeRead(() => readCustomAttribute(bytes, layout, row, input.maxHeapItemBytes), issues);
62
+ const attribute = safeRead(() => readCustomAttribute(bytes, layout, row, maxBytes), issues);
346
63
  if (attribute?.parent_token === metadataToken(32, 1) &&
347
64
  attribute.type_name ===
348
65
  "System.Runtime.Versioning.TargetFrameworkAttribute" &&
@@ -350,10 +67,29 @@ export const readManagedMetadataInventory = (bytes, layout, input, resourceDirec
350
67
  !targetFrameworks.includes(attribute.decoded_fixed_string))
351
68
  targetFrameworks.push(attribute.decoded_fixed_string);
352
69
  }
70
+ return targetFrameworks;
71
+ };
72
+ /** Inventory bounded identity tables without CLR reflection or execution. */
73
+ export const readManagedMetadataInventory = (bytes, layout, input, resourceDirectory) => {
74
+ const issues = [];
75
+ const module = safeRead(() => readModule(bytes, layout, input.maxHeapItemBytes), issues) ??
76
+ null;
77
+ const assembly = safeRead(() => readAssembly(bytes, layout, input.maxHeapItemBytes), issues) ?? null;
78
+ const references = readPagedReferences(bytes, layout, input, issues);
79
+ const resources = readPagedResources({
80
+ bytes,
81
+ layout,
82
+ input,
83
+ resourceDirectory,
84
+ issues,
85
+ });
86
+ const attributes = readPagedAttributes(bytes, layout, input, issues);
87
+ const referenceNames = collectReferenceNames(bytes, layout, input.maxHeapItemBytes, issues);
88
+ const targetFrameworks = collectTargetFrameworks(bytes, layout, input.maxHeapItemBytes, issues);
353
89
  return {
354
90
  module,
355
91
  assembly,
356
- targetFrameworks: targetFrameworks.sort(),
92
+ targetFrameworks: [...targetFrameworks].sort(),
357
93
  referenceNames: [...new Set(referenceNames)].sort(),
358
94
  references,
359
95
  resources,
@@ -0,0 +1,292 @@
1
+ import { metadataRowOffset, } from "./ManagedMetadataLayout.js";
2
+ import { MetadataRowCursor, metadataToken, readMetadataBlob, readMetadataGuid, readMetadataString, sha256Bytes, strongNameToken, } from "./ManagedMetadataHeaps.js";
3
+ import { managedFailure } from "./ManagedReaderFailure.js";
4
+ const rowCursor = ({ bytes, layout, table, row, }) => {
5
+ const descriptor = layout.table(table);
6
+ const start = metadataRowOffset(layout, table, row);
7
+ if (descriptor === undefined)
8
+ throw managedFailure("invalid-row", `metadata.${String(table)}`, "Metadata table is absent", start);
9
+ return new MetadataRowCursor(bytes, start, start + descriptor.rowSize, `metadata.${descriptor.name}`);
10
+ };
11
+ const publicKeyIdentity = (bytes, kind) => ({
12
+ kind: bytes.length === 0 ? "none" : kind,
13
+ byte_length: bytes.length,
14
+ sha256: bytes.length === 0 ? null : sha256Bytes(bytes),
15
+ token: bytes.length === 0
16
+ ? null
17
+ : kind === "public-key"
18
+ ? strongNameToken(bytes)
19
+ : bytes.length === 8
20
+ ? bytes.toString("hex")
21
+ : null,
22
+ });
23
+ export const readModule = (bytes, layout, maxBytes) => {
24
+ const table = layout.table(0);
25
+ if (table === undefined || table.rowCount === 0)
26
+ return null;
27
+ const cursor = rowCursor({ bytes, layout, table: 0, row: 1 });
28
+ const generation = cursor.readUInt16();
29
+ const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
30
+ const mvid = readMetadataGuid(bytes, layout, cursor.readIndex(layout.guidIndexSize));
31
+ const encId = readMetadataGuid(bytes, layout, cursor.readIndex(layout.guidIndexSize));
32
+ const encBaseId = readMetadataGuid(bytes, layout, cursor.readIndex(layout.guidIndexSize));
33
+ return {
34
+ name,
35
+ generation,
36
+ mvid,
37
+ enc_id: encId,
38
+ enc_base_id: encBaseId,
39
+ token: metadataToken(0, 1),
40
+ row_offset: table.offset,
41
+ };
42
+ };
43
+ export const readAssembly = (bytes, layout, maxBytes) => {
44
+ const table = layout.table(32);
45
+ if (table === undefined || table.rowCount === 0)
46
+ return null;
47
+ const cursor = rowCursor({ bytes, layout, table: 32, row: 1 });
48
+ const hashAlgorithm = cursor.readUInt32();
49
+ const version = [
50
+ cursor.readUInt16(),
51
+ cursor.readUInt16(),
52
+ cursor.readUInt16(),
53
+ cursor.readUInt16(),
54
+ ].join(".");
55
+ const flags = cursor.readUInt32();
56
+ const key = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
57
+ const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
58
+ const culture = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
59
+ return {
60
+ name,
61
+ version,
62
+ culture: culture.length === 0 ? null : culture,
63
+ flags,
64
+ hash_algorithm: hashAlgorithm,
65
+ public_key: publicKeyIdentity(key, (flags & 1) === 0 ? "public-key-token" : "public-key"),
66
+ token: metadataToken(32, 1),
67
+ row_offset: table.offset,
68
+ };
69
+ };
70
+ export const readAssemblyReference = (bytes, layout, row, maxBytes) => {
71
+ const cursor = rowCursor({ bytes, layout, table: 35, row });
72
+ const version = [
73
+ cursor.readUInt16(),
74
+ cursor.readUInt16(),
75
+ cursor.readUInt16(),
76
+ cursor.readUInt16(),
77
+ ].join(".");
78
+ const flags = cursor.readUInt32();
79
+ const keyOrToken = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
80
+ const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
81
+ const culture = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
82
+ const hashValue = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
83
+ return {
84
+ name,
85
+ version,
86
+ culture: culture.length === 0 ? null : culture,
87
+ flags,
88
+ public_key_or_token: publicKeyIdentity(keyOrToken, (flags & 1) === 0 ? "public-key-token" : "public-key"),
89
+ hash_value_sha256: hashValue.length === 0 ? null : sha256Bytes(hashValue),
90
+ hash_value_length: hashValue.length,
91
+ token: metadataToken(35, row),
92
+ row_offset: metadataRowOffset(layout, 35, row),
93
+ };
94
+ };
95
+ const codedToken = (raw, bits, tables) => {
96
+ if (raw === 0)
97
+ return null;
98
+ const tag = raw & (2 ** bits - 1);
99
+ const row = Math.floor(raw / 2 ** bits);
100
+ const table = tables[tag];
101
+ return table === undefined || row === 0 ? null : metadataToken(table, row);
102
+ };
103
+ const readTypeName = ({ bytes, layout, table, row, maxBytes, }) => {
104
+ const descriptor = layout.table(table);
105
+ if (descriptor === undefined || row < 1 || row > descriptor.rowCount)
106
+ return null;
107
+ const cursor = rowCursor({ bytes, layout, table, row });
108
+ if (table === 1)
109
+ cursor.readIndex(layout.codedIndexSize("ResolutionScope"));
110
+ else
111
+ cursor.readUInt32();
112
+ const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
113
+ const namespace = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
114
+ return namespace.length === 0 ? name : `${namespace}.${name}`;
115
+ };
116
+ const declaringTypeForMethod = (bytes, layout, methodRow, maxBytes) => {
117
+ const types = layout.table(2);
118
+ const methods = layout.table(6);
119
+ if (types === undefined || methods === undefined)
120
+ return null;
121
+ for (let row = 1; row <= types.rowCount; row += 1) {
122
+ const cursor = rowCursor({ bytes, layout, table: 2, row });
123
+ cursor.readUInt32();
124
+ const nameIndex = cursor.readIndex(layout.stringIndexSize);
125
+ const namespaceIndex = cursor.readIndex(layout.stringIndexSize);
126
+ cursor.readIndex(layout.codedIndexSize("TypeDefOrRef"));
127
+ cursor.readIndex(layout.tableIndexSize(4));
128
+ const methodStart = cursor.readIndex(layout.tableIndexSize(6));
129
+ const methodEnd = row === types.rowCount
130
+ ? methods.rowCount + 1
131
+ : methodListForType(bytes, layout, row + 1);
132
+ if (methodRow < methodStart || methodRow >= methodEnd)
133
+ continue;
134
+ const name = readMetadataString(bytes, layout, nameIndex, maxBytes);
135
+ const namespace = readMetadataString(bytes, layout, namespaceIndex, maxBytes);
136
+ return namespace.length === 0 ? name : `${namespace}.${name}`;
137
+ }
138
+ return null;
139
+ };
140
+ const methodListForType = (bytes, layout, row) => {
141
+ const cursor = rowCursor({ bytes, layout, table: 2, row });
142
+ cursor.readUInt32();
143
+ cursor.readIndex(layout.stringIndexSize);
144
+ cursor.readIndex(layout.stringIndexSize);
145
+ cursor.readIndex(layout.codedIndexSize("TypeDefOrRef"));
146
+ cursor.readIndex(layout.tableIndexSize(4));
147
+ return cursor.readIndex(layout.tableIndexSize(6));
148
+ };
149
+ const attributeTypeName = (bytes, layout, rawType, maxBytes) => {
150
+ const tag = rawType & 7;
151
+ const row = Math.floor(rawType / 8);
152
+ if (row === 0)
153
+ return null;
154
+ if (tag === 2)
155
+ return declaringTypeForMethod(bytes, layout, row, maxBytes);
156
+ if (tag !== 3)
157
+ return null;
158
+ const memberRefs = layout.table(10);
159
+ if (memberRefs === undefined || row > memberRefs.rowCount)
160
+ return null;
161
+ const cursor = rowCursor({ bytes, layout, table: 10, row });
162
+ const parent = cursor.readIndex(layout.codedIndexSize("MemberRefParent"));
163
+ const parentTag = parent & 7;
164
+ const parentRow = Math.floor(parent / 8);
165
+ if (parentTag === 0)
166
+ return readTypeName({ bytes, layout, table: 2, row: parentRow, maxBytes });
167
+ if (parentTag === 1)
168
+ return readTypeName({ bytes, layout, table: 1, row: parentRow, maxBytes });
169
+ if (parentTag === 3)
170
+ return declaringTypeForMethod(bytes, layout, parentRow, maxBytes);
171
+ return null;
172
+ };
173
+ const decodeCompressedLength = (blob, offset) => {
174
+ const first = blob[offset];
175
+ if (first === undefined)
176
+ return undefined;
177
+ if ((first & 0x80) === 0)
178
+ return { length: first, prefix: 1 };
179
+ if ((first & 0xc0) === 0x80 && blob[offset + 1] !== undefined)
180
+ return {
181
+ length: ((first & 0x3f) << 8) | (blob[offset + 1] ?? 0),
182
+ prefix: 2,
183
+ };
184
+ if ((first & 0xe0) === 0xc0 &&
185
+ blob[offset + 1] !== undefined &&
186
+ blob[offset + 2] !== undefined &&
187
+ blob[offset + 3] !== undefined)
188
+ return {
189
+ length: (first & 0x1f) * 0x01_00_00_00 +
190
+ (blob[offset + 1] ?? 0) * 0x01_00_00 +
191
+ (blob[offset + 2] ?? 0) * 0x0100 +
192
+ (blob[offset + 3] ?? 0),
193
+ prefix: 4,
194
+ };
195
+ return undefined;
196
+ };
197
+ const decodeFixedString = (blob) => {
198
+ if (blob.length < 3 || blob.readUInt16LE(0) !== 1 || blob[2] === 0xff)
199
+ return null;
200
+ const length = decodeCompressedLength(blob, 2);
201
+ if (length === undefined)
202
+ return null;
203
+ const start = 2 + length.prefix;
204
+ if (start > blob.length - length.length)
205
+ return null;
206
+ try {
207
+ return new TextDecoder("utf-8", { fatal: true }).decode(blob.subarray(start, start + length.length));
208
+ }
209
+ catch {
210
+ return null;
211
+ }
212
+ };
213
+ export const readCustomAttribute = (bytes, layout, row, maxBytes) => {
214
+ const cursor = rowCursor({ bytes, layout, table: 12, row });
215
+ const parentRaw = cursor.readIndex(layout.codedIndexSize("HasCustomAttribute"));
216
+ const typeRaw = cursor.readIndex(layout.codedIndexSize("CustomAttributeType"));
217
+ const value = readMetadataBlob(bytes, layout, cursor.readIndex(layout.blobIndexSize), maxBytes);
218
+ const parent = codedToken(parentRaw, 5, [
219
+ 6, 4, 1, 2, 8, 9, 10, 0, 14, 23, 20, 17, 26, 27, 32, 35, 38, 39, 40, 42,
220
+ 44, 43,
221
+ ]);
222
+ if (parent === null)
223
+ throw managedFailure("invalid-row", "metadata.CustomAttribute", "CustomAttribute parent coded index is invalid", cursor.start);
224
+ const typeName = attributeTypeName(bytes, layout, typeRaw, maxBytes);
225
+ return {
226
+ parent_token: parent,
227
+ constructor_token: codedToken(typeRaw, 3, [undefined, undefined, 6, 10]),
228
+ type_name: typeName,
229
+ value_length: value.length,
230
+ value_sha256: sha256Bytes(value),
231
+ decoded_fixed_string: typeName === "System.Runtime.Versioning.TargetFrameworkAttribute"
232
+ ? decodeFixedString(value)
233
+ : null,
234
+ token: metadataToken(12, row),
235
+ row_offset: cursor.start,
236
+ };
237
+ };
238
+ export const readResource = ({ bytes, layout, row, maxBytes, directory, issues, }) => {
239
+ const cursor = rowCursor({ bytes, layout, table: 40, row });
240
+ const declaredOffset = cursor.readUInt32();
241
+ const flags = cursor.readUInt32();
242
+ const name = readMetadataString(bytes, layout, cursor.readIndex(layout.stringIndexSize), maxBytes);
243
+ const implementationRaw = cursor.readIndex(layout.codedIndexSize("Implementation"));
244
+ const implementationToken = codedToken(implementationRaw, 2, [38, 35, 39]);
245
+ let dataLength = null;
246
+ let dataSha256 = null;
247
+ if (implementationRaw === 0) {
248
+ if (directory === null || declaredOffset > directory.size - 4) {
249
+ issues.push({
250
+ code: "invalid-resource",
251
+ scope: `metadata.ManifestResource:${metadataToken(40, row)}`,
252
+ offset: directory?.offset ?? null,
253
+ detail: "Embedded resource offset leaves the CLI resources directory",
254
+ });
255
+ }
256
+ else {
257
+ const start = directory.offset + declaredOffset;
258
+ dataLength = bytes.readUInt32LE(start);
259
+ if (dataLength > directory.size - declaredOffset - 4) {
260
+ issues.push({
261
+ code: "invalid-resource",
262
+ scope: `metadata.ManifestResource:${metadataToken(40, row)}`,
263
+ offset: start,
264
+ detail: "Embedded resource length leaves the CLI resources directory",
265
+ });
266
+ }
267
+ else if (dataLength > maxBytes) {
268
+ issues.push({
269
+ code: "limit-exceeded",
270
+ scope: `metadata.ManifestResource:${metadataToken(40, row)}`,
271
+ offset: start + 4,
272
+ detail: `Embedded resource exceeds max_heap_item_bytes ${String(maxBytes)}; digest omitted`,
273
+ });
274
+ }
275
+ else {
276
+ dataSha256 = sha256Bytes(bytes.subarray(start + 4, start + 4 + dataLength));
277
+ }
278
+ }
279
+ }
280
+ return {
281
+ name,
282
+ flags,
283
+ visibility: (flags & 7) === 1 ? "public" : (flags & 7) === 2 ? "private" : "unknown",
284
+ implementation_token: implementationToken,
285
+ embedded: implementationRaw === 0,
286
+ declared_offset: declaredOffset,
287
+ data_length: dataLength,
288
+ data_sha256: dataSha256,
289
+ token: metadataToken(40, row),
290
+ row_offset: cursor.start,
291
+ };
292
+ };