@futpib/parser 1.0.0 → 1.0.2

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 (380) hide show
  1. package/build/allSettledStream.js +32 -14
  2. package/build/allSettledStream.test.js +32 -0
  3. package/build/androidPackage.d.ts +39 -0
  4. package/build/androidPackageParser.d.ts +17 -0
  5. package/build/androidPackageParser.js +183 -0
  6. package/build/{apkParser.test.js → androidPackageParser.test.js} +7 -7
  7. package/build/androidPackageUnparser.d.ts +4 -0
  8. package/build/androidPackageUnparser.js +90 -0
  9. package/build/androidPackageUnparser.test.js +26 -0
  10. package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
  11. package/build/arbitrarilySlicedAsyncInterable.js +3 -3
  12. package/build/arbitraryFileSystemEntry.js +1 -1
  13. package/build/arbitraryZip.d.ts +1 -1
  14. package/build/arbitraryZip.js +13 -19
  15. package/build/arbitraryZipPermissions.d.ts +1 -8
  16. package/build/arbitraryZipPermissions.js +1 -16
  17. package/build/arbitraryZipStream.d.ts +1 -1
  18. package/build/arbitraryZipStream.js +3 -3
  19. package/build/arrayParser.d.ts +1 -1
  20. package/build/arrayParser.js +2 -2
  21. package/build/arrayParser.test.js +4 -4
  22. package/build/arrayUnparser.d.ts +2 -0
  23. package/build/arrayUnparser.js +8 -0
  24. package/build/backsmali.d.ts +1 -0
  25. package/build/backsmali.js +22 -0
  26. package/build/bsonParser.js +6 -2
  27. package/build/bsonParser.test.js +2 -2
  28. package/build/{parserInvariant.d.ts → customInvariant.d.ts} +1 -1
  29. package/build/{parserInvariant.js → customInvariant.js} +1 -1
  30. package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
  31. package/build/dalvikBytecodeParser/formatParsers.js +169 -0
  32. package/build/dalvikBytecodeParser.d.ts +107 -0
  33. package/build/dalvikBytecodeParser.js +836 -0
  34. package/build/dalvikExecutable.d.ts +158 -0
  35. package/build/dalvikExecutable.js +20 -0
  36. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  37. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  38. package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
  39. package/build/dalvikExecutableParser/typeParsers.js +34 -0
  40. package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
  41. package/build/dalvikExecutableParser/typedNumbers.js +19 -0
  42. package/build/dalvikExecutableParser.d.ts +5 -0
  43. package/build/dalvikExecutableParser.js +1439 -0
  44. package/build/dalvikExecutableParser.test.js +70 -0
  45. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
  46. package/build/debugLogInputParser.d.ts +4 -0
  47. package/build/debugLogInputParser.js +16 -0
  48. package/build/debugLogParser.d.ts +1 -1
  49. package/build/debugLogParser.js +15 -4
  50. package/build/disjunctionParser.d.ts +2 -1
  51. package/build/disjunctionParser.js +4 -2
  52. package/build/elementParser.d.ts +2 -2
  53. package/build/elementParser.js +1 -1
  54. package/build/elementTerminatedArrayParser.d.ts +3 -0
  55. package/build/elementTerminatedArrayParser.js +18 -0
  56. package/build/elementTerminatedArrayParser.test.js +52 -0
  57. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  58. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  59. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  60. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  61. package/build/elementTerminatedSequenceParser.js +27 -0
  62. package/build/elementTerminatedSequenceParser.test.js +34 -0
  63. package/build/endOfInputParser.d.ts +2 -2
  64. package/build/exactElementParser.d.ts +1 -1
  65. package/build/exactElementParser.js +10 -5
  66. package/build/exactSequenceParser.d.ts +2 -1
  67. package/build/exactSequenceParser.js +12 -2
  68. package/build/fetchCid.d.ts +1 -0
  69. package/build/fetchCid.js +107 -0
  70. package/build/fixedLengthSequenceParser.d.ts +1 -0
  71. package/build/fixedLengthSequenceParser.js +18 -1
  72. package/build/fixedLengthSequenceParser.test.js +41 -0
  73. package/build/hasExecutable.d.ts +1 -0
  74. package/build/hasExecutable.js +8 -0
  75. package/build/highResolutionTimer.d.ts +16 -0
  76. package/build/highResolutionTimer.js +42 -0
  77. package/build/index.d.ts +5 -2
  78. package/build/index.js +3 -0
  79. package/build/inputReader.d.ts +14 -3
  80. package/build/inputReader.js +43 -6
  81. package/build/inputReader.test.js +172 -7
  82. package/build/inputReaderState.d.ts +10 -0
  83. package/build/inputReaderState.js +16 -0
  84. package/build/inspect.d.ts +1 -0
  85. package/build/inspect.js +7 -0
  86. package/build/javaKeyStoreParser.d.ts +2 -0
  87. package/build/javaKeyStoreParser.js +67 -0
  88. package/build/javaKeyStoreParser.test.d.ts +1 -0
  89. package/build/javaKeyStoreParser.test.js +16 -0
  90. package/build/jsonParser.d.ts +2 -0
  91. package/build/jsonParser.js +13 -15
  92. package/build/jsonParser.test.js +2 -2
  93. package/build/leb128Parser.d.ts +7 -0
  94. package/build/leb128Parser.js +82 -0
  95. package/build/leb128Parser.test.d.ts +1 -0
  96. package/build/leb128Parser.test.js +107 -0
  97. package/build/listParser.d.ts +1 -1
  98. package/build/listParser.js +5 -5
  99. package/build/lookaheadParser.d.ts +2 -0
  100. package/build/lookaheadParser.js +14 -0
  101. package/build/{negativeLookahead.d.ts → negativeLookaheadParser.d.ts} +1 -1
  102. package/build/negativeLookaheadParser.js +24 -0
  103. package/build/negativeLookaheadParser.test.d.ts +1 -0
  104. package/build/negativeLookaheadParser.test.js +30 -0
  105. package/build/nonEmptyArrayParser.d.ts +2 -0
  106. package/build/nonEmptyArrayParser.js +32 -0
  107. package/build/nonEmptyArrayParser.test.d.ts +1 -0
  108. package/build/nonEmptyArrayParser.test.js +16 -0
  109. package/build/optionalParser.d.ts +1 -1
  110. package/build/optionalParser.js +2 -2
  111. package/build/parser.d.ts +13 -4
  112. package/build/parser.js +67 -32
  113. package/build/parser.test.js +94 -27
  114. package/build/parserAccessorParser.d.ts +1 -1
  115. package/build/parserAccessorParser.js +9 -1
  116. package/build/parserConsumedSequenceParser.d.ts +2 -0
  117. package/build/parserConsumedSequenceParser.js +22 -0
  118. package/build/parserContext.d.ts +20 -6
  119. package/build/parserContext.js +70 -40
  120. package/build/parserContext.test.js +34 -7
  121. package/build/parserCreatorCompose.d.ts +4 -3
  122. package/build/parserCreatorCompose.js +9 -3
  123. package/build/parserError.d.ts +6 -0
  124. package/build/parserError.js +6 -6
  125. package/build/parserImplementationInvariant.d.ts +1 -1
  126. package/build/parserImplementationInvariant.js +2 -2
  127. package/build/parserInputCompanion.d.ts +35 -0
  128. package/build/parserInputCompanion.js +68 -0
  129. package/build/promiseCompose.d.ts +1 -1
  130. package/build/promiseCompose.js +12 -1
  131. package/build/promiseSettled.d.ts +1 -0
  132. package/build/promiseSettled.js +4 -0
  133. package/build/quantifierParser.d.ts +2 -0
  134. package/build/quantifierParser.js +17 -0
  135. package/build/separatedArrayParser.d.ts +2 -0
  136. package/build/separatedArrayParser.js +39 -0
  137. package/build/separatedArrayParser.test.d.ts +1 -0
  138. package/build/separatedArrayParser.test.js +21 -0
  139. package/build/sequenceBuffer.d.ts +13 -3
  140. package/build/sequenceBuffer.js +60 -8
  141. package/build/sequenceBuffer.test.js +59 -2
  142. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  143. package/build/sequenceTerminatedSequenceParser.js +32 -0
  144. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  145. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  146. package/build/sequenceUnparser.d.ts +2 -0
  147. package/build/sequenceUnparser.js +6 -0
  148. package/build/skipParser.d.ts +1 -1
  149. package/build/skipParser.js +4 -2
  150. package/build/skipToParser.d.ts +2 -0
  151. package/build/skipToParser.js +11 -0
  152. package/build/sliceBoundedParser.d.ts +2 -2
  153. package/build/sliceBoundedParser.js +8 -3
  154. package/build/sliceBoundedParser.test.js +37 -3
  155. package/build/smali.d.ts +1 -0
  156. package/build/smali.js +17 -0
  157. package/build/smaliParser.d.ts +12 -0
  158. package/build/smaliParser.js +656 -0
  159. package/build/smaliParser.test.d.ts +1 -0
  160. package/build/smaliParser.test.js +115 -0
  161. package/build/terminatedArrayParser.d.ts +4 -2
  162. package/build/terminatedArrayParser.js +82 -5
  163. package/build/terminatedArrayParser.test.d.ts +1 -0
  164. package/build/terminatedArrayParser.test.js +131 -0
  165. package/build/toAsyncIterable.d.ts +1 -0
  166. package/build/toAsyncIterable.js +7 -0
  167. package/build/toAsyncIterator.d.ts +1 -0
  168. package/build/toAsyncIterator.js +33 -0
  169. package/build/tupleParser.d.ts +4 -0
  170. package/build/tupleParser.js +1 -5
  171. package/build/uint8Array.d.ts +1 -0
  172. package/build/uint8Array.js +7 -0
  173. package/build/unionParser.d.ts +2 -1
  174. package/build/unionParser.js +27 -12
  175. package/build/unionParser.test.d.ts +1 -0
  176. package/build/unionParser.test.js +60 -0
  177. package/build/unparser.d.ts +8 -0
  178. package/build/unparser.js +104 -0
  179. package/build/unparser.test.d.ts +1 -0
  180. package/build/unparser.test.js +150 -0
  181. package/build/unparserContext.d.ts +31 -0
  182. package/build/unparserContext.js +74 -0
  183. package/build/unparserError.d.ts +9 -0
  184. package/build/unparserError.js +9 -0
  185. package/build/unparserImplementationInvariant.d.ts +2 -0
  186. package/build/unparserImplementationInvariant.js +5 -0
  187. package/build/unparserOutputCompanion.d.ts +15 -0
  188. package/build/unparserOutputCompanion.js +13 -0
  189. package/build/zip.d.ts +9 -17
  190. package/build/zipParser.d.ts +20 -12
  191. package/build/zipParser.js +83 -71
  192. package/build/zipParser.test.js +2 -7
  193. package/build/zipUnparser.d.ts +8 -0
  194. package/build/zipUnparser.js +200 -0
  195. package/build/zipUnparser.test.d.ts +1 -0
  196. package/build/zipUnparser.test.js +80 -0
  197. package/package.json +26 -8
  198. package/src/allSettledStream.test.ts +40 -0
  199. package/src/allSettledStream.ts +47 -15
  200. package/src/androidPackage.ts +48 -0
  201. package/src/{apkParser.test.ts → androidPackageParser.test.ts} +7 -8
  202. package/src/androidPackageParser.test.ts.md +271 -0
  203. package/src/androidPackageParser.test.ts.snap +0 -0
  204. package/src/androidPackageParser.ts +440 -0
  205. package/src/androidPackageUnparser.test.ts +36 -0
  206. package/src/androidPackageUnparser.ts +120 -0
  207. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  208. package/src/arbitraryFileSystemEntry.ts +2 -4
  209. package/src/arbitraryZip.ts +20 -27
  210. package/src/arbitraryZipPermissions.ts +0 -25
  211. package/src/arbitraryZipStream.ts +4 -4
  212. package/src/arrayParser.test.ts +4 -4
  213. package/src/arrayParser.ts +3 -2
  214. package/src/arrayUnparser.ts +13 -0
  215. package/src/backsmali.ts +30 -0
  216. package/src/bsonParser.test.ts +2 -2
  217. package/src/bsonParser.ts +16 -5
  218. package/src/{parserInvariant.ts → customInvariant.ts} +2 -2
  219. package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
  220. package/src/dalvikBytecodeParser.ts +2074 -0
  221. package/src/dalvikExecutable.ts +220 -0
  222. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  223. package/src/dalvikExecutableParser/typeParsers.ts +65 -0
  224. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  225. package/src/dalvikExecutableParser.test.ts +89 -0
  226. package/src/dalvikExecutableParser.test.ts.md +634 -0
  227. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  228. package/src/dalvikExecutableParser.ts +2768 -0
  229. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
  230. package/src/debugLogInputParser.ts +28 -0
  231. package/src/debugLogParser.ts +20 -4
  232. package/src/disjunctionParser.ts +10 -5
  233. package/src/elementParser.ts +3 -3
  234. package/src/elementTerminatedArrayParser.test.ts +99 -0
  235. package/src/elementTerminatedArrayParser.ts +31 -0
  236. package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
  237. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  238. package/src/elementTerminatedSequenceParser.test.ts +54 -0
  239. package/src/elementTerminatedSequenceParser.ts +43 -0
  240. package/src/endOfInputParser.ts +4 -4
  241. package/src/exactElementParser.ts +18 -12
  242. package/src/exactSequenceParser.ts +24 -3
  243. package/src/fetchCid.ts +125 -0
  244. package/src/fixedLengthSequenceParser.test.ts +77 -0
  245. package/src/fixedLengthSequenceParser.ts +28 -1
  246. package/src/hasExecutable.ts +11 -0
  247. package/src/highResolutionTimer.ts +49 -0
  248. package/src/index.ts +15 -2
  249. package/src/inputReader.test.ts +216 -7
  250. package/src/inputReader.ts +80 -5
  251. package/src/inputReaderState.ts +33 -0
  252. package/src/inspect.ts +9 -0
  253. package/src/javaKeyStore.ts +0 -0
  254. package/src/javaKeyStoreParser.test.ts +22 -0
  255. package/src/javaKeyStoreParser.test.ts.md +103 -0
  256. package/src/javaKeyStoreParser.test.ts.snap +0 -0
  257. package/src/javaKeyStoreParser.ts +136 -0
  258. package/src/jsonParser.test.ts +2 -2
  259. package/src/jsonParser.ts +23 -34
  260. package/src/leb128Parser.test.ts +171 -0
  261. package/src/leb128Parser.ts +125 -0
  262. package/src/listParser.ts +6 -6
  263. package/src/lookaheadParser.ts +19 -0
  264. package/src/negativeLookaheadParser.test.ts +53 -0
  265. package/src/negativeLookaheadParser.ts +36 -0
  266. package/src/nonEmptyArrayParser.test.ts +20 -0
  267. package/src/nonEmptyArrayParser.ts +44 -0
  268. package/src/optionalParser.ts +4 -3
  269. package/src/parser.test.ts +148 -27
  270. package/src/parser.test.ts.md +21 -21
  271. package/src/parser.test.ts.snap +0 -0
  272. package/src/parser.ts +153 -49
  273. package/src/parserAccessorParser.ts +12 -2
  274. package/src/parserConsumedSequenceParser.ts +29 -0
  275. package/src/parserContext.test.ts +38 -7
  276. package/src/parserContext.ts +127 -51
  277. package/src/parserCreatorCompose.ts +25 -7
  278. package/src/parserError.ts +9 -6
  279. package/src/parserImplementationInvariant.ts +2 -2
  280. package/src/parserInputCompanion.ts +102 -0
  281. package/src/promiseCompose.ts +17 -3
  282. package/src/promiseSettled.ts +6 -0
  283. package/src/quantifierParser.ts +25 -0
  284. package/src/separatedArrayParser.test.ts +34 -0
  285. package/src/separatedArrayParser.ts +55 -0
  286. package/src/sequenceBuffer.test.ts +72 -2
  287. package/src/sequenceBuffer.ts +93 -7
  288. package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
  289. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  290. package/src/sequenceUnparser.ts +9 -0
  291. package/src/skipParser.ts +7 -5
  292. package/src/skipToParser.ts +16 -0
  293. package/src/sliceBoundedParser.test.ts +45 -3
  294. package/src/sliceBoundedParser.ts +21 -3
  295. package/src/smali.ts +24 -0
  296. package/src/smaliParser.test.ts +132 -0
  297. package/src/smaliParser.test.ts.md +2320 -0
  298. package/src/smaliParser.test.ts.snap +0 -0
  299. package/src/smaliParser.ts +1166 -0
  300. package/src/terminatedArrayParser.test.ts +258 -0
  301. package/src/terminatedArrayParser.ts +111 -6
  302. package/src/toAsyncIterable.ts +7 -0
  303. package/src/toAsyncIterator.ts +48 -0
  304. package/src/tupleParser.ts +8 -5
  305. package/src/uint8Array.ts +10 -0
  306. package/src/unionParser.test.ts +79 -0
  307. package/src/unionParser.ts +44 -16
  308. package/src/unparser.test.ts +221 -0
  309. package/src/unparser.ts +209 -0
  310. package/src/unparserContext.ts +127 -0
  311. package/src/unparserError.ts +12 -0
  312. package/src/unparserImplementationInvariant.ts +6 -0
  313. package/src/unparserOutputCompanion.ts +24 -0
  314. package/src/zip.ts +10 -22
  315. package/src/zipParser.test.ts +2 -8
  316. package/src/zipParser.ts +223 -146
  317. package/src/zipUnparser.test.ts +119 -0
  318. package/src/zipUnparser.ts +300 -0
  319. package/build/apk.d.ts +0 -13
  320. package/build/apkParser.d.ts +0 -3
  321. package/build/apkParser.js +0 -135
  322. package/build/arbitraryDosDate.d.ts +0 -2
  323. package/build/arbitraryDosDate.js +0 -8
  324. package/build/arbitraryZipEntry.d.ts +0 -3
  325. package/build/arbitraryZipEntry.js +0 -26
  326. package/build/createDisjunctionParser.d.ts +0 -2
  327. package/build/createDisjunctionParser.js +0 -47
  328. package/build/createExactParser.d.ts +0 -2
  329. package/build/createExactParser.js +0 -12
  330. package/build/createSequentialUnionParser.d.ts +0 -2
  331. package/build/createSequentialUnionParser.js +0 -69
  332. package/build/fixedLengthChunkParser.d.ts +0 -2
  333. package/build/fixedLengthChunkParser.js +0 -12
  334. package/build/fixedLengthParser.d.ts +0 -2
  335. package/build/fixedLengthParser.js +0 -12
  336. package/build/inputChunkBuffer.d.ts +0 -15
  337. package/build/inputChunkBuffer.js +0 -40
  338. package/build/inputChunkBuffer.test.js +0 -34
  339. package/build/inputCompanion.d.ts +0 -18
  340. package/build/inputCompanion.js +0 -28
  341. package/build/invariantDefined.d.ts +0 -1
  342. package/build/invariantDefined.js +0 -5
  343. package/build/invariantIdentity.d.ts +0 -3
  344. package/build/invariantIdentity.js +0 -5
  345. package/build/jsonParser2.d.ts +0 -3
  346. package/build/jsonParser2.js +0 -52
  347. package/build/jsonParser2.test.js +0 -22
  348. package/build/negativeLookahead.js +0 -20
  349. package/build/parserCompose.d.ts +0 -3
  350. package/build/parserCompose.js +0 -7
  351. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  352. package/build/parserImplementationInvariantInvariant.js +0 -15
  353. package/build/promiseFish.d.ts +0 -1
  354. package/build/promiseFish.js +0 -3
  355. package/build/sequenceParser.d.ts +0 -3
  356. package/build/sequenceParser.js +0 -10
  357. package/build/terminatedSequenceParser.d.ts +0 -2
  358. package/build/terminatedSequenceParser.js +0 -24
  359. package/build/zipEntry.d.ts +0 -28
  360. package/build/zipFile.d.ts +0 -32
  361. package/build/zipFileEntry.d.ts +0 -6
  362. package/src/apk.ts +0 -16
  363. package/src/apkParser.test.ts.md +0 -268
  364. package/src/apkParser.test.ts.snap +0 -0
  365. package/src/apkParser.ts +0 -327
  366. package/src/inputCompanion.ts +0 -43
  367. package/src/invariantDefined.ts +0 -6
  368. package/src/invariantIdentity.ts +0 -8
  369. package/src/negativeLookahead.ts +0 -26
  370. /package/build/{apk.js → androidPackage.js} +0 -0
  371. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  372. /package/build/{arbitraryDosPermissions.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  373. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
  374. /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  375. /package/build/{jsonParser2.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  376. /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  377. /package/build/{parserParsingInvariant.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
  378. /package/build/{zipEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
  379. /package/build/{zipFile.js → javaKeyStore.d.ts} +0 -0
  380. /package/build/{zipFileEntry.js → javaKeyStore.js} +0 -0
@@ -0,0 +1,1439 @@
1
+ import invariant from 'invariant';
2
+ import { MUtf8Decoder } from "mutf-8";
3
+ import { createExactElementParser } from './exactElementParser.js';
4
+ import { createExactSequenceParser } from './exactSequenceParser.js';
5
+ import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js';
6
+ import { cloneParser, setParserName } from './parser.js';
7
+ import { parserCreatorCompose } from './parserCreatorCompose.js';
8
+ import { promiseCompose } from './promiseCompose.js';
9
+ import { createQuantifierParser } from './quantifierParser.js';
10
+ import { createTupleParser } from './tupleParser.js';
11
+ import { createParserAccessorParser } from './parserAccessorParser.js';
12
+ import { createSkipToParser } from './skipToParser.js';
13
+ import { createLookaheadParser } from './lookaheadParser.js';
14
+ import { getIsoTypedNumberArray, isoIndexIntoFieldIds, isoIndexIntoMethodIds, isoIndexIntoPrototypeIds, isoIndexIntoStringIds, isoIndexIntoTypeIds, isoOffsetFromEncodedCatchHandlerListToEncodedCatchHandler, isoOffsetToAnnotationItem, isoOffsetToAnnotationsDirectoryItem, isoOffsetToAnnotationSetItem, isoOffsetToAnnotationSetRefListItem, isoOffsetToClassDataItem, isoOffsetToCodeItem, isoOffsetToDebugInfoItem, isoOffsetToEncodedArrayItem, isoOffsetToStringDataItem, isoOffsetToTypeList } from './dalvikExecutableParser/typedNumbers.js';
15
+ import { sleb128NumberParser, uleb128NumberParser } from './leb128Parser.js';
16
+ import { createDisjunctionParser } from './disjunctionParser.js';
17
+ import { createElementTerminatedSequenceParser } from './elementTerminatedSequenceParser.js';
18
+ import { createElementTerminatedArrayParserUnsafe } from './elementTerminatedArrayParser.js';
19
+ import { createDalvikBytecodeParser, resolveDalvikBytecodeOperation } from './dalvikBytecodeParser.js';
20
+ import { ubyteParser, uintParser, uleb128p1NumberParser, ushortParser } from './dalvikExecutableParser/typeParsers.js';
21
+ // https://source.android.com/docs/core/runtime/dex-format
22
+ const createByteAlignParser = (byteAlignment) => async (parserContext) => {
23
+ const toSkip = (byteAlignment - (parserContext.position % byteAlignment)) % byteAlignment;
24
+ parserContext.skip(toSkip);
25
+ };
26
+ const byteAlign4Parser = createByteAlignParser(4);
27
+ const dalvikExecutableHeaderVersionParser = promiseCompose(createTupleParser([
28
+ createExactSequenceParser(Buffer.from('dex\n', 'utf8')),
29
+ createFixedLengthSequenceParser(3),
30
+ createExactElementParser(0),
31
+ ]), ([_magic1, versionUint8Array, _magic2]) => {
32
+ const versionBuffer = Buffer.from(versionUint8Array);
33
+ const versionString = versionBuffer.toString('utf8');
34
+ const version = Number.parseInt(versionString, 10);
35
+ return version;
36
+ });
37
+ const sizeOffsetParser = promiseCompose(createTupleParser([
38
+ uintParser,
39
+ uintParser,
40
+ ]), ([size, offset]) => ({ size, offset }));
41
+ const dalvikExecutableHeaderItemParser = promiseCompose(createTupleParser([
42
+ dalvikExecutableHeaderVersionParser,
43
+ uintParser,
44
+ createFixedLengthSequenceParser(20),
45
+ uintParser,
46
+ uintParser,
47
+ uintParser,
48
+ sizeOffsetParser,
49
+ uintParser,
50
+ sizeOffsetParser,
51
+ sizeOffsetParser,
52
+ sizeOffsetParser,
53
+ sizeOffsetParser,
54
+ sizeOffsetParser,
55
+ sizeOffsetParser,
56
+ sizeOffsetParser,
57
+ ]), ([version, checksum, sha1Hash, fileSize, headerSize, endianTag, link, mapOffset, stringIds, typeIds, prototypeIds, fieldIds, methodIds, classDefinitions, data,]) => ({
58
+ version,
59
+ checksum,
60
+ sha1Hash,
61
+ fileSize,
62
+ headerSize,
63
+ endianTag,
64
+ link,
65
+ mapOffset,
66
+ stringIds,
67
+ typeIds,
68
+ prototypeIds,
69
+ fieldIds,
70
+ methodIds,
71
+ classDefinitions,
72
+ data,
73
+ }));
74
+ const dalvikExecutableStringIdItemParser = promiseCompose(cloneParser(uintParser), (offset) => isoOffsetToStringDataItem.wrap(offset));
75
+ const isoDalvikExecutableStringIdItems = getIsoTypedNumberArray();
76
+ const createSkipToThenStringIdItemsParser = ({ size, offset }) => (size === 0
77
+ ? (() => isoDalvikExecutableStringIdItems.wrap([]))
78
+ : promiseCompose(createTupleParser([
79
+ createSkipToParser(offset),
80
+ createQuantifierParser(dalvikExecutableStringIdItemParser, size),
81
+ ]), ([_, stringIds]) => isoDalvikExecutableStringIdItems.wrap(stringIds)));
82
+ const dalvikExecutableTypeIdItemParser = promiseCompose(cloneParser(uintParser), (index) => isoIndexIntoStringIds.wrap(index));
83
+ const isoDalvikExecutableTypeIdItems = getIsoTypedNumberArray();
84
+ const createSkipToThenTypeIdItemsParser = ({ size, offset }) => (size === 0
85
+ ? (() => isoDalvikExecutableTypeIdItems.wrap([]))
86
+ : promiseCompose(createTupleParser([
87
+ createSkipToParser(offset),
88
+ createQuantifierParser(dalvikExecutableTypeIdItemParser, size),
89
+ ]), ([_, typeIds]) => isoDalvikExecutableTypeIdItems.wrap(typeIds)));
90
+ const prototypeIdItemParser = promiseCompose(createTupleParser([
91
+ byteAlign4Parser,
92
+ uintParser,
93
+ uintParser,
94
+ uintParser,
95
+ ]), ([_, shortyIndex, returnTypeIndex, parametersOffset]) => ({
96
+ shortyIndex: isoIndexIntoStringIds.wrap(shortyIndex),
97
+ returnTypeIndex: isoIndexIntoTypeIds.wrap(returnTypeIndex),
98
+ parametersOffset: isoOffsetToTypeList.wrap(parametersOffset),
99
+ }));
100
+ const isoDalvikExecutablePrototypeIdItems = getIsoTypedNumberArray();
101
+ const createSkipToThenPrototypeIdItemsParser = ({ size, offset }) => (size === 0
102
+ ? (() => isoDalvikExecutablePrototypeIdItems.wrap([]))
103
+ : promiseCompose(createTupleParser([
104
+ createSkipToParser(offset),
105
+ createQuantifierParser(prototypeIdItemParser, size),
106
+ ]), ([_, prototypeIds]) => isoDalvikExecutablePrototypeIdItems.wrap(prototypeIds)));
107
+ const createSkipToThenItemByOffsetParser = ({ sizeOffset: { size, offset }, itemParser, byteAlign4, isoOffset, parserName, }) => {
108
+ const skipToThenItemByOffsetParser = async (parserContext) => {
109
+ const itemByOffset = new Map();
110
+ if (size === 0) {
111
+ return itemByOffset;
112
+ }
113
+ await createSkipToParser(offset)(parserContext);
114
+ for (let i = 0; i < size; i++) {
115
+ if (byteAlign4) {
116
+ await byteAlign4Parser(parserContext);
117
+ }
118
+ const offset = parserContext.position;
119
+ const item = await itemParser(parserContext);
120
+ itemByOffset.set(isoOffset.wrap(offset), item);
121
+ }
122
+ return itemByOffset;
123
+ };
124
+ setParserName(skipToThenItemByOffsetParser, parserName);
125
+ return skipToThenItemByOffsetParser;
126
+ };
127
+ const dalvikExecutableFieldIdItemParser = promiseCompose(createTupleParser([
128
+ ushortParser,
129
+ ushortParser,
130
+ uintParser,
131
+ ]), ([classIndex, typeIndex, nameIndex]) => ({
132
+ classIndex: isoIndexIntoTypeIds.wrap(classIndex),
133
+ typeIndex: isoIndexIntoTypeIds.wrap(typeIndex),
134
+ nameIndex: isoIndexIntoStringIds.wrap(nameIndex),
135
+ }));
136
+ const isoDalvikExecutableFieldIdItems = getIsoTypedNumberArray();
137
+ const createSkipToThenFieldIdItemsParser = ({ size, offset }) => (size === 0
138
+ ? (() => isoDalvikExecutableFieldIdItems.wrap([]))
139
+ : promiseCompose(createTupleParser([
140
+ createSkipToParser(offset),
141
+ createQuantifierParser(dalvikExecutableFieldIdItemParser, size),
142
+ ]), ([_, fieldIds]) => isoDalvikExecutableFieldIdItems.wrap(fieldIds)));
143
+ const dalvikExecutableMethodIdItemParser = promiseCompose(createTupleParser([
144
+ ushortParser,
145
+ ushortParser,
146
+ uintParser,
147
+ ]), ([classIndex, prototypeIndex, nameIndex]) => ({
148
+ classIndex: isoIndexIntoTypeIds.wrap(classIndex),
149
+ prototypeIndex: isoIndexIntoPrototypeIds.wrap(prototypeIndex),
150
+ nameIndex: isoIndexIntoStringIds.wrap(nameIndex),
151
+ }));
152
+ const isoDalvikExecutableMethodIdItems = getIsoTypedNumberArray();
153
+ const createSkipToThenMethodIdItemsParser = ({ size, offset }) => (size === 0
154
+ ? (() => isoDalvikExecutableMethodIdItems.wrap([]))
155
+ : promiseCompose(createTupleParser([
156
+ createSkipToParser(offset),
157
+ createQuantifierParser(dalvikExecutableMethodIdItemParser, size),
158
+ ]), ([_, methodIds]) => isoDalvikExecutableMethodIdItems.wrap(methodIds)));
159
+ const uintAccessFlagsParser = promiseCompose(uintParser, (flags) => ({
160
+ public: Boolean(flags & 0b00000001),
161
+ private: Boolean(flags & 0b00000010),
162
+ protected: Boolean(flags & 0b00000100),
163
+ static: Boolean(flags & 0b00001000),
164
+ final: Boolean(flags & 0b00010000),
165
+ synchronized: Boolean(flags & 0b00100000),
166
+ volatile: Boolean(flags & 0b01000000),
167
+ bridge: Boolean(flags & 0b01000000),
168
+ transient: Boolean(flags & 0b10000000),
169
+ varargs: Boolean(flags & 0b10000000),
170
+ native: false,
171
+ interface: false,
172
+ abstract: false,
173
+ strict: false,
174
+ synthetic: false,
175
+ annotation: false,
176
+ enum: false,
177
+ constructor: false,
178
+ declaredSynchronized: false,
179
+ }));
180
+ const uleb128AccessFlagsParser = promiseCompose(uleb128NumberParser, flags => ({
181
+ public: Boolean(flags & 0b00000001),
182
+ private: Boolean(flags & 0b00000010),
183
+ protected: Boolean(flags & 0b00000100),
184
+ static: Boolean(flags & 0b00001000),
185
+ final: Boolean(flags & 0b00010000),
186
+ synchronized: Boolean(flags & 0b00100000),
187
+ volatile: Boolean(flags & 0b01000000),
188
+ bridge: Boolean(flags & 0b01000000),
189
+ transient: Boolean(flags & 0b10000000),
190
+ varargs: Boolean(flags & 0b10000000),
191
+ native: Boolean(flags & 0b00000001_00000000),
192
+ interface: Boolean(flags & 0b00000010_00000000),
193
+ abstract: Boolean(flags & 0b00000100_00000000),
194
+ strict: Boolean(flags & 0b00001000_00000000),
195
+ synthetic: Boolean(flags & 0b00010000_00000000),
196
+ annotation: Boolean(flags & 0b00100000_00000000),
197
+ enum: Boolean(flags & 0b01000000_00000000),
198
+ constructor: Boolean(flags & 0b00000001_00000000_00000000),
199
+ declaredSynchronized: Boolean(flags & 0b00000010_00000000_00000000),
200
+ }));
201
+ const DEX_CLASS_DEFINITION_ITEM_SOURCE_FILE_NO_INDEX = 0xffffffff;
202
+ const createSkipToThenClassDefinitionItemsParser = ({ size, offset }) => (size === 0
203
+ ? (() => [])
204
+ : promiseCompose(createTupleParser([
205
+ createSkipToParser(offset),
206
+ createQuantifierParser(promiseCompose(createTupleParser([
207
+ uintParser,
208
+ uintAccessFlagsParser,
209
+ uintParser,
210
+ uintParser,
211
+ uintParser,
212
+ uintParser,
213
+ uintParser,
214
+ uintParser,
215
+ ]), ([classIndex, accessFlags, superclassIndex, interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset, staticValuesOffset,]) => ({
216
+ classIndex: isoIndexIntoTypeIds.wrap(classIndex),
217
+ accessFlags,
218
+ superclassIndex: isoIndexIntoTypeIds.wrap(superclassIndex),
219
+ interfacesOffset: isoOffsetToTypeList.wrap(interfacesOffset),
220
+ sourceFileIndex: (sourceFileIndex === DEX_CLASS_DEFINITION_ITEM_SOURCE_FILE_NO_INDEX
221
+ ? undefined
222
+ : isoIndexIntoStringIds.wrap(sourceFileIndex)),
223
+ annotationsOffset: isoOffsetToAnnotationsDirectoryItem.wrap(annotationsOffset),
224
+ classDataOffset: isoOffsetToClassDataItem.wrap(classDataOffset),
225
+ staticValuesOffset: isoOffsetToEncodedArrayItem.wrap(staticValuesOffset),
226
+ })), size),
227
+ ]), ([_, classDefinitions]) => classDefinitions));
228
+ const createRawDataParser = ({ size, offset }) => (size === 0
229
+ ? (() => undefined)
230
+ : promiseCompose(createTupleParser([
231
+ createSkipToParser(offset),
232
+ createFixedLengthSequenceParser(size),
233
+ ]), ([_, data]) => data));
234
+ const stringDataItemParser = promiseCompose(createTupleParser([
235
+ uleb128NumberParser,
236
+ createElementTerminatedSequenceParser(0),
237
+ ]), ([utf16Size, data]) => ({
238
+ utf16Size,
239
+ data: new Uint8Array(data),
240
+ }));
241
+ const stringDataItemStringParser = promiseCompose(stringDataItemParser, ({ utf16Size, data }) => {
242
+ const mutf8Decoder = new MUtf8Decoder();
243
+ const string = mutf8Decoder.decode(data);
244
+ invariant(string.length === utf16Size, 'String length mismatch. Expected: %s, actual: %s', utf16Size, string.length);
245
+ return string;
246
+ });
247
+ const createSkipToThenStringsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
248
+ sizeOffset,
249
+ itemParser: stringDataItemStringParser,
250
+ byteAlign4: false,
251
+ isoOffset: isoOffsetToStringDataItem,
252
+ parserName: 'skipToThenStringsParser',
253
+ });
254
+ const dalvikExecutableTypeItemParser = promiseCompose(cloneParser(ushortParser), (index) => isoIndexIntoTypeIds.wrap(index));
255
+ const isoDalvikExecutableTypeList = getIsoTypedNumberArray();
256
+ const dalvikExecutableTypeListParser = parserCreatorCompose(() => createTupleParser([
257
+ byteAlign4Parser,
258
+ uintParser,
259
+ ]), ([_, size]) => promiseCompose(createQuantifierParser(dalvikExecutableTypeItemParser, size), (typeItems) => isoDalvikExecutableTypeList.wrap(typeItems)))();
260
+ const createSkipToThenTypeListByOffsetParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
261
+ sizeOffset,
262
+ itemParser: dalvikExecutableTypeListParser,
263
+ byteAlign4: true,
264
+ isoOffset: isoOffsetToTypeList,
265
+ parserName: 'skipToThenTypeListByOffsetParser',
266
+ });
267
+ const fieldAnnotationParser = promiseCompose(createTupleParser([
268
+ uintParser,
269
+ uintParser,
270
+ ]), ([fieldIndex, annotationsOffset,]) => ({
271
+ fieldIndex: isoIndexIntoFieldIds.wrap(fieldIndex),
272
+ annotationsOffset: isoOffsetToAnnotationSetItem.wrap(annotationsOffset),
273
+ }));
274
+ const createFieldAnnotationsParser = (fieldsSize) => createQuantifierParser(fieldAnnotationParser, fieldsSize);
275
+ const methodAnnotationParser = promiseCompose(createTupleParser([
276
+ uintParser,
277
+ uintParser,
278
+ ]), ([methodIndex, annotationsOffset,]) => ({
279
+ methodIndex: isoIndexIntoMethodIds.wrap(methodIndex),
280
+ annotationsOffset: isoOffsetToAnnotationSetItem.wrap(annotationsOffset),
281
+ }));
282
+ const createMethodAnnotationsParser = (methodsSize) => createQuantifierParser(methodAnnotationParser, methodsSize);
283
+ const parameterAnnotationParser = promiseCompose(createTupleParser([
284
+ uintParser,
285
+ uintParser,
286
+ ]), ([methodIndex, annotationsOffset,]) => ({
287
+ methodIndex: isoIndexIntoMethodIds.wrap(methodIndex),
288
+ annotationsOffset: isoOffsetToAnnotationSetRefListItem.wrap(annotationsOffset),
289
+ }));
290
+ const createParameterAnnotationsParser = (parametersSize) => createQuantifierParser(parameterAnnotationParser, parametersSize);
291
+ const annotationsDirectoryItemParser = parserCreatorCompose(() => createTupleParser([
292
+ byteAlign4Parser,
293
+ uintParser,
294
+ uintParser,
295
+ uintParser,
296
+ uintParser,
297
+ ]), ([_, classAnnotationsOffset, fieldsSize, annotatedMethodsSize, annotatedParametersSize,]) => promiseCompose(createTupleParser([
298
+ () => isoOffsetToAnnotationSetItem.wrap(classAnnotationsOffset),
299
+ createFieldAnnotationsParser(fieldsSize),
300
+ createMethodAnnotationsParser(annotatedMethodsSize),
301
+ createParameterAnnotationsParser(annotatedParametersSize),
302
+ ]), ([classAnnotationsOffset, fieldAnnotations, methodAnnotations, parameterAnnotations,]) => ({
303
+ classAnnotationsOffset,
304
+ fieldAnnotations,
305
+ methodAnnotations,
306
+ parameterAnnotations,
307
+ })))();
308
+ const createSkipToThenAnnotationsDirectoryItemsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
309
+ sizeOffset,
310
+ itemParser: annotationsDirectoryItemParser,
311
+ byteAlign4: true,
312
+ isoOffset: isoOffsetToAnnotationsDirectoryItem,
313
+ parserName: 'skipToThenAnnotationsDirectoryItemsParser',
314
+ });
315
+ const encodedFieldParser = promiseCompose(createTupleParser([
316
+ uleb128NumberParser,
317
+ uleb128AccessFlagsParser,
318
+ ]), ([fieldIndexDiff, accessFlags]) => ({ fieldIndexDiff, accessFlags }));
319
+ const createEncodedFieldsParser = (fieldsSize) => promiseCompose(createQuantifierParser(encodedFieldParser, fieldsSize), (encodedFields) => {
320
+ let previousFieldIndex = 0;
321
+ return encodedFields.map(({ fieldIndexDiff, accessFlags }) => {
322
+ previousFieldIndex += fieldIndexDiff;
323
+ return {
324
+ fieldIndex: isoIndexIntoFieldIds.wrap(previousFieldIndex),
325
+ accessFlags,
326
+ };
327
+ });
328
+ });
329
+ const encodedMethodParser = promiseCompose(createTupleParser([
330
+ uleb128NumberParser,
331
+ uleb128AccessFlagsParser,
332
+ uleb128NumberParser,
333
+ ]), ([methodIndexDiff, accessFlags, codeOffset,]) => ({
334
+ methodIndexDiff,
335
+ accessFlags,
336
+ codeOffset: isoOffsetToCodeItem.wrap(codeOffset),
337
+ }));
338
+ const createEncodedMethodsParser = (methodsSize) => promiseCompose(createQuantifierParser(encodedMethodParser, methodsSize), (encodedMethods) => {
339
+ let previousMethodIndex = 0;
340
+ return encodedMethods.map(({ methodIndexDiff, accessFlags, codeOffset }) => {
341
+ previousMethodIndex += methodIndexDiff;
342
+ return {
343
+ methodIndex: isoIndexIntoMethodIds.wrap(previousMethodIndex),
344
+ accessFlags,
345
+ codeOffset,
346
+ };
347
+ });
348
+ });
349
+ const classDataItemParser = parserCreatorCompose(() => createTupleParser([
350
+ uleb128NumberParser,
351
+ uleb128NumberParser,
352
+ uleb128NumberParser,
353
+ uleb128NumberParser,
354
+ ]), ([staticFieldsSize, instanceFieldsSize, directMethodsSize, virtualMethodsSize,]) => promiseCompose(createTupleParser([
355
+ createEncodedFieldsParser(staticFieldsSize),
356
+ createEncodedFieldsParser(instanceFieldsSize),
357
+ createEncodedMethodsParser(directMethodsSize),
358
+ createEncodedMethodsParser(virtualMethodsSize),
359
+ ]), ([staticFields, instanceFields, directMethods, virtualMethods,]) => ({
360
+ staticFields,
361
+ instanceFields,
362
+ directMethods,
363
+ virtualMethods,
364
+ })))();
365
+ const createSkipToThenClassDataItemsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
366
+ sizeOffset,
367
+ itemParser: classDataItemParser,
368
+ byteAlign4: false,
369
+ isoOffset: isoOffsetToClassDataItem,
370
+ parserName: 'skipToThenClassDataItemsParser',
371
+ });
372
+ const createByteWith5LeastSignificantBitsEqualParser = (leastSignificant5) => {
373
+ const byteWith5LeastSignificantBitsEqualParser = async (parserContext) => {
374
+ const byte = await parserContext.read(0);
375
+ parserContext.invariant((byte & 0b00011111) === leastSignificant5, 'Expected byte with 5 least significant bits equal to %s, but got %s', leastSignificant5.toString(2).padStart(8, '0'), byte.toString(2).padStart(8, '0'));
376
+ return byte;
377
+ };
378
+ setParserName(byteWith5LeastSignificantBitsEqualParser, `createByteWith5LeastSignificantBitsEqualParser(${leastSignificant5.toString(2).padStart(5, '0')})`);
379
+ return byteWith5LeastSignificantBitsEqualParser;
380
+ };
381
+ const createEncodedValueArgParser = (valueType) => promiseCompose(createByteWith5LeastSignificantBitsEqualParser(valueType), (byte) => byte >> 5);
382
+ const encodedValueByteParser = promiseCompose(createTupleParser([
383
+ createExactElementParser(0),
384
+ ubyteParser,
385
+ ]), ([_, value]) => value);
386
+ setParserName(encodedValueByteParser, 'encodedValueByteParser');
387
+ const encodedValueShortParser = parserCreatorCompose(() => createEncodedValueArgParser(0x02), sizeSubOne => {
388
+ const size = sizeSubOne + 1;
389
+ if (size === 1) {
390
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
391
+ const buffer = Buffer.from(uint8Array);
392
+ return buffer.readInt8(0);
393
+ });
394
+ }
395
+ invariant(size === 2, '(encodedValueShortParser) Unexpected size: %s', size);
396
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
397
+ const buffer = Buffer.from(uint8Array);
398
+ return buffer.readInt16LE(0);
399
+ });
400
+ })();
401
+ setParserName(encodedValueShortParser, 'encodedValueShortParser');
402
+ const encodedValueCharParser = parserCreatorCompose(() => createEncodedValueArgParser(0x03), sizeSubOne => {
403
+ const size = sizeSubOne + 1;
404
+ if (size == 1) {
405
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
406
+ const buffer = Buffer.from([0, ...uint8Array]);
407
+ return buffer.readUInt16LE(0);
408
+ });
409
+ }
410
+ invariant(size === 2, '(encodedValueCharParser) Unexpected size: %s', size);
411
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
412
+ const buffer = Buffer.from(uint8Array);
413
+ return buffer.readUInt16LE(0);
414
+ });
415
+ })();
416
+ setParserName(encodedValueCharParser, 'encodedValueCharParser');
417
+ const encodedValueIntParser = parserCreatorCompose(() => createEncodedValueArgParser(0x04), sizeSubOne => {
418
+ const size = sizeSubOne + 1;
419
+ if (size === 1) {
420
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
421
+ const buffer = Buffer.from(uint8Array);
422
+ return buffer.readInt8(0);
423
+ });
424
+ }
425
+ if (size === 2) {
426
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
427
+ const buffer = Buffer.from(uint8Array);
428
+ return buffer.readInt16LE(0);
429
+ });
430
+ }
431
+ if (size === 3) {
432
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
433
+ const firstByte = uint8Array[0];
434
+ const firstBit = (firstByte & 0b10000000) >> 7;
435
+ const extensionByte = firstBit === 1 ? 0xff : 0x00;
436
+ const buffer = Buffer.from([extensionByte, ...uint8Array]);
437
+ return buffer.readInt32LE(0);
438
+ });
439
+ }
440
+ invariant(size === 4, '(encodedValueIntParser) Unexpected size: %s', size);
441
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
442
+ const buffer = Buffer.from(uint8Array);
443
+ return buffer.readInt32LE(0);
444
+ });
445
+ })();
446
+ setParserName(encodedValueIntParser, 'encodedValueIntParser');
447
+ const encodedValueLongParser = parserCreatorCompose(() => createEncodedValueArgParser(0x06), sizeSubOne => {
448
+ const size = sizeSubOne + 1;
449
+ if (size === 1) {
450
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
451
+ const buffer = Buffer.from(uint8Array);
452
+ return BigInt(buffer.readInt8(0));
453
+ });
454
+ }
455
+ if (size === 2) {
456
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
457
+ const buffer = Buffer.from(uint8Array);
458
+ return BigInt(buffer.readInt16LE(0));
459
+ });
460
+ }
461
+ if (size === 3) {
462
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
463
+ const firstByte = uint8Array[0];
464
+ const firstBit = (firstByte & 0b10000000) >> 7;
465
+ const extensionByte = firstBit === 1 ? 0xff : 0x00;
466
+ const buffer = Buffer.from([extensionByte, ...uint8Array]);
467
+ return BigInt(buffer.readInt32LE(0));
468
+ });
469
+ }
470
+ if (size === 4) {
471
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
472
+ const buffer = Buffer.from(uint8Array);
473
+ return BigInt(buffer.readInt32LE(0));
474
+ });
475
+ }
476
+ if (size === 5) {
477
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
478
+ const firstByte = uint8Array[0];
479
+ const firstBit = (firstByte & 0b10000000) >> 7;
480
+ const extensionByte = firstBit === 1 ? 0xff : 0x00;
481
+ const buffer = Buffer.from([extensionByte, extensionByte, extensionByte, ...uint8Array]);
482
+ return BigInt(buffer.readBigInt64LE(0));
483
+ });
484
+ }
485
+ invariant(size === 8, '(encodedValueLongParser) Unexpected size: %s', size);
486
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
487
+ const buffer = Buffer.from(uint8Array);
488
+ return buffer.readBigInt64LE(0);
489
+ });
490
+ })();
491
+ setParserName(encodedValueLongParser, 'encodedValueLongParser');
492
+ const encodedValueFloatParser = parserCreatorCompose(() => createEncodedValueArgParser(0x10), sizeSubOne => {
493
+ const size = sizeSubOne + 1;
494
+ if (size === 1) {
495
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
496
+ const buffer = Buffer.from([...uint8Array, 0, 0, 0]);
497
+ return buffer.readFloatLE(0);
498
+ });
499
+ }
500
+ if (size === 2) {
501
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
502
+ const buffer = Buffer.from([...uint8Array, 0, 0]);
503
+ return buffer.readFloatLE(0);
504
+ });
505
+ }
506
+ invariant(size === 4, '(encodedValueFloatParser) Unexpected size: %s', size);
507
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
508
+ const buffer = Buffer.from(uint8Array);
509
+ return buffer.readFloatLE(0);
510
+ });
511
+ })();
512
+ setParserName(encodedValueFloatParser, 'encodedValueFloatParser');
513
+ const encodedValueDoubleParser = parserCreatorCompose(() => createEncodedValueArgParser(0x11), sizeSubOne => {
514
+ const size = sizeSubOne + 1;
515
+ if (size === 1) {
516
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
517
+ const buffer = Buffer.from([...uint8Array, 0, 0, 0, 0, 0, 0, 0]);
518
+ return buffer.readDoubleLE(0);
519
+ });
520
+ }
521
+ if (size === 2) {
522
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
523
+ const buffer = Buffer.from([...uint8Array, 0, 0, 0, 0, 0, 0]);
524
+ return buffer.readDoubleLE(0);
525
+ });
526
+ }
527
+ if (size === 4) {
528
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
529
+ const buffer = Buffer.from([...uint8Array, 0, 0, 0, 0]);
530
+ return buffer.readDoubleLE(0);
531
+ });
532
+ }
533
+ invariant(size === 8, '(encodedValueDoubleParser) Unexpected size: %s', size);
534
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
535
+ const buffer = Buffer.from(uint8Array);
536
+ return buffer.readDoubleLE(0);
537
+ });
538
+ })();
539
+ setParserName(encodedValueDoubleParser, 'encodedValueDoubleParser');
540
+ const encodedValueMethodTypeParser = parserCreatorCompose(() => createEncodedValueArgParser(0x15), sizeSubOne => {
541
+ const size = sizeSubOne + 1;
542
+ if (size === 1) {
543
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
544
+ const buffer = Buffer.from(uint8Array);
545
+ return buffer.readUint8(0);
546
+ });
547
+ }
548
+ if (size === 2) {
549
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
550
+ const buffer = Buffer.from(uint8Array);
551
+ return buffer.readUInt16LE(0);
552
+ });
553
+ }
554
+ invariant(size === 4, '(encodedValueMethodTypeParser) Unexpected size: %s', size);
555
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
556
+ const buffer = Buffer.from(uint8Array);
557
+ return buffer.readUInt32LE(0);
558
+ });
559
+ })();
560
+ setParserName(encodedValueMethodTypeParser, 'encodedValueMethodTypeParser');
561
+ const encodedValueMethodHandleParser = parserCreatorCompose(() => createEncodedValueArgParser(0x16), sizeSubOne => {
562
+ const size = sizeSubOne + 1;
563
+ if (size === 1) {
564
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
565
+ const buffer = Buffer.from(uint8Array);
566
+ return buffer.readUInt8(0);
567
+ });
568
+ }
569
+ if (size === 2) {
570
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
571
+ const buffer = Buffer.from(uint8Array);
572
+ return buffer.readUInt16LE(0);
573
+ });
574
+ }
575
+ invariant(size === 4, '(encodedValueMethodHandleParser) Unexpected size: %s', size);
576
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
577
+ const buffer = Buffer.from(uint8Array);
578
+ return buffer.readUInt32LE(0);
579
+ });
580
+ })();
581
+ setParserName(encodedValueMethodHandleParser, 'encodedValueMethodHandleParser');
582
+ const encodedValueStringParser = parserCreatorCompose(() => createEncodedValueArgParser(0x17), sizeSubOne => {
583
+ const size = sizeSubOne + 1;
584
+ if (size === 1) {
585
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
586
+ const buffer = Buffer.from(uint8Array);
587
+ return buffer.readUInt8(0);
588
+ });
589
+ }
590
+ if (size === 2) {
591
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
592
+ const buffer = Buffer.from(uint8Array);
593
+ return buffer.readUInt16LE(0);
594
+ });
595
+ }
596
+ invariant(size === 4, '(encodedValueStringParser) Unexpected size: %s', size);
597
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
598
+ const buffer = Buffer.from(uint8Array);
599
+ return buffer.readUInt32LE(0);
600
+ });
601
+ })();
602
+ setParserName(encodedValueStringParser, 'encodedValueStringParser');
603
+ const encodedValueTypeParser = parserCreatorCompose(() => createEncodedValueArgParser(0x18), sizeSubOne => {
604
+ const size = sizeSubOne + 1;
605
+ if (size === 1) {
606
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
607
+ const buffer = Buffer.from(uint8Array);
608
+ return buffer.readUInt8(0);
609
+ });
610
+ }
611
+ if (size === 2) {
612
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
613
+ const buffer = Buffer.from(uint8Array);
614
+ return buffer.readUInt16LE(0);
615
+ });
616
+ }
617
+ invariant(size === 4, '(encodedValueTypeParser) Unexpected size: %s', size);
618
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
619
+ const buffer = Buffer.from(uint8Array);
620
+ return buffer.readUInt32LE(0);
621
+ });
622
+ })();
623
+ setParserName(encodedValueTypeParser, 'encodedValueTypeParser');
624
+ const encodedValueFieldParser = parserCreatorCompose(() => createEncodedValueArgParser(0x19), sizeSubOne => {
625
+ const size = sizeSubOne + 1;
626
+ if (size === 1) {
627
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
628
+ const buffer = Buffer.from(uint8Array);
629
+ return buffer.readUInt8(0);
630
+ });
631
+ }
632
+ if (size === 2) {
633
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
634
+ const buffer = Buffer.from(uint8Array);
635
+ return buffer.readUInt16LE(0);
636
+ });
637
+ }
638
+ invariant(size === 4, '(encodedValueFieldParser) Unexpected size: %s', size);
639
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
640
+ const buffer = Buffer.from(uint8Array);
641
+ return buffer.readUInt32LE(0);
642
+ });
643
+ })();
644
+ setParserName(encodedValueFieldParser, 'encodedValueFieldParser');
645
+ const encodedValueMethodParser = parserCreatorCompose(() => createEncodedValueArgParser(0x1a), sizeSubOne => {
646
+ const size = sizeSubOne + 1;
647
+ if (size === 1) {
648
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
649
+ const buffer = Buffer.from(uint8Array);
650
+ return buffer.readUInt8(0);
651
+ });
652
+ }
653
+ if (size === 2) {
654
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
655
+ const buffer = Buffer.from(uint8Array);
656
+ return buffer.readUInt16LE(0);
657
+ });
658
+ }
659
+ invariant(size === 4, '(encodedValueMethodParser) Unexpected size: %s', size);
660
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
661
+ const buffer = Buffer.from(uint8Array);
662
+ return buffer.readUInt32LE(0);
663
+ });
664
+ })();
665
+ setParserName(encodedValueMethodParser, 'encodedValueMethodParser');
666
+ const encodedValueEnumParser = parserCreatorCompose(() => createEncodedValueArgParser(0x1b), sizeSubOne => {
667
+ const size = sizeSubOne + 1;
668
+ if (size === 1) {
669
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
670
+ const buffer = Buffer.from(uint8Array);
671
+ return buffer.readUInt8(0);
672
+ });
673
+ }
674
+ if (size === 2) {
675
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
676
+ const buffer = Buffer.from(uint8Array);
677
+ return buffer.readUInt16LE(0);
678
+ });
679
+ }
680
+ invariant(size === 4, '(encodedValueEnumParser) Unexpected size: %s', size);
681
+ return promiseCompose(createFixedLengthSequenceParser(size), (uint8Array) => {
682
+ const buffer = Buffer.from(uint8Array);
683
+ return buffer.readUInt32LE(0);
684
+ });
685
+ })();
686
+ setParserName(encodedValueEnumParser, 'encodedValueEnumParser');
687
+ const encodedArrayParser = parserCreatorCompose(() => uleb128NumberParser, (size) => createQuantifierParser(encodedValueParser, size))();
688
+ setParserName(encodedArrayParser, 'encodedArrayParser');
689
+ const encodedValueArrayParser = promiseCompose(createTupleParser([
690
+ parserCreatorCompose(() => createEncodedValueArgParser(0x1c), valueArg => parserContext => {
691
+ parserContext.invariant(valueArg === 0, '(encodedValueArrayParser) valueArg: %s', valueArg);
692
+ })(),
693
+ encodedArrayParser,
694
+ ]), ([_, array]) => array);
695
+ setParserName(encodedValueArrayParser, 'encodedValueArrayParser');
696
+ const annotationElementParser = promiseCompose(createTupleParser([
697
+ uleb128NumberParser,
698
+ createParserAccessorParser(() => encodedValueParser),
699
+ ]), ([nameIndex, value,]) => ({
700
+ nameIndex: isoIndexIntoStringIds.wrap(nameIndex),
701
+ value,
702
+ }));
703
+ setParserName(annotationElementParser, 'annotationElementParser');
704
+ const encodedAnnotationParser = promiseCompose(parserCreatorCompose(() => createTupleParser([
705
+ uleb128NumberParser,
706
+ uleb128NumberParser,
707
+ ]), ([typeIndex, size,]) => createTupleParser([
708
+ () => typeIndex,
709
+ createQuantifierParser(annotationElementParser, size),
710
+ ]))(), ([typeIndex, elements,]) => ({
711
+ typeIndex: isoIndexIntoTypeIds.wrap(typeIndex),
712
+ elements,
713
+ }));
714
+ setParserName(encodedAnnotationParser, 'encodedAnnotationParser');
715
+ const encodedValueAnnotationParser = promiseCompose(createTupleParser([
716
+ parserCreatorCompose(() => createEncodedValueArgParser(0x1d), valueArg => parserContext => {
717
+ parserContext.invariant(valueArg === 0, '(encodedValueAnnotationParser) valueArg: %s', valueArg);
718
+ })(),
719
+ encodedAnnotationParser,
720
+ ]), ([_, annotation]) => annotation);
721
+ setParserName(encodedValueAnnotationParser, 'encodedValueAnnotationParser');
722
+ const encodedValueNullParser = parserCreatorCompose(() => createEncodedValueArgParser(0x1e), valueArg => parserContext => {
723
+ parserContext.invariant(valueArg === 0, '(encodedValueNullParser) valueArg: %s', valueArg);
724
+ return null;
725
+ })();
726
+ setParserName(encodedValueNullParser, 'encodedValueNullParser');
727
+ const encodedValueBooleanParser = promiseCompose(createEncodedValueArgParser(0x1f), (value) => Boolean(value));
728
+ setParserName(encodedValueBooleanParser, 'encodedValueBooleanParser');
729
+ const encodedValueParser = createDisjunctionParser([
730
+ encodedValueByteParser,
731
+ encodedValueShortParser,
732
+ encodedValueCharParser,
733
+ encodedValueIntParser,
734
+ encodedValueLongParser,
735
+ encodedValueFloatParser,
736
+ encodedValueDoubleParser,
737
+ encodedValueMethodTypeParser,
738
+ encodedValueMethodHandleParser,
739
+ encodedValueStringParser,
740
+ encodedValueTypeParser,
741
+ encodedValueFieldParser,
742
+ encodedValueMethodParser,
743
+ encodedValueEnumParser,
744
+ encodedValueArrayParser,
745
+ encodedValueAnnotationParser,
746
+ encodedValueNullParser,
747
+ encodedValueBooleanParser,
748
+ ]);
749
+ setParserName(encodedValueParser, 'encodedValueParser');
750
+ const tryItemParser = promiseCompose(createTupleParser([
751
+ uintParser,
752
+ ushortParser,
753
+ ushortParser,
754
+ ]), ([startAddress, instructionCount, handlerOffset,]) => ({
755
+ startAddress,
756
+ instructionCount,
757
+ handlerOffset: isoOffsetFromEncodedCatchHandlerListToEncodedCatchHandler.wrap(handlerOffset),
758
+ }));
759
+ setParserName(tryItemParser, 'tryItemParser');
760
+ const encodedTypeAddressPairParser = promiseCompose(createTupleParser([
761
+ uleb128NumberParser,
762
+ uleb128NumberParser,
763
+ ]), ([typeIndex, address,]) => ({
764
+ typeIndex: isoIndexIntoTypeIds.wrap(typeIndex),
765
+ address,
766
+ }));
767
+ const encodedCatchHandlerParser = parserCreatorCompose(() => sleb128NumberParser, size => promiseCompose(createTupleParser([
768
+ createQuantifierParser(encodedTypeAddressPairParser, Math.abs(size)),
769
+ size <= 0 ? uleb128NumberParser : () => undefined,
770
+ ]), ([handlers, catchAllAddress,]) => ({
771
+ size,
772
+ handlers,
773
+ catchAllAddress,
774
+ })))();
775
+ setParserName(encodedCatchHandlerParser, 'encodedCatchHandlerParser');
776
+ const encodedCatchHandlerListParser = async (parserContext) => {
777
+ const listOffset = parserContext.position;
778
+ const handlers = new Map();
779
+ const size = await uleb128NumberParser(parserContext);
780
+ for (let i = 0; i < size; i += 1) {
781
+ const handlerRelativeOffset = isoOffsetFromEncodedCatchHandlerListToEncodedCatchHandler.wrap(parserContext.position - listOffset);
782
+ const handler = await encodedCatchHandlerParser(parserContext);
783
+ handlers.set(handlerRelativeOffset, handler);
784
+ }
785
+ return handlers;
786
+ };
787
+ setParserName(encodedCatchHandlerListParser, 'encodedCatchHandlerListParser');
788
+ const createDalvikExecutableCodeItemParser = ({ createInstructionsParser, }) => {
789
+ const dalvikExecutableCodeItemParser = parserCreatorCompose(() => createTupleParser([
790
+ byteAlign4Parser,
791
+ ushortParser,
792
+ ushortParser,
793
+ ushortParser,
794
+ ushortParser,
795
+ uintParser,
796
+ uintParser,
797
+ ]), ([_, registersSize, insSize, outsSize, triesSize, debugInfoOffset, instructionsSize,]) => {
798
+ return promiseCompose(createTupleParser([
799
+ createInstructionsParser(instructionsSize * 2),
800
+ ((triesSize !== 0
801
+ && instructionsSize % 2 === 1)
802
+ ? byteAlign4Parser
803
+ : () => undefined),
804
+ (triesSize !== 0
805
+ ? createQuantifierParser(tryItemParser, triesSize)
806
+ : () => []),
807
+ (triesSize !== 0
808
+ ? encodedCatchHandlerListParser
809
+ : () => new Map()),
810
+ ]), ([instructions, _padding, tryItems, handlers,]) => {
811
+ return {
812
+ registersSize,
813
+ insSize,
814
+ outsSize,
815
+ triesSize,
816
+ debugInfoOffset: isoOffsetToDebugInfoItem.wrap(debugInfoOffset),
817
+ instructions,
818
+ tryItems,
819
+ handlers,
820
+ };
821
+ });
822
+ })();
823
+ setParserName(dalvikExecutableCodeItemParser, 'dalvikExecutableCodeItemParser');
824
+ return dalvikExecutableCodeItemParser;
825
+ };
826
+ const createSkipToThenCodeItemsParser = ({ sizeOffset, createInstructionsParser, }) => createSkipToThenItemByOffsetParser({
827
+ sizeOffset,
828
+ itemParser: createDalvikExecutableCodeItemParser({
829
+ createInstructionsParser,
830
+ }),
831
+ byteAlign4: true,
832
+ isoOffset: isoOffsetToCodeItem,
833
+ parserName: 'skipToThenCodeItemsParser',
834
+ });
835
+ const dalvikExecutableDebugByteCodeValueParser = parserCreatorCompose(() => ubyteParser, (value) => {
836
+ switch (value) {
837
+ case 0x01: return promiseCompose(uleb128NumberParser, (addressDiff) => ({ type: 'advancePc', addressDiff }));
838
+ case 0x02: return promiseCompose(sleb128NumberParser, (lineDiff) => ({ type: 'advanceLine', lineDiff }));
839
+ case 0x03: return promiseCompose(createTupleParser([
840
+ uleb128NumberParser,
841
+ uleb128NumberParser,
842
+ uleb128NumberParser,
843
+ ]), ([registerNum, nameIndex, typeIndex]) => ({
844
+ type: 'startLocal',
845
+ registerNum,
846
+ nameIndex: isoIndexIntoStringIds.wrap(nameIndex),
847
+ typeIndex: isoIndexIntoTypeIds.wrap(typeIndex),
848
+ }));
849
+ case 0x04: return promiseCompose(createTupleParser([
850
+ uleb128NumberParser,
851
+ uleb128NumberParser,
852
+ uleb128NumberParser,
853
+ uleb128NumberParser,
854
+ ]), ([registerNum, nameIndex, typeIndex, signatureIndex]) => ({
855
+ type: 'startLocalExtended',
856
+ registerNum,
857
+ nameIndex: isoIndexIntoStringIds.wrap(nameIndex),
858
+ typeIndex: isoIndexIntoTypeIds.wrap(typeIndex),
859
+ signatureIndex: isoIndexIntoStringIds.wrap(signatureIndex),
860
+ }));
861
+ case 0x05: return promiseCompose(uleb128NumberParser, (registerNum) => ({ type: 'endLocal', registerNum }));
862
+ case 0x06: return promiseCompose(uleb128NumberParser, (registerNum) => ({ type: 'restartLocal', registerNum }));
863
+ case 0x07: return () => ({ type: 'setPrologueEnd' });
864
+ case 0x08: return () => ({ type: 'setEpilogueBegin' });
865
+ case 0x09: return promiseCompose(uleb128NumberParser, (nameIndex) => ({ type: 'setFile', nameIndex: isoIndexIntoStringIds.wrap(nameIndex) }));
866
+ default: return parserContext => {
867
+ parserContext.invariant(value >= 0x0a, 'Unexpected special value: %s', value);
868
+ return { type: 'special', value };
869
+ };
870
+ }
871
+ })();
872
+ setParserName(dalvikExecutableDebugByteCodeValueParser, 'dalvikExecutableDebugByteCodeValueParser');
873
+ const debugByteCodeParser = createElementTerminatedArrayParserUnsafe(dalvikExecutableDebugByteCodeValueParser, 0);
874
+ setParserName(debugByteCodeParser, 'debugByteCodeParser');
875
+ const DEX_DEBUG_INFO_ITEM_PARAMETER_NAME_NO_INDEX = -1;
876
+ const debugInfoItemParser = parserCreatorCompose(() => createTupleParser([
877
+ uleb128NumberParser,
878
+ uleb128NumberParser,
879
+ ]), ([lineStart, parametersSize,]) => promiseCompose(createTupleParser([
880
+ createQuantifierParser(uleb128p1NumberParser, parametersSize),
881
+ debugByteCodeParser,
882
+ ]), ([parameterNames, bytecode]) => ({
883
+ lineStart,
884
+ parameterNames: parameterNames.map(parameterName => parameterName === DEX_DEBUG_INFO_ITEM_PARAMETER_NAME_NO_INDEX ? undefined : isoIndexIntoStringIds.wrap(parameterName)),
885
+ bytecode,
886
+ })))();
887
+ setParserName(debugInfoItemParser, 'debugInfoItemParser');
888
+ const createSkipToThenDebugInfoItemsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
889
+ sizeOffset,
890
+ itemParser: debugInfoItemParser,
891
+ byteAlign4: false,
892
+ isoOffset: isoOffsetToDebugInfoItem,
893
+ parserName: 'skipToThenDebugInfoItemsParser',
894
+ });
895
+ const dalvikExecutableAnnotationItemVisibilityParser = promiseCompose(ubyteParser, (visibility) => {
896
+ switch (visibility) {
897
+ case 0x00: return 'build';
898
+ case 0x01: return 'runtime';
899
+ case 0x02: return 'system';
900
+ default: invariant(false, 'Unexpected visibility: %s', visibility);
901
+ }
902
+ });
903
+ setParserName(dalvikExecutableAnnotationItemVisibilityParser, 'dalvikExecutableAnnotationItemVisibilityParser');
904
+ const dalvikExecutableAnnotationItemParser = promiseCompose(createTupleParser([
905
+ dalvikExecutableAnnotationItemVisibilityParser,
906
+ encodedAnnotationParser,
907
+ ]), ([visibility, encodedAnnotation]) => ({ visibility, encodedAnnotation }));
908
+ setParserName(dalvikExecutableAnnotationItemParser, 'dalvikExecutableAnnotationItemParser');
909
+ const createSkipToThenAnnotationItemsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
910
+ sizeOffset,
911
+ itemParser: dalvikExecutableAnnotationItemParser,
912
+ byteAlign4: false,
913
+ isoOffset: isoOffsetToAnnotationItem,
914
+ parserName: 'skipToThenAnnotationItemsParser',
915
+ });
916
+ const dalvikExecutableHeaderAndMapParser = parserCreatorCompose(() => dalvikExecutableHeaderItemParser, (headerItem) => promiseCompose(createLookaheadParser(createDalvikExecutableMapListParser(headerItem.mapOffset)), (mapList) => ({ headerItem, mapList })))();
917
+ const dalvikExecutableAnnotationOffsetItemParser = promiseCompose(uintParser, (annotationOffset) => ({
918
+ annotationOffset: isoOffsetToAnnotationItem.wrap(annotationOffset),
919
+ }));
920
+ const dalvikExecutableAnnotationSetItemParser = parserCreatorCompose(() => createTupleParser([
921
+ byteAlign4Parser,
922
+ uintParser,
923
+ ]), ([_, size]) => promiseCompose(createQuantifierParser(dalvikExecutableAnnotationOffsetItemParser, size), (entries) => ({ entries })))();
924
+ const createSkipToThenAnnotationSetItemsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
925
+ sizeOffset,
926
+ itemParser: dalvikExecutableAnnotationSetItemParser,
927
+ byteAlign4: true,
928
+ isoOffset: isoOffsetToAnnotationSetItem,
929
+ parserName: 'skipToThenAnnotationSetItemsParser',
930
+ });
931
+ const dalvikExecutableAnnotationSetRefItemParser = promiseCompose(uintParser, (annotationsOffset) => isoOffsetToAnnotationSetItem.wrap(annotationsOffset));
932
+ const dalvikExecutableAnnotationSetRefListParser = parserCreatorCompose(() => createTupleParser([
933
+ byteAlign4Parser,
934
+ uintParser,
935
+ ]), ([_, size]) => promiseCompose(createQuantifierParser(dalvikExecutableAnnotationSetRefItemParser, size), (list) => ({ list })))();
936
+ const createSkipToThenAnnotationSetRefListsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
937
+ sizeOffset,
938
+ itemParser: dalvikExecutableAnnotationSetRefListParser,
939
+ byteAlign4: true,
940
+ isoOffset: isoOffsetToAnnotationSetRefListItem,
941
+ parserName: 'skipToThenAnnotationSetRefListsParser',
942
+ });
943
+ const dalvikExecutableMapItemTypeParser = promiseCompose(ushortParser, (type) => {
944
+ switch (type) {
945
+ case 0x0000: return 'headerItem';
946
+ case 0x0001: return 'stringIdItem';
947
+ case 0x0002: return 'typeIdItem';
948
+ case 0x0003: return 'prototypeIdItem';
949
+ case 0x0004: return 'fieldIdItem';
950
+ case 0x0005: return 'methodIdItem';
951
+ case 0x0006: return 'classDefinitionItem';
952
+ case 0x0007: return 'callSiteIdItem';
953
+ case 0x0008: return 'methodHandleItem';
954
+ case 0x1000: return 'mapList';
955
+ case 0x1001: return 'typeList';
956
+ case 0x1002: return 'annotationSetRefList';
957
+ case 0x1003: return 'annotationSetItem';
958
+ case 0x2000: return 'classDataItem';
959
+ case 0x2001: return 'codeItem';
960
+ case 0x2002: return 'stringDataItem';
961
+ case 0x2003: return 'debugInfoItem';
962
+ case 0x2004: return 'annotationItem';
963
+ case 0x2005: return 'encodedArrayItem';
964
+ case 0x2006: return 'annotationsDirectoryItem';
965
+ case 0xF000: return 'hiddenApiClassDataItem';
966
+ default: invariant(false, 'Unexpected map item type: %s', type);
967
+ }
968
+ });
969
+ const dalvikExecutableMapItemParser = promiseCompose(createTupleParser([
970
+ dalvikExecutableMapItemTypeParser,
971
+ ushortParser,
972
+ uintParser,
973
+ uintParser,
974
+ ]), ([type, _unused, size, offset]) => ({ type, size, offset }));
975
+ const dalvikExecutableMapListParser = parserCreatorCompose(() => uintParser, size => {
976
+ return createQuantifierParser(dalvikExecutableMapItemParser, size);
977
+ })();
978
+ setParserName(dalvikExecutableMapListParser, 'dalvikExecutableMapListParser');
979
+ const createDalvikExecutableMapListParser = (mapOffset) => {
980
+ const dalvikExecutableMapParser = promiseCompose(createTupleParser([
981
+ createSkipToParser(mapOffset),
982
+ dalvikExecutableMapListParser,
983
+ ]), ([_, map]) => map);
984
+ setParserName(dalvikExecutableMapParser, 'dalvikExecutableMapParser');
985
+ return dalvikExecutableMapParser;
986
+ };
987
+ const createSkipToThenEncodedArrayItemsParser = (sizeOffset) => createSkipToThenItemByOffsetParser({
988
+ sizeOffset,
989
+ itemParser: encodedArrayParser,
990
+ byteAlign4: false,
991
+ isoOffset: isoOffsetToEncodedArrayItem,
992
+ parserName: 'skipToThenEncodedArrayItemsParser',
993
+ });
994
+ const createDalvikExecutableDataParser = ({ headerItem, mapList, createInstructionsParser, }) => {
995
+ const dalvikExecutableDataParser = async (parserContext) => {
996
+ let stringIdItems = isoDalvikExecutableStringIdItems.wrap([]);
997
+ let typeIdItems = isoDalvikExecutableTypeIdItems.wrap([]);
998
+ let prototypeIdItems = isoDalvikExecutablePrototypeIdItems.wrap([]);
999
+ let fieldIdItems = isoDalvikExecutableFieldIdItems.wrap([]);
1000
+ let methodIdItems = isoDalvikExecutableMethodIdItems.wrap([]);
1001
+ let classDefinitionItems = [];
1002
+ let callSiteIdItems = [];
1003
+ let methodHandleItems = [];
1004
+ let typeListByOffset = new Map();
1005
+ let annotationSetRefListItemByOffset = new Map();
1006
+ let annotationSetItemByOffset = new Map();
1007
+ let classDataItemByOffset = new Map();
1008
+ let codeItemByOffset = new Map();
1009
+ let stringDataItemStringByOffset = new Map();
1010
+ let debugInfoItemByOffset = new Map();
1011
+ let annotationItemByOffset = new Map();
1012
+ let encodedArrayItemByOffset = new Map();
1013
+ let annotationsDirectoryItemByOffset = new Map();
1014
+ let hiddenApiClassDataItems = [];
1015
+ for (const dexMapItem of mapList) {
1016
+ if (dexMapItem.type === 'headerItem') {
1017
+ continue;
1018
+ }
1019
+ if (dexMapItem.type === 'stringIdItem') {
1020
+ stringIdItems = await createSkipToThenStringIdItemsParser(dexMapItem)(parserContext);
1021
+ continue;
1022
+ }
1023
+ if (dexMapItem.type === 'typeIdItem') {
1024
+ typeIdItems = await createSkipToThenTypeIdItemsParser(dexMapItem)(parserContext);
1025
+ continue;
1026
+ }
1027
+ if (dexMapItem.type === 'prototypeIdItem') {
1028
+ prototypeIdItems = await createSkipToThenPrototypeIdItemsParser(dexMapItem)(parserContext);
1029
+ continue;
1030
+ }
1031
+ if (dexMapItem.type === 'fieldIdItem') {
1032
+ fieldIdItems = await createSkipToThenFieldIdItemsParser(dexMapItem)(parserContext);
1033
+ continue;
1034
+ }
1035
+ if (dexMapItem.type === 'methodIdItem') {
1036
+ methodIdItems = await createSkipToThenMethodIdItemsParser(dexMapItem)(parserContext);
1037
+ continue;
1038
+ }
1039
+ if (dexMapItem.type === 'classDefinitionItem') {
1040
+ classDefinitionItems = await createSkipToThenClassDefinitionItemsParser(dexMapItem)(parserContext);
1041
+ continue;
1042
+ }
1043
+ if (dexMapItem.type === 'callSiteIdItem') {
1044
+ // TODO
1045
+ }
1046
+ if (dexMapItem.type === 'methodHandleItem') {
1047
+ // TODO
1048
+ }
1049
+ if (dexMapItem.type === 'mapList') {
1050
+ await createDalvikExecutableMapListParser(dexMapItem.offset)(parserContext);
1051
+ continue;
1052
+ }
1053
+ if (dexMapItem.type === 'typeList') {
1054
+ typeListByOffset = await createSkipToThenTypeListByOffsetParser(dexMapItem)(parserContext);
1055
+ continue;
1056
+ }
1057
+ if (dexMapItem.type === 'annotationSetRefList') {
1058
+ annotationSetRefListItemByOffset = await createSkipToThenAnnotationSetRefListsParser(dexMapItem)(parserContext);
1059
+ continue;
1060
+ }
1061
+ if (dexMapItem.type === 'annotationSetItem') {
1062
+ annotationSetItemByOffset = await createSkipToThenAnnotationSetItemsParser(dexMapItem)(parserContext);
1063
+ continue;
1064
+ }
1065
+ if (dexMapItem.type === 'classDataItem') {
1066
+ classDataItemByOffset = await createSkipToThenClassDataItemsParser(dexMapItem)(parserContext);
1067
+ continue;
1068
+ }
1069
+ if (dexMapItem.type === 'codeItem') {
1070
+ codeItemByOffset = await createSkipToThenCodeItemsParser({
1071
+ sizeOffset: dexMapItem,
1072
+ createInstructionsParser,
1073
+ })(parserContext);
1074
+ continue;
1075
+ }
1076
+ if (dexMapItem.type === 'stringDataItem') {
1077
+ stringDataItemStringByOffset = await createSkipToThenStringsParser(dexMapItem)(parserContext);
1078
+ continue;
1079
+ }
1080
+ if (dexMapItem.type === 'debugInfoItem') {
1081
+ debugInfoItemByOffset = await createSkipToThenDebugInfoItemsParser(dexMapItem)(parserContext);
1082
+ continue;
1083
+ }
1084
+ if (dexMapItem.type === 'annotationItem') {
1085
+ annotationItemByOffset = await createSkipToThenAnnotationItemsParser(dexMapItem)(parserContext);
1086
+ continue;
1087
+ }
1088
+ if (dexMapItem.type === 'encodedArrayItem') {
1089
+ encodedArrayItemByOffset = await createSkipToThenEncodedArrayItemsParser(dexMapItem)(parserContext);
1090
+ continue;
1091
+ }
1092
+ if (dexMapItem.type === 'annotationsDirectoryItem') {
1093
+ annotationsDirectoryItemByOffset = await createSkipToThenAnnotationsDirectoryItemsParser(dexMapItem)(parserContext);
1094
+ continue;
1095
+ }
1096
+ if (dexMapItem.type === 'hiddenApiClassDataItem') {
1097
+ // TODO
1098
+ }
1099
+ invariant(false, 'Unexpected map item type: %s', dexMapItem.type);
1100
+ }
1101
+ return {
1102
+ headerItem,
1103
+ stringIdItems,
1104
+ typeIdItems,
1105
+ prototypeIdItems,
1106
+ fieldIdItems,
1107
+ methodIdItems,
1108
+ classDefinitionItems,
1109
+ callSiteIdItems,
1110
+ methodHandleItems,
1111
+ mapList,
1112
+ typeListByOffset,
1113
+ annotationSetRefListItemByOffset,
1114
+ annotationSetItemByOffset,
1115
+ classDataItemByOffset,
1116
+ codeItemByOffset,
1117
+ stringDataItemStringByOffset,
1118
+ debugInfoItemByOffset,
1119
+ annotationItemByOffset,
1120
+ encodedArrayItemByOffset,
1121
+ annotationsDirectoryItemByOffset,
1122
+ hiddenApiClassDataItems,
1123
+ };
1124
+ };
1125
+ setParserName(dalvikExecutableDataParser, 'dalvikExecutableDataParser');
1126
+ return dalvikExecutableDataParser;
1127
+ };
1128
+ const createDalvikExecutableParser = ({ createInstructionsParser, }) => parserCreatorCompose(() => dalvikExecutableHeaderAndMapParser, ({ headerItem, mapList, }) => promiseCompose(createTupleParser([
1129
+ createDalvikExecutableDataParser({
1130
+ headerItem,
1131
+ mapList,
1132
+ createInstructionsParser,
1133
+ }),
1134
+ createRawDataParser(headerItem.link),
1135
+ ]), async ([{ headerItem: _headerItem, stringIdItems, typeIdItems, prototypeIdItems, fieldIdItems, methodIdItems, classDefinitionItems,
1136
+ // callSiteIdItems,
1137
+ // methodHandleItems,
1138
+ mapList: _mapList, typeListByOffset, annotationSetRefListItemByOffset, annotationSetItemByOffset, classDataItemByOffset, codeItemByOffset, stringDataItemStringByOffset, debugInfoItemByOffset, annotationItemByOffset, encodedArrayItemByOffset, annotationsDirectoryItemByOffset,
1139
+ // hiddenApiClassDataItems,
1140
+ }, link,]) => {
1141
+ const strings = stringIdItems.map((stringId) => {
1142
+ const stringOffset = stringId;
1143
+ const string = stringDataItemStringByOffset.get(stringOffset);
1144
+ invariant(string !== undefined, 'String must be there. String offset: %s', stringOffset);
1145
+ return string;
1146
+ });
1147
+ const types = typeIdItems.map((typeId) => {
1148
+ const type = strings.at(typeId);
1149
+ invariant(type, 'Type string must be there. Type id: %s', typeId);
1150
+ return type;
1151
+ });
1152
+ const resolvedTypeListByOffset = new Map([
1153
+ [isoOffsetToTypeList.wrap(0), []],
1154
+ ]);
1155
+ for (const [offset, typeIndexes] of typeListByOffset) {
1156
+ const typeNames = isoDalvikExecutableTypeList.unwrap(typeIndexes).map((typeIndex) => {
1157
+ const type = types.at(typeIndex);
1158
+ invariant(type, 'Type must be there. Type id: %s', typeIndex);
1159
+ return type;
1160
+ });
1161
+ resolvedTypeListByOffset.set(offset, typeNames);
1162
+ }
1163
+ const prototypes = prototypeIdItems.map((prototypeId) => {
1164
+ const shorty = strings.at(prototypeId.shortyIndex);
1165
+ invariant(shorty, 'Shorty must be there. Shorty id: %s', prototypeId.shortyIndex);
1166
+ const returnType = types.at(prototypeId.returnTypeIndex);
1167
+ invariant(returnType, 'Return type must be there. Return type id: %s', prototypeId.returnTypeIndex);
1168
+ const parameters = resolvedTypeListByOffset.get(prototypeId.parametersOffset);
1169
+ invariant(parameters !== undefined, 'Parameters must be there. Parameters offset: %s', prototypeId.parametersOffset);
1170
+ return { shorty, returnType, parameters };
1171
+ });
1172
+ const fields = fieldIdItems.map((fieldId) => {
1173
+ const class_ = types.at(fieldId.classIndex);
1174
+ invariant(class_, 'Class must be there. Class id: %s', fieldId.classIndex);
1175
+ const type = types.at(fieldId.typeIndex);
1176
+ invariant(type, 'Type must be there. Type id: %s', fieldId.typeIndex);
1177
+ const name = strings.at(fieldId.nameIndex);
1178
+ invariant(name, 'Name string must be there. String offset: %s', fieldId.nameIndex);
1179
+ return { class: class_, type, name };
1180
+ });
1181
+ const methods = methodIdItems.map((methodId) => {
1182
+ const class_ = types.at(methodId.classIndex);
1183
+ invariant(class_, 'Class must be there. Class id: %s', methodId.classIndex);
1184
+ const prototype = prototypes.at(methodId.prototypeIndex);
1185
+ invariant(prototype, 'Prototype must be there. Prototype id: %s', methodId.prototypeIndex);
1186
+ const name = strings.at(methodId.nameIndex);
1187
+ invariant(name, 'Name string must be there. String offset: %s', methodId.nameIndex);
1188
+ return { class: class_, prototype, name };
1189
+ });
1190
+ const debugInfoByOffset = new Map([
1191
+ [isoOffsetToDebugInfoItem.wrap(0), undefined],
1192
+ ]);
1193
+ for (const [offset, debugInfoItem] of debugInfoItemByOffset) {
1194
+ debugInfoByOffset.set(offset, {
1195
+ lineStart: debugInfoItem.lineStart,
1196
+ parameterNames: debugInfoItem.parameterNames.map((index) => {
1197
+ if (index === undefined) {
1198
+ return undefined;
1199
+ }
1200
+ const string = strings.at(index);
1201
+ invariant(string !== undefined, 'String must be there. String id: %s', index);
1202
+ return string;
1203
+ }),
1204
+ bytecode: debugInfoItem.bytecode.map((value) => {
1205
+ switch (value.type) {
1206
+ case 'startLocal': return {
1207
+ type: 'startLocal',
1208
+ registerNum: value.registerNum,
1209
+ name: value.nameIndex === undefined ? undefined : strings.at(value.nameIndex),
1210
+ type_: value.typeIndex === undefined ? undefined : types.at(value.typeIndex),
1211
+ };
1212
+ case 'startLocalExtended': return {
1213
+ type: 'startLocalExtended',
1214
+ registerNum: value.registerNum,
1215
+ name: value.nameIndex === undefined ? undefined : strings.at(value.nameIndex),
1216
+ type_: value.typeIndex === undefined ? undefined : types.at(value.typeIndex),
1217
+ signature: value.signatureIndex === undefined ? undefined : strings.at(value.signatureIndex),
1218
+ };
1219
+ case 'setFile': return { type: 'setFile', name: strings.at(value.nameIndex) };
1220
+ default: return value;
1221
+ }
1222
+ }),
1223
+ });
1224
+ }
1225
+ const codeByOffset = new Map([
1226
+ [isoOffsetToCodeItem.wrap(0), undefined],
1227
+ ]);
1228
+ for (const [offset, codeItem] of codeItemByOffset) {
1229
+ const debugInfo = debugInfoByOffset.get(codeItem.debugInfoOffset);
1230
+ codeByOffset.set(offset, {
1231
+ registersSize: codeItem.registersSize,
1232
+ insSize: codeItem.insSize,
1233
+ outsSize: codeItem.outsSize,
1234
+ debugInfo: debugInfo,
1235
+ instructions: codeItem.instructions,
1236
+ tries: codeItem.tryItems.map((tryItem) => {
1237
+ const handler_ = codeItem.handlers.get(tryItem.handlerOffset);
1238
+ invariant(handler_, 'Handler must be there. Handler offset: %s', tryItem.handlerOffset);
1239
+ const handler = {
1240
+ ...handler_,
1241
+ handlers: handler_.handlers.map((encodedHandler) => {
1242
+ const type = types.at(encodedHandler.typeIndex);
1243
+ invariant(type, 'Type must be there. Type id: %s', encodedHandler.typeIndex);
1244
+ return {
1245
+ type,
1246
+ address: encodedHandler.address,
1247
+ };
1248
+ }),
1249
+ };
1250
+ return {
1251
+ startAddress: tryItem.startAddress,
1252
+ instructionCount: tryItem.instructionCount,
1253
+ handler,
1254
+ };
1255
+ }),
1256
+ });
1257
+ }
1258
+ const classDataByOffset = new Map([
1259
+ [isoOffsetToClassDataItem.wrap(0), undefined],
1260
+ ]);
1261
+ const resolvers = {
1262
+ resolveIndexIntoStringIds(indexIntoStringIds) {
1263
+ const string = strings.at(indexIntoStringIds);
1264
+ invariant(string, 'String must be there. String id: %s', indexIntoStringIds);
1265
+ return string;
1266
+ },
1267
+ resolveIndexIntoTypeIds(indexIntoTypeIds) {
1268
+ const type = types.at(indexIntoTypeIds);
1269
+ invariant(type, 'Type must be there. Type id: %s', indexIntoTypeIds);
1270
+ return type;
1271
+ },
1272
+ resolveIndexIntoMethodIds(indexIntoMethodIds) {
1273
+ const method = methods.at(indexIntoMethodIds);
1274
+ invariant(method, 'Method must be there. Method id: %s', indexIntoMethodIds);
1275
+ return method;
1276
+ },
1277
+ resolveIndexIntoFieldIds(indexIntoFieldIds) {
1278
+ const field = fields.at(indexIntoFieldIds);
1279
+ invariant(field, 'Field must be there. Field id: %s', indexIntoFieldIds);
1280
+ return field;
1281
+ },
1282
+ };
1283
+ function resolveCode(code) {
1284
+ if (!code) {
1285
+ return code;
1286
+ }
1287
+ const { instructions, ...rest } = code;
1288
+ if (!Array.isArray(instructions)) {
1289
+ return code;
1290
+ }
1291
+ return {
1292
+ ...rest,
1293
+ instructions: instructions.map((instruction) => {
1294
+ return resolveDalvikBytecodeOperation(instruction, resolvers);
1295
+ }),
1296
+ };
1297
+ }
1298
+ for (const [offset, classDataItem] of classDataItemByOffset) {
1299
+ classDataByOffset.set(offset, {
1300
+ staticFields: classDataItem.staticFields.map((encodedField) => {
1301
+ const field = fields.at(encodedField.fieldIndex);
1302
+ invariant(field, 'Field must be there. Field id: %s', encodedField.fieldIndex);
1303
+ return {
1304
+ field,
1305
+ accessFlags: encodedField.accessFlags,
1306
+ };
1307
+ }),
1308
+ instanceFields: classDataItem.instanceFields.map((encodedField) => {
1309
+ const field = fields.at(encodedField.fieldIndex);
1310
+ invariant(field, 'Field must be there. Field id: %s', encodedField.fieldIndex);
1311
+ return {
1312
+ field,
1313
+ accessFlags: encodedField.accessFlags,
1314
+ };
1315
+ }),
1316
+ directMethods: classDataItem.directMethods.map((method) => {
1317
+ const method_ = methods.at(method.methodIndex);
1318
+ invariant(method_, 'Method must be there. Method id: %s', method.methodIndex);
1319
+ const code = codeByOffset.get(method.codeOffset);
1320
+ invariant(!method.codeOffset || code, 'Code must be there. Code offset: %s', method.codeOffset);
1321
+ return {
1322
+ method: method_,
1323
+ accessFlags: method.accessFlags,
1324
+ code: resolveCode(code),
1325
+ };
1326
+ }),
1327
+ virtualMethods: classDataItem.virtualMethods.map((method) => {
1328
+ const method_ = methods.at(method.methodIndex);
1329
+ invariant(method_, 'Method must be there. Method id: %s', method.methodIndex);
1330
+ const code = codeByOffset.get(method.codeOffset);
1331
+ invariant(!method.codeOffset || code, 'Code must be there. Code offset: %s', method.codeOffset);
1332
+ return {
1333
+ method: method_,
1334
+ accessFlags: method.accessFlags,
1335
+ code: resolveCode(code),
1336
+ };
1337
+ }),
1338
+ });
1339
+ }
1340
+ function resolveAnnotationOffsetItem({ annotationOffset }) {
1341
+ const annotationItem = annotationItemByOffset.get(annotationOffset);
1342
+ invariant(annotationItem, 'Annotation must be there. Annotation offset: %s', annotationOffset);
1343
+ const type = types.at(annotationItem.encodedAnnotation.typeIndex);
1344
+ invariant(type, 'Type must be there. Type id: %s', annotationItem.encodedAnnotation.typeIndex);
1345
+ const elements = annotationItem.encodedAnnotation.elements.map((element) => {
1346
+ const name = strings.at(element.nameIndex);
1347
+ invariant(name, 'Name string must be there. String offset: %s', element.nameIndex);
1348
+ return {
1349
+ name,
1350
+ value: element.value,
1351
+ };
1352
+ });
1353
+ return {
1354
+ visibility: annotationItem.visibility,
1355
+ type,
1356
+ elements,
1357
+ };
1358
+ }
1359
+ function resolveAnnotationSetItem(annotationSetItem) {
1360
+ return annotationSetItem?.entries.map(resolveAnnotationOffsetItem);
1361
+ }
1362
+ const classDefinitions = classDefinitionItems.map((classDefinitionItem) => {
1363
+ const class_ = types.at(classDefinitionItem.classIndex);
1364
+ invariant(class_, 'Class must be there. Class id: %s', classDefinitionItem.classIndex);
1365
+ const superclass = types.at(classDefinitionItem.superclassIndex);
1366
+ invariant(superclass, 'Superclass must be there. Superclass id: %s', classDefinitionItem.superclassIndex);
1367
+ const interfaces = resolvedTypeListByOffset.get(classDefinitionItem.interfacesOffset);
1368
+ invariant(interfaces !== undefined, 'Interfaces must be there. Interfaces offset: %s', classDefinitionItem.interfacesOffset);
1369
+ const sourceFile = classDefinitionItem.sourceFileIndex === undefined ? undefined : strings.at(classDefinitionItem.sourceFileIndex);
1370
+ const annotationsDirectoryItem = annotationsDirectoryItemByOffset.get(classDefinitionItem.annotationsOffset);
1371
+ invariant(isoOffsetToAnnotationsDirectoryItem.unwrap(classDefinitionItem.annotationsOffset) === 0 || annotationsDirectoryItem, 'Annotations directory item must be there. Annotations offset: %s', classDefinitionItem.annotationsOffset);
1372
+ const annotations = (() => {
1373
+ if (!annotationsDirectoryItem) {
1374
+ return undefined;
1375
+ }
1376
+ const classAnnotationSetItem = annotationSetItemByOffset.get(annotationsDirectoryItem.classAnnotationsOffset);
1377
+ invariant(isoOffsetToAnnotationSetItem.unwrap(annotationsDirectoryItem.classAnnotationsOffset) === 0 || classAnnotationSetItem, 'Class annotations must be there. Class annotations offset: %s', annotationsDirectoryItem.classAnnotationsOffset);
1378
+ const classAnnotations = (classAnnotationSetItem
1379
+ ? resolveAnnotationSetItem(classAnnotationSetItem)
1380
+ : undefined);
1381
+ const fieldAnnotations = annotationsDirectoryItem.fieldAnnotations.map((fieldAnnotation) => {
1382
+ const field = fields.at(fieldAnnotation.fieldIndex);
1383
+ invariant(field, 'Field must be there. Field id: %s', fieldAnnotation.fieldIndex);
1384
+ const annotations = annotationSetItemByOffset.get(fieldAnnotation.annotationsOffset);
1385
+ invariant(isoOffsetToAnnotationSetItem.unwrap(fieldAnnotation.annotationsOffset) === 0 || annotations, 'Annotations must be there. Annotations offset: %s', fieldAnnotation.annotationsOffset);
1386
+ return { field, annotations: annotations?.entries.map(resolveAnnotationOffsetItem) };
1387
+ });
1388
+ const methodAnnotations = annotationsDirectoryItem.methodAnnotations.map((methodAnnotation) => {
1389
+ const method = methods.at(methodAnnotation.methodIndex);
1390
+ invariant(method, 'Method must be there. Method id: %s', methodAnnotation.methodIndex);
1391
+ const annotationSetItem = annotationSetItemByOffset.get(methodAnnotation.annotationsOffset);
1392
+ invariant(isoOffsetToAnnotationSetItem.unwrap(methodAnnotation.annotationsOffset) === 0 || annotationSetItem, 'Annotations must be there. Annotations offset: %s', methodAnnotation.annotationsOffset);
1393
+ return { method, annotations: resolveAnnotationSetItem(annotationSetItem) };
1394
+ });
1395
+ const parameterAnnotations = annotationsDirectoryItem.parameterAnnotations.map((parameterAnnotation) => {
1396
+ const method = methods.at(parameterAnnotation.methodIndex);
1397
+ invariant(method, 'Method must be there. Method id: %s', parameterAnnotation.methodIndex);
1398
+ const annotationSetRefList = annotationSetRefListItemByOffset.get(parameterAnnotation.annotationsOffset);
1399
+ invariant(isoOffsetToAnnotationSetRefListItem.unwrap(parameterAnnotation.annotationsOffset) === 0 || annotationSetRefList, 'Annotations must be there. Annotations offset: %s', parameterAnnotation.annotationsOffset);
1400
+ const annotations = annotationSetRefList?.list.map((annotationSetRefItem) => {
1401
+ const annotationSetItem = annotationSetItemByOffset.get(annotationSetRefItem);
1402
+ invariant(isoOffsetToAnnotationSetItem.unwrap(annotationSetRefItem) === 0 || annotationSetItem, 'Annotations must be there. Annotations offset: %s', annotationSetRefItem);
1403
+ return resolveAnnotationSetItem(annotationSetItem);
1404
+ });
1405
+ return { method, annotations };
1406
+ });
1407
+ return {
1408
+ classAnnotations,
1409
+ fieldAnnotations,
1410
+ methodAnnotations,
1411
+ parameterAnnotations,
1412
+ };
1413
+ })();
1414
+ const classData = classDataByOffset.get(classDefinitionItem.classDataOffset);
1415
+ const staticValues = isoOffsetToEncodedArrayItem.unwrap(classDefinitionItem.staticValuesOffset) === 0 ? [] : encodedArrayItemByOffset.get(classDefinitionItem.staticValuesOffset);
1416
+ invariant(staticValues, 'Static values must be there. Static values offset: %s', classDefinitionItem.staticValuesOffset);
1417
+ return {
1418
+ class: class_,
1419
+ accessFlags: classDefinitionItem.accessFlags,
1420
+ superclass,
1421
+ interfaces,
1422
+ sourceFile,
1423
+ annotations,
1424
+ classData,
1425
+ staticValues,
1426
+ };
1427
+ });
1428
+ return {
1429
+ classDefinitions,
1430
+ link,
1431
+ };
1432
+ }))();
1433
+ export const dalvikExecutableParser = createDalvikExecutableParser({
1434
+ createInstructionsParser: createDalvikBytecodeParser,
1435
+ });
1436
+ setParserName(dalvikExecutableParser, 'dalvikExecutableParser');
1437
+ export const dalvikExecutableWithRawInstructionsParser = createDalvikExecutableParser({
1438
+ createInstructionsParser: createFixedLengthSequenceParser,
1439
+ });