@futpib/parser 1.0.1 → 1.0.3

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 (425) hide show
  1. package/.github/copilot-instructions.md +149 -0
  2. package/.github/workflows/copilot-setup-steps.yml +18 -0
  3. package/.github/workflows/main.yml +29 -8
  4. package/.yarn/releases/yarn-4.9.4.cjs +942 -0
  5. package/.yarnrc.yml +1 -1
  6. package/build/allSettledStream.js +32 -14
  7. package/build/allSettledStream.test.js +32 -0
  8. package/build/androidPackage.d.ts +39 -0
  9. package/build/androidPackageParser.d.ts +17 -0
  10. package/build/androidPackageParser.js +185 -0
  11. package/build/androidPackageParser.test.js +22 -0
  12. package/build/androidPackageUnparser.d.ts +4 -0
  13. package/build/androidPackageUnparser.js +94 -0
  14. package/build/androidPackageUnparser.test.js +26 -0
  15. package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
  16. package/build/arbitrarilySlicedAsyncInterable.js +3 -3
  17. package/build/arbitrarilySlicedAsyncInterator.js +2 -1
  18. package/build/arbitraryDalvikBytecode.d.ts +4 -0
  19. package/build/arbitraryDalvikBytecode.js +640 -0
  20. package/build/arbitraryDalvikExecutable.d.ts +3 -0
  21. package/build/arbitraryDalvikExecutable.js +282 -0
  22. package/build/arbitraryDosDateTime.js +1 -0
  23. package/build/arbitraryZipStream.js +1 -1
  24. package/build/arrayParser.js +2 -2
  25. package/build/arrayParser.test.js +3 -3
  26. package/build/arrayUnparser.d.ts +1 -1
  27. package/build/backsmali.d.ts +3 -0
  28. package/build/backsmali.js +50 -0
  29. package/build/bsonParser.js +6 -2
  30. package/build/customInvariant.d.ts +2 -1
  31. package/build/customInvariant.js +4 -6
  32. package/build/dalvikBytecodeParser/formatParsers.d.ts +171 -0
  33. package/build/dalvikBytecodeParser/formatParsers.js +304 -0
  34. package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
  35. package/build/dalvikBytecodeParser/formatSizes.js +34 -0
  36. package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
  37. package/build/dalvikBytecodeParser/operationFormats.js +225 -0
  38. package/build/dalvikBytecodeParser.d.ts +1207 -0
  39. package/build/dalvikBytecodeParser.js +1289 -0
  40. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
  41. package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
  42. package/build/dalvikBytecodeUnparser.d.ts +3 -0
  43. package/build/dalvikBytecodeUnparser.js +642 -0
  44. package/build/dalvikBytecodeUnparser.test.js +25 -0
  45. package/build/dalvikExecutable.d.ts +215 -0
  46. package/build/dalvikExecutable.js +56 -0
  47. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  48. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  49. package/build/dalvikExecutableParser/typeParsers.d.ts +11 -0
  50. package/build/dalvikExecutableParser/typeParsers.js +39 -0
  51. package/build/dalvikExecutableParser/typedNumbers.d.ts +106 -0
  52. package/build/dalvikExecutableParser/typedNumbers.js +18 -0
  53. package/build/dalvikExecutableParser.d.ts +5 -0
  54. package/build/dalvikExecutableParser.js +1757 -0
  55. package/build/dalvikExecutableParser.test.js +72 -0
  56. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +275 -0
  57. package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
  58. package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
  59. package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
  60. package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
  61. package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
  62. package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
  63. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
  64. package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
  65. package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
  66. package/build/dalvikExecutableUnparser/utils.js +108 -0
  67. package/build/dalvikExecutableUnparser.d.ts +4 -0
  68. package/build/dalvikExecutableUnparser.js +406 -0
  69. package/build/dalvikExecutableUnparser.test.js +31 -0
  70. package/build/debugLogInputParser.d.ts +4 -0
  71. package/build/debugLogInputParser.js +16 -0
  72. package/build/debugLogParser.js +14 -3
  73. package/build/disjunctionParser.d.ts +2 -1
  74. package/build/disjunctionParser.js +6 -4
  75. package/build/elementTerminatedArrayParser.d.ts +3 -0
  76. package/build/elementTerminatedArrayParser.js +18 -0
  77. package/build/elementTerminatedArrayParser.test.js +52 -0
  78. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  79. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  80. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  81. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  82. package/build/elementTerminatedSequenceParser.js +27 -0
  83. package/build/elementTerminatedSequenceParser.test.js +34 -0
  84. package/build/endOfInputParser.d.ts +1 -1
  85. package/build/exactElementParser.js +10 -5
  86. package/build/exactElementSwitchParser.d.ts +3 -0
  87. package/build/exactElementSwitchParser.js +22 -0
  88. package/build/exactSequenceParser.d.ts +2 -1
  89. package/build/exactSequenceParser.js +12 -2
  90. package/build/fetchCid.d.ts +1 -0
  91. package/build/fetchCid.js +103 -0
  92. package/build/fetchCid.test.js +16 -0
  93. package/build/fixedLengthSequenceParser.d.ts +1 -0
  94. package/build/fixedLengthSequenceParser.js +18 -1
  95. package/build/fixedLengthSequenceParser.test.js +41 -0
  96. package/build/hasExecutable.d.ts +1 -0
  97. package/build/hasExecutable.js +8 -0
  98. package/build/highResolutionTimer.d.ts +16 -0
  99. package/build/highResolutionTimer.js +42 -0
  100. package/build/inputReader.d.ts +11 -0
  101. package/build/inputReader.js +37 -0
  102. package/build/inputReader.test.js +161 -8
  103. package/build/inputReaderState.d.ts +10 -0
  104. package/build/inputReaderState.js +16 -0
  105. package/build/inspect.d.ts +1 -0
  106. package/build/inspect.js +7 -0
  107. package/build/javaKeyStoreParser.test.js +8 -8
  108. package/build/jsonParser.d.ts +2 -0
  109. package/build/jsonParser.js +19 -22
  110. package/build/lazyMessageError.d.ts +48 -0
  111. package/build/lazyMessageError.js +53 -0
  112. package/build/lazyMessageError.test.d.ts +1 -0
  113. package/build/lazyMessageError.test.js +15 -0
  114. package/build/leb128Parser.d.ts +7 -0
  115. package/build/leb128Parser.js +82 -0
  116. package/build/leb128Parser.test.d.ts +1 -0
  117. package/build/leb128Parser.test.js +107 -0
  118. package/build/lookaheadParser.d.ts +2 -0
  119. package/build/lookaheadParser.js +14 -0
  120. package/build/negativeLookaheadParser.js +22 -16
  121. package/build/negativeLookaheadParser.test.d.ts +1 -0
  122. package/build/negativeLookaheadParser.test.js +30 -0
  123. package/build/noStackCaptureOverheadError.d.ts +4 -0
  124. package/build/noStackCaptureOverheadError.js +9 -0
  125. package/build/noStackCaptureOverheadError.test.d.ts +1 -0
  126. package/build/noStackCaptureOverheadError.test.js +15 -0
  127. package/build/nonEmptyArrayParser.d.ts +2 -0
  128. package/build/nonEmptyArrayParser.js +32 -0
  129. package/build/nonEmptyArrayParser.test.d.ts +1 -0
  130. package/build/nonEmptyArrayParser.test.js +17 -0
  131. package/build/optionalParser.js +2 -2
  132. package/build/parser.d.ts +11 -1
  133. package/build/parser.js +82 -32
  134. package/build/parser.test.js +141 -25
  135. package/build/parserAccessorParser.js +9 -1
  136. package/build/parserConsumedSequenceParser.d.ts +1 -1
  137. package/build/parserConsumedSequenceParser.js +21 -16
  138. package/build/parserContext.d.ts +22 -6
  139. package/build/parserContext.js +113 -57
  140. package/build/parserContext.test.js +33 -2
  141. package/build/parserCreatorCompose.d.ts +1 -0
  142. package/build/parserCreatorCompose.js +8 -2
  143. package/build/parserError.d.ts +605 -40
  144. package/build/parserError.js +98 -53
  145. package/build/parserImplementationInvariant.d.ts +1 -1
  146. package/build/parserImplementationInvariant.js +2 -2
  147. package/build/parserInputCompanion.d.ts +15 -0
  148. package/build/parserInputCompanion.js +38 -0
  149. package/build/promiseCompose.d.ts +1 -1
  150. package/build/promiseCompose.js +11 -1
  151. package/build/promiseSettled.d.ts +1 -0
  152. package/build/promiseSettled.js +4 -0
  153. package/build/separatedArrayParser.d.ts +2 -0
  154. package/build/separatedArrayParser.js +39 -0
  155. package/build/separatedArrayParser.test.d.ts +1 -0
  156. package/build/separatedArrayParser.test.js +21 -0
  157. package/build/separatedNonEmptyArrayParser.d.ts +2 -0
  158. package/build/separatedNonEmptyArrayParser.js +40 -0
  159. package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
  160. package/build/separatedNonEmptyArrayParser.test.js +66 -0
  161. package/build/sequenceBuffer.d.ts +10 -0
  162. package/build/sequenceBuffer.js +54 -2
  163. package/build/sequenceBuffer.test.js +57 -0
  164. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  165. package/build/sequenceTerminatedSequenceParser.js +32 -0
  166. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  167. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  168. package/build/sequenceUnparser.d.ts +1 -1
  169. package/build/skipParser.d.ts +1 -1
  170. package/build/skipParser.js +4 -2
  171. package/build/skipToParser.d.ts +2 -0
  172. package/build/skipToParser.js +11 -0
  173. package/build/sliceBoundedParser.d.ts +1 -1
  174. package/build/sliceBoundedParser.js +7 -2
  175. package/build/sliceBoundedParser.test.js +30 -1
  176. package/build/smali.d.ts +1 -0
  177. package/build/smali.js +21 -0
  178. package/build/smaliParser.d.ts +68 -0
  179. package/build/smaliParser.js +2081 -0
  180. package/build/smaliParser.test.d.ts +1 -0
  181. package/build/smaliParser.test.js +410 -0
  182. package/build/stringFromAsyncIterable.d.ts +1 -0
  183. package/build/stringFromAsyncIterable.js +7 -0
  184. package/build/terminatedArrayParser.d.ts +3 -1
  185. package/build/terminatedArrayParser.js +79 -2
  186. package/build/terminatedArrayParser.test.d.ts +1 -0
  187. package/build/terminatedArrayParser.test.js +131 -0
  188. package/build/toAsyncIterable.d.ts +1 -0
  189. package/build/toAsyncIterable.js +7 -0
  190. package/build/toAsyncIterator.d.ts +1 -0
  191. package/build/toAsyncIterator.js +33 -0
  192. package/build/tupleParser.d.ts +4 -0
  193. package/build/tupleParser.js +1 -5
  194. package/build/unionParser.d.ts +2 -1
  195. package/build/unionParser.js +29 -14
  196. package/build/unionParser.test.d.ts +1 -0
  197. package/build/unionParser.test.js +60 -0
  198. package/build/unparser.d.ts +3 -3
  199. package/build/unparser.js +6 -4
  200. package/build/unparser.test.js +7 -19
  201. package/build/unparserContext.d.ts +2 -2
  202. package/build/unparserContext.js +2 -3
  203. package/build/unparserError.d.ts +2 -1
  204. package/build/unparserError.js +2 -1
  205. package/build/unparserImplementationInvariant.d.ts +1 -1
  206. package/build/unparserOutputCompanion.d.ts +1 -1
  207. package/build/unparserOutputCompanion.js +1 -1
  208. package/build/zipParser.d.ts +7 -2
  209. package/build/zipParser.js +36 -12
  210. package/build/zipUnparser.d.ts +7 -4
  211. package/build/zipUnparser.js +64 -45
  212. package/build/zipUnparser.test.js +15 -15
  213. package/package.json +33 -24
  214. package/src/allSettledStream.test.ts +40 -0
  215. package/src/allSettledStream.ts +47 -15
  216. package/src/androidPackage.ts +48 -0
  217. package/src/androidPackageParser.test.ts +27 -0
  218. package/src/{apkParser.test.ts.md → androidPackageParser.test.ts.md} +4 -4
  219. package/src/androidPackageParser.test.ts.snap +0 -0
  220. package/src/androidPackageParser.ts +398 -0
  221. package/src/androidPackageUnparser.test.ts +34 -0
  222. package/src/androidPackageUnparser.ts +126 -0
  223. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  224. package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
  225. package/src/arbitraryDalvikBytecode.ts +992 -0
  226. package/src/arbitraryDalvikExecutable.ts +434 -0
  227. package/src/arbitraryDosDateTime.ts +1 -0
  228. package/src/arbitraryZipStream.ts +1 -1
  229. package/src/arrayParser.test.ts +3 -3
  230. package/src/arrayParser.ts +2 -2
  231. package/src/arrayUnparser.ts +2 -2
  232. package/src/backsmali.ts +74 -0
  233. package/src/bsonParser.test.ts +12 -14
  234. package/src/bsonParser.ts +13 -2
  235. package/src/customInvariant.ts +8 -12
  236. package/src/dalvikBytecodeParser/formatParsers.ts +780 -0
  237. package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
  238. package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
  239. package/src/dalvikBytecodeParser.ts +2873 -0
  240. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
  241. package/src/dalvikBytecodeUnparser.test.ts +44 -0
  242. package/src/dalvikBytecodeUnparser.ts +758 -0
  243. package/src/dalvikExecutable.ts +282 -0
  244. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  245. package/src/dalvikExecutableParser/typeParsers.ts +74 -0
  246. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  247. package/src/dalvikExecutableParser.test.ts +89 -0
  248. package/src/dalvikExecutableParser.test.ts.md +634 -0
  249. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  250. package/src/dalvikExecutableParser.ts +3245 -0
  251. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +363 -0
  252. package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
  253. package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
  254. package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
  255. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
  256. package/src/dalvikExecutableUnparser/utils.ts +149 -0
  257. package/src/dalvikExecutableUnparser.test.ts +57 -0
  258. package/src/dalvikExecutableUnparser.ts +581 -0
  259. package/src/debugLogInputParser.ts +28 -0
  260. package/src/debugLogParser.ts +19 -3
  261. package/src/disjunctionParser.ts +12 -7
  262. package/src/elementTerminatedArrayParser.test.ts +99 -0
  263. package/src/elementTerminatedArrayParser.ts +31 -0
  264. package/src/elementTerminatedSequenceArrayParser.test.ts +52 -0
  265. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  266. package/src/elementTerminatedSequenceParser.test.ts +52 -0
  267. package/src/elementTerminatedSequenceParser.ts +43 -0
  268. package/src/endOfInputParser.ts +1 -1
  269. package/src/exactElementParser.ts +17 -11
  270. package/src/exactElementSwitchParser.ts +41 -0
  271. package/src/exactSequenceParser.ts +23 -2
  272. package/src/fetchCid.test.ts +20 -0
  273. package/src/fetchCid.ts +121 -0
  274. package/src/fixedLengthSequenceParser.test.ts +75 -0
  275. package/src/fixedLengthSequenceParser.ts +28 -1
  276. package/src/hasExecutable.ts +11 -0
  277. package/src/highResolutionTimer.ts +49 -0
  278. package/src/inputReader.test.ts +204 -8
  279. package/src/inputReader.ts +76 -3
  280. package/src/inputReaderState.ts +33 -0
  281. package/src/inspect.ts +9 -0
  282. package/src/javaKeyStoreParser.test.ts +12 -15
  283. package/src/javaKeyStoreParser.ts +2 -6
  284. package/src/jsonParser.test.ts +2 -4
  285. package/src/jsonParser.ts +46 -62
  286. package/src/lazyMessageError.test.ts +21 -0
  287. package/src/lazyMessageError.ts +88 -0
  288. package/src/leb128Parser.test.ts +173 -0
  289. package/src/leb128Parser.ts +125 -0
  290. package/src/lookaheadParser.ts +19 -0
  291. package/src/negativeLookaheadParser.test.ts +49 -0
  292. package/src/negativeLookaheadParser.ts +27 -15
  293. package/src/noStackCaptureOverheadError.test.ts +17 -0
  294. package/src/noStackCaptureOverheadError.ts +12 -0
  295. package/src/nonEmptyArrayParser.test.ts +21 -0
  296. package/src/nonEmptyArrayParser.ts +44 -0
  297. package/src/optionalParser.ts +3 -2
  298. package/src/parser.test.ts +203 -31
  299. package/src/parser.test.ts.md +34 -27
  300. package/src/parser.test.ts.snap +0 -0
  301. package/src/parser.ts +172 -45
  302. package/src/parserAccessorParser.ts +12 -2
  303. package/src/parserConsumedSequenceParser.ts +26 -17
  304. package/src/parserContext.test.ts +37 -2
  305. package/src/parserContext.ts +185 -79
  306. package/src/parserCreatorCompose.ts +20 -2
  307. package/src/parserError.ts +144 -61
  308. package/src/parserImplementationInvariant.ts +3 -3
  309. package/src/parserInputCompanion.ts +55 -0
  310. package/src/promiseCompose.ts +17 -3
  311. package/src/promiseSettled.ts +6 -0
  312. package/src/separatedArrayParser.test.ts +34 -0
  313. package/src/separatedArrayParser.ts +55 -0
  314. package/src/separatedNonEmptyArrayParser.test.ts +117 -0
  315. package/src/separatedNonEmptyArrayParser.ts +61 -0
  316. package/src/sequenceBuffer.test.ts +70 -0
  317. package/src/sequenceBuffer.ts +88 -2
  318. package/src/sequenceTerminatedSequenceParser.test.ts +58 -0
  319. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  320. package/src/sequenceUnparser.ts +2 -2
  321. package/src/skipParser.ts +7 -5
  322. package/src/skipToParser.ts +16 -0
  323. package/src/sliceBoundedParser.test.ts +35 -1
  324. package/src/sliceBoundedParser.ts +19 -1
  325. package/src/smali.ts +29 -0
  326. package/src/smaliParser.test.ts +443 -0
  327. package/src/smaliParser.test.ts.md +3907 -0
  328. package/src/smaliParser.test.ts.snap +0 -0
  329. package/src/smaliParser.ts +3348 -0
  330. package/src/stringFromAsyncIterable.ts +9 -0
  331. package/src/terminatedArrayParser.test.ts +258 -0
  332. package/src/terminatedArrayParser.ts +109 -6
  333. package/src/toAsyncIterable.ts +7 -0
  334. package/src/toAsyncIterator.ts +48 -0
  335. package/src/tupleParser.ts +8 -5
  336. package/src/uint8Array.ts +2 -3
  337. package/src/unionParser.test.ts +78 -0
  338. package/src/unionParser.ts +47 -21
  339. package/src/unparser.test.ts +18 -34
  340. package/src/unparser.ts +13 -9
  341. package/src/unparserContext.ts +9 -13
  342. package/src/unparserError.ts +2 -1
  343. package/src/unparserImplementationInvariant.ts +1 -1
  344. package/src/unparserOutputCompanion.ts +1 -1
  345. package/src/zip.ts +2 -6
  346. package/src/zipParser.ts +71 -20
  347. package/src/zipUnparser.test.ts +19 -19
  348. package/src/zipUnparser.ts +139 -90
  349. package/tsconfig.json +7 -1
  350. package/xo.config.ts +15 -0
  351. package/.yarn/releases/yarn-4.5.3.cjs +0 -934
  352. package/build/apk.d.ts +0 -39
  353. package/build/apkParser.d.ts +0 -16
  354. package/build/apkParser.js +0 -164
  355. package/build/apkParser.test.js +0 -22
  356. package/build/apkUnparser.d.ts +0 -4
  357. package/build/apkUnparser.js +0 -90
  358. package/build/apkUnparser.test.js +0 -26
  359. package/build/arbitraryDosDate.d.ts +0 -2
  360. package/build/arbitraryDosDate.js +0 -8
  361. package/build/arbitraryZipEntry.d.ts +0 -3
  362. package/build/arbitraryZipEntry.js +0 -26
  363. package/build/createDisjunctionParser.d.ts +0 -2
  364. package/build/createDisjunctionParser.js +0 -47
  365. package/build/createExactParser.d.ts +0 -2
  366. package/build/createExactParser.js +0 -12
  367. package/build/createSequentialUnionParser.d.ts +0 -2
  368. package/build/createSequentialUnionParser.js +0 -69
  369. package/build/fixedLengthChunkParser.d.ts +0 -2
  370. package/build/fixedLengthChunkParser.js +0 -12
  371. package/build/fixedLengthParser.d.ts +0 -2
  372. package/build/fixedLengthParser.js +0 -12
  373. package/build/inputChunkBuffer.d.ts +0 -15
  374. package/build/inputChunkBuffer.js +0 -40
  375. package/build/inputChunkBuffer.test.js +0 -34
  376. package/build/inputCompanion.d.ts +0 -18
  377. package/build/inputCompanion.js +0 -28
  378. package/build/invariantDefined.d.ts +0 -1
  379. package/build/invariantDefined.js +0 -5
  380. package/build/invariantIdentity.d.ts +0 -3
  381. package/build/invariantIdentity.js +0 -5
  382. package/build/javaKeystoreParser.d.ts +0 -2
  383. package/build/javaKeystoreParser.js +0 -7
  384. package/build/jsonParser2.d.ts +0 -3
  385. package/build/jsonParser2.js +0 -52
  386. package/build/jsonParser2.test.js +0 -22
  387. package/build/negativeLookahead.d.ts +0 -2
  388. package/build/negativeLookahead.js +0 -18
  389. package/build/parserCompose.d.ts +0 -3
  390. package/build/parserCompose.js +0 -7
  391. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  392. package/build/parserImplementationInvariantInvariant.js +0 -15
  393. package/build/parserInvariant.d.ts +0 -4
  394. package/build/parserInvariant.js +0 -11
  395. package/build/promiseFish.d.ts +0 -1
  396. package/build/promiseFish.js +0 -3
  397. package/build/sequenceParser.d.ts +0 -3
  398. package/build/sequenceParser.js +0 -10
  399. package/build/terminatedSequenceParser.d.ts +0 -2
  400. package/build/terminatedSequenceParser.js +0 -24
  401. package/build/unparserInputCompanion.d.ts +0 -15
  402. package/build/unparserInputCompanion.js +0 -13
  403. package/build/zipEntry.d.ts +0 -28
  404. package/build/zipFile.d.ts +0 -32
  405. package/build/zipFileEntry.d.ts +0 -6
  406. package/src/apk.ts +0 -48
  407. package/src/apkParser.test.ts +0 -30
  408. package/src/apkParser.test.ts.snap +0 -0
  409. package/src/apkParser.ts +0 -392
  410. package/src/apkUnparser.test.ts +0 -37
  411. package/src/apkUnparser.ts +0 -120
  412. package/src/invariantDefined.ts +0 -6
  413. package/src/invariantIdentity.ts +0 -8
  414. /package/build/{apk.js → androidPackage.js} +0 -0
  415. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  416. /package/build/{apkUnparser.test.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  417. /package/build/{arbitraryDosPermissions.d.ts → dalvikBytecodeUnparser.test.d.ts} +0 -0
  418. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
  419. /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  420. /package/build/{jsonParser2.test.d.ts → dalvikExecutableUnparser.test.d.ts} +0 -0
  421. /package/build/{parserParsingInvariant.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  422. /package/build/{parserParsingInvariant.js → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  423. /package/build/{zipEntry.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
  424. /package/build/{zipFile.js → fetchCid.test.d.ts} +0 -0
  425. /package/build/{zipFileEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
@@ -0,0 +1,72 @@
1
+ import test from 'ava';
2
+ import { runParser } from './parser.js';
3
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
4
+ import { dalvikExecutableParser, dalvikExecutableWithRawInstructionsParser } from './dalvikExecutableParser.js';
5
+ import { fetchCid } from './fetchCid.js';
6
+ const dexWithRawInstructionsMacro = test.macro({
7
+ title: (providedTitle, dexCid) => providedTitle ?? `dex (with instructions as bytes) ${dexCid}`,
8
+ async exec(t, dexCid, shouldSnapshot) {
9
+ const dexStream = await fetchCid(dexCid);
10
+ const actual = await runParser(dalvikExecutableWithRawInstructionsParser, dexStream, uint8ArrayParserInputCompanion, {
11
+ errorJoinMode: 'all',
12
+ });
13
+ if (shouldSnapshot) {
14
+ t.snapshot(actual);
15
+ }
16
+ else {
17
+ // Console.dir(actual, { depth: null });
18
+ t.pass();
19
+ }
20
+ },
21
+ });
22
+ test.serial(dexWithRawInstructionsMacro, 'bafkreibb4gsprc3fvmnyqx6obswvm7e7wngnfj64gz65ey72r7xgyzymt4', true);
23
+ test.serial(dexWithRawInstructionsMacro, 'bafybeiebe27ylo53trgitu6fqfbmba43c4ivxj3nt4kumsilkucpbdxtqq', false);
24
+ test.serial(dexWithRawInstructionsMacro, 'bafybeibbupm7uzhuq4pa674rb2amxsenbdaoijigmaf4onaodaql4mh7yy', false);
25
+ test.serial(dexWithRawInstructionsMacro, 'bafybeicb3qajmwy6li7hche2nkucvytaxcyxhwhphmi73tgydjzmyoqoda', false);
26
+ function objectWalk(object, f, initialPath = []) {
27
+ f(initialPath, object);
28
+ if (!object
29
+ || typeof object !== 'object') {
30
+ return;
31
+ }
32
+ if (Array.isArray(object)) {
33
+ for (const [index, value] of object.entries()) {
34
+ objectWalk(value, f, [...initialPath, index]);
35
+ }
36
+ }
37
+ else {
38
+ for (const [key, value] of Object.entries(object)) {
39
+ objectWalk(value, f, [...initialPath, key]);
40
+ }
41
+ }
42
+ }
43
+ const dexWithParsedInstructionsMacro = test.macro({
44
+ title: (providedTitle, dexCid) => providedTitle ?? `dex (with parsed instructions) ${dexCid}`,
45
+ async exec(t, dexCid, shouldSnapshot) {
46
+ const dexStream = await fetchCid(dexCid);
47
+ debugger;
48
+ const actual = await runParser(dalvikExecutableParser, dexStream, uint8ArrayParserInputCompanion, {
49
+ errorJoinMode: 'all',
50
+ });
51
+ debugger;
52
+ objectWalk(actual, path => {
53
+ const key = path.at(-1);
54
+ if (typeof key !== 'string') {
55
+ return;
56
+ }
57
+ t.false(key.endsWith('Offset') && key !== 'branchOffset', 'All offsets should be resolved: ' + path.join('.'));
58
+ t.false(key.endsWith('Index'), 'All indexes should be resolved: ' + path.join('.'));
59
+ });
60
+ if (shouldSnapshot) {
61
+ t.snapshot(actual);
62
+ }
63
+ else {
64
+ // Console.dir(actual, { depth: null });
65
+ t.pass();
66
+ }
67
+ },
68
+ });
69
+ test.serial.only(dexWithParsedInstructionsMacro, 'bafkreibb4gsprc3fvmnyqx6obswvm7e7wngnfj64gz65ey72r7xgyzymt4', true);
70
+ test.serial.skip(dexWithParsedInstructionsMacro, 'bafybeiebe27ylo53trgitu6fqfbmba43c4ivxj3nt4kumsilkucpbdxtqq', false);
71
+ test.serial.skip(dexWithParsedInstructionsMacro, 'bafybeibbupm7uzhuq4pa674rb2amxsenbdaoijigmaf4onaodaql4mh7yy', false);
72
+ test.serial.skip(dexWithParsedInstructionsMacro, 'bafybeicb3qajmwy6li7hche2nkucvytaxcyxhwhphmi73tgydjzmyoqoda', false);
@@ -0,0 +1,275 @@
1
+ import test from 'ava';
2
+ import { runParser } from './parser.js';
3
+ import { stringParserInputCompanion, uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
4
+ import { dalvikExecutableParser } from './dalvikExecutableParser.js';
5
+ import { fetchCid } from './fetchCid.js';
6
+ import { hasExecutable } from './hasExecutable.js';
7
+ import { backsmaliSmaliIsolateClass, baksmaliClass, baksmaliListClasses } from './backsmali.js';
8
+ import { smaliParser } from './smaliParser.js';
9
+ import { smaliClass } from './smali.js';
10
+ const hasBaksmaliPromise = hasExecutable('baksmali');
11
+ const hasSmaliPromise = hasExecutable('smali');
12
+ function objectWalk(object, f, initialPath = []) {
13
+ f(initialPath, object);
14
+ if (!object
15
+ || typeof object !== 'object') {
16
+ return;
17
+ }
18
+ if (Array.isArray(object)) {
19
+ for (const [index, value] of object.entries()) {
20
+ objectWalk(value, f, [...initialPath, index]);
21
+ }
22
+ }
23
+ else {
24
+ for (const [key, value] of Object.entries(object)) {
25
+ objectWalk(value, f, [...initialPath, key]);
26
+ }
27
+ }
28
+ }
29
+ function normalizeSmaliFilePath(smaliFilePath) {
30
+ if (typeof smaliFilePath === 'string') {
31
+ return {
32
+ smaliFilePath,
33
+ isolate: false,
34
+ };
35
+ }
36
+ return {
37
+ smaliFilePath: smaliFilePath.smaliFilePath,
38
+ isolate: smaliFilePath.isolate ?? false,
39
+ };
40
+ }
41
+ function normalizeClassDefinition(classDefinition) {
42
+ objectWalk(classDefinition, (_path, value) => {
43
+ if (value
44
+ && typeof value === 'object'
45
+ && 'debugInfo' in value) {
46
+ value.debugInfo = undefined;
47
+ }
48
+ });
49
+ }
50
+ const parseDexAgainstSmaliMacro = test.macro({
51
+ title(providedTitle, dexCid, smaliFilePathInput) {
52
+ const { smaliFilePath, isolate } = normalizeSmaliFilePath(smaliFilePathInput);
53
+ return providedTitle ?? `parse(dex) against parse(smali(dex)) ${dexCid} ${smaliFilePath}${isolate ? ' isolated' : ''}`;
54
+ },
55
+ async exec(t, dexCid, smaliFilePathInput) {
56
+ const { smaliFilePath, isolate } = normalizeSmaliFilePath(smaliFilePathInput);
57
+ const hasBaksmali = await hasBaksmaliPromise;
58
+ if (!hasBaksmali) {
59
+ t.pass('skipping test because baksmali is not available');
60
+ return;
61
+ }
62
+ const dexStream = await fetchCid(dexCid);
63
+ const smali_ = await baksmaliClass(dexStream, smaliFilePath);
64
+ const smali = (smali_
65
+ .replaceAll(/^\s+# getter for:.*$/gm, '')
66
+ .replaceAll(/^\s+# setter for:.*$/gm, '')
67
+ .replaceAll(/^\s+# invokes:.*$/gm, '')
68
+ .replaceAll(/\n{3,}/g, '\n\n'));
69
+ // Console.log(smali);
70
+ const classDefinitionFromSmali = await runParser(smaliParser, smali, stringParserInputCompanion, {
71
+ errorJoinMode: 'all',
72
+ });
73
+ let dexStream2 = await fetchCid(dexCid);
74
+ if (isolate) {
75
+ dexStream2 = await backsmaliSmaliIsolateClass(dexStream2, smaliFilePath);
76
+ }
77
+ const executableFromDex = await runParser(dalvikExecutableParser, dexStream2, uint8ArrayParserInputCompanion, {
78
+ errorJoinMode: 'all',
79
+ });
80
+ const classDefinitionFromDex = executableFromDex.classDefinitions.find(classDefinition => classDefinition.class === classDefinitionFromSmali.class);
81
+ // Normalize both DEX and Smali by removing debug info
82
+ normalizeClassDefinition(classDefinitionFromDex);
83
+ normalizeClassDefinition(classDefinitionFromSmali);
84
+ // Console.dir({
85
+ // classDefinitionFromSmali,
86
+ // classDefinitionFromDex,
87
+ // }, {
88
+ // depth: null,
89
+ // });
90
+ t.deepEqual(classDefinitionFromDex, classDefinitionFromSmali);
91
+ },
92
+ });
93
+ const parseAllClassesInDexAgainstSmaliMacro = test.macro({
94
+ title(providedTitle, dexCid, options) {
95
+ return providedTitle ?? `parse all classes from dex ${dexCid} against smali${options?.skipUntilClassPath ? ` (skip until ${options.skipUntilClassPath})` : ''}`;
96
+ },
97
+ async exec(t, dexCid, options) {
98
+ const hasBaksmali = await hasBaksmaliPromise;
99
+ if (!hasBaksmali) {
100
+ t.pass('skipping test because baksmali is not available');
101
+ return;
102
+ }
103
+ const dexStream = await fetchCid(dexCid);
104
+ const classes = ((await baksmaliListClasses(dexStream))
105
+ .map(smaliFilePath => ({ smaliFilePath, sort: Math.random() }))
106
+ .sort((a, b) => a.sort - b.sort)
107
+ .map(({ smaliFilePath }) => smaliFilePath));
108
+ const failures = [];
109
+ let shouldProcess = options?.skipUntilClassPath === undefined;
110
+ let processedCount = 0;
111
+ for (const smaliFilePath of classes) {
112
+ if (options?.skipUntilClassPath && smaliFilePath === options.skipUntilClassPath) {
113
+ shouldProcess = true;
114
+ }
115
+ if (!shouldProcess) {
116
+ continue;
117
+ }
118
+ processedCount++;
119
+ const result = await t.try(parseDexAgainstSmaliMacro, dexCid, {
120
+ smaliFilePath,
121
+ isolate: true,
122
+ });
123
+ if (result.passed) {
124
+ result.commit();
125
+ console.log(`ok ${processedCount}/${classes.length}`, smaliFilePath);
126
+ continue;
127
+ }
128
+ function consoleLogFailure(failure) {
129
+ const [error] = failure.errors;
130
+ console.log(error.formattedDetails.at(0).formatted ?? error);
131
+ }
132
+ console.log(smaliFilePath);
133
+ consoleLogFailure(result);
134
+ failures.push(result);
135
+ if (failures.length >= (options?.maxFailures ?? 1)) {
136
+ for (const failure of failures) {
137
+ consoleLogFailure(failure);
138
+ }
139
+ for (const failure of failures) {
140
+ failure.commit();
141
+ }
142
+ }
143
+ }
144
+ for (const failure of failures) {
145
+ failure.commit();
146
+ }
147
+ t.pass('completed all classes');
148
+ },
149
+ });
150
+ const testCasesByCid = {
151
+ bafybeicb3qajmwy6li7hche2nkucvytaxcyxhwhphmi73tgydjzmyoqoda: [
152
+ { smaliFilePath: 'androidx/activity/ComponentActivity$1', isolate: true },
153
+ { smaliFilePath: 'androidx/activity/R$id', isolate: true },
154
+ { smaliFilePath: 'androidx/activity/ComponentActivity$NonConfigurationInstances', isolate: true },
155
+ { smaliFilePath: 'androidx/appcompat/R$styleable', isolate: true },
156
+ { smaliFilePath: 'androidx/core/content/FileProvider', isolate: true },
157
+ { smaliFilePath: 'androidx/core/view/KeyEventDispatcher', isolate: true },
158
+ { smaliFilePath: 'com/google/android/exoplayer2/audio/Sonic', isolate: true },
159
+ { smaliFilePath: 'com/google/android/exoplayer2/ext/opus/OpusDecoder', isolate: true },
160
+ { smaliFilePath: 'com/google/android/exoplayer2/extractor/ts/H262Reader', isolate: true },
161
+ { smaliFilePath: 'com/google/android/gms/internal/common/zzg', isolate: true },
162
+ { smaliFilePath: 'com/google/android/gms/internal/mlkit_vision_label/zzcm', isolate: true },
163
+ { smaliFilePath: 'com/google/android/play/core/integrity/model/StandardIntegrityErrorCode', isolate: true },
164
+ { smaliFilePath: 'com/google/common/math/IntMath', isolate: true },
165
+ { smaliFilePath: 'com/google/gson/internal/bind/CollectionTypeAdapterFactory', isolate: true },
166
+ ],
167
+ bafkreibb4gsprc3fvmnyqx6obswvm7e7wngnfj64gz65ey72r7xgyzymt4: [
168
+ 'pl/czak/minimal/MainActivity',
169
+ 'pl/czak/minimal/R',
170
+ ],
171
+ bafybeibbupm7uzhuq4pa674rb2amxsenbdaoijigmaf4onaodaql4mh7yy: [
172
+ { smaliFilePath: 'com/journeyapps/barcodescanner/CaptureActivity', isolate: true },
173
+ { smaliFilePath: '_COROUTINE/ArtificialStackFrames', isolate: true },
174
+ { smaliFilePath: 'androidx/appcompat/widget/AppCompatTextHelper', isolate: true },
175
+ { smaliFilePath: '_COROUTINE/CoroutineDebuggingKt', isolate: true },
176
+ { smaliFilePath: 'androidx/compose/ui/text/android/style/LineHeightSpan', isolate: true },
177
+ { smaliFilePath: 'androidx/compose/ui/layout/LayoutIdElement', isolate: true },
178
+ { smaliFilePath: 'androidx/compose/ui/text/EmojiSupportMatch', isolate: true },
179
+ { smaliFilePath: 'androidx/compose/ui/focus/FocusTransactionsKt', isolate: true },
180
+ { smaliFilePath: 'androidx/compose/animation/core/SpringSimulationKt', isolate: true },
181
+ { smaliFilePath: 'androidx/constraintlayout/core/widgets/ConstraintWidget', isolate: true },
182
+ { smaliFilePath: 'ch/qos/logback/core/CoreConstants', isolate: true },
183
+ { smaliFilePath: 'ch/qos/logback/classic/spi/ClassPackagingData', isolate: true },
184
+ { smaliFilePath: 'kotlin/coroutines/jvm/internal/DebugMetadata', isolate: true },
185
+ ],
186
+ bafybeiebe27ylo53trgitu6fqfbmba43c4ivxj3nt4kumsilkucpbdxtqq: [
187
+ { smaliFilePath: 'androidx/viewpager2/adapter/FragmentStateAdapter$5', isolate: true },
188
+ { smaliFilePath: 'androidx/lifecycle/b0', isolate: true },
189
+ { smaliFilePath: 'androidx/activity/b', isolate: true },
190
+ { smaliFilePath: 'androidx/activity/result/a$a', isolate: true },
191
+ { smaliFilePath: 'androidx/annotation/Keep', isolate: true },
192
+ { smaliFilePath: 'androidx/activity/result/e', isolate: true },
193
+ { smaliFilePath: 'androidx/appcompat/widget/ActionBarContextView$a', isolate: true },
194
+ { smaliFilePath: 'androidx/appcompat/widget/b0', isolate: true },
195
+ { smaliFilePath: 'androidx/appcompat/widget/b1', isolate: true },
196
+ { smaliFilePath: 'androidx/appcompat/widget/e', isolate: true },
197
+ { smaliFilePath: 'androidx/appcompat/widget/m0', isolate: true },
198
+ { smaliFilePath: 'androidx/appcompat/widget/r1', isolate: true },
199
+ { smaliFilePath: 'androidx/recyclerview/widget/RecyclerView$a0', isolate: true },
200
+ { smaliFilePath: 'androidx/constraintlayout/widget/ConstraintLayout$a', isolate: true },
201
+ { smaliFilePath: 'l4/a', isolate: true },
202
+ { smaliFilePath: 'n4/o', isolate: true },
203
+ { smaliFilePath: 'o6/f', isolate: true },
204
+ { smaliFilePath: 'a', isolate: true },
205
+ { smaliFilePath: 'a/b', isolate: true },
206
+ { smaliFilePath: 'f/b', isolate: true },
207
+ { smaliFilePath: 'h1/j', isolate: true },
208
+ { smaliFilePath: 'android/app/AppComponentFactory', isolate: true },
209
+ { smaliFilePath: 'android/app/job/JobInfo$TriggerContentUri', isolate: true },
210
+ { smaliFilePath: 'android/graphics/BlendModeColorFilter', isolate: true },
211
+ { smaliFilePath: 'android/graphics/fonts/Font$Builder', isolate: true },
212
+ { smaliFilePath: 'android/os/LocaleList', isolate: true },
213
+ { smaliFilePath: 'a0/i', isolate: true },
214
+ { smaliFilePath: 'a0/l', isolate: true },
215
+ { smaliFilePath: 'a0/n', isolate: true },
216
+ { smaliFilePath: 'a0/p', isolate: true },
217
+ { smaliFilePath: 'a0/v', isolate: true },
218
+ { smaliFilePath: 'a0/v$a', isolate: true },
219
+ { smaliFilePath: 'a3/a', isolate: true },
220
+ { smaliFilePath: 'a3/b', isolate: true },
221
+ { smaliFilePath: 'a3/d', isolate: true },
222
+ { smaliFilePath: 'a4/b', isolate: true },
223
+ { smaliFilePath: 'b4/v', isolate: true },
224
+ { smaliFilePath: 'd6/a', isolate: true },
225
+ { smaliFilePath: 'q2/d$a', isolate: true },
226
+ { smaliFilePath: 'y4/t1', isolate: true },
227
+ { smaliFilePath: 'com/google/android/material/textfield/b', isolate: true },
228
+ { smaliFilePath: 'm/g', isolate: true },
229
+ ],
230
+ };
231
+ for (const [dexCid, smaliFilePaths] of Object.entries(testCasesByCid)) {
232
+ for (const smaliFilePath of smaliFilePaths) {
233
+ test.serial(parseDexAgainstSmaliMacro, dexCid, smaliFilePath);
234
+ }
235
+ }
236
+ for (const dexCid of Object.keys(testCasesByCid)) {
237
+ test.serial.skip(parseAllClassesInDexAgainstSmaliMacro, dexCid);
238
+ }
239
+ const smali = `
240
+ .class public final La0/l;
241
+ .super Ljava/lang/Object;
242
+ .source "SourceFile"
243
+
244
+ # direct methods
245
+ .method public static final a(Lh1/p;ZJ)F
246
+ .registers 6
247
+
248
+ return v0
249
+ .end method
250
+ `;
251
+ test.serial('parse(dex(smali)) againts parse(smali)', async (t) => {
252
+ const hasSmali = await hasSmaliPromise;
253
+ if (!hasSmali) {
254
+ t.pass('skipping test because smali is not available');
255
+ return;
256
+ }
257
+ const dexBuffer = await smaliClass(smali);
258
+ const classDefinitionFromSmali = await runParser(smaliParser, smali, stringParserInputCompanion, {
259
+ errorJoinMode: 'all',
260
+ });
261
+ const executableFromDex = await runParser(dalvikExecutableParser, dexBuffer, uint8ArrayParserInputCompanion, {
262
+ errorJoinMode: 'all',
263
+ });
264
+ const classDefinitionFromDex = executableFromDex.classDefinitions.find(classDefinition => classDefinition.class === classDefinitionFromSmali.class);
265
+ // Normalize both DEX and Smali by removing debug info
266
+ normalizeClassDefinition(classDefinitionFromDex);
267
+ normalizeClassDefinition(classDefinitionFromSmali);
268
+ // Console.dir({
269
+ // classDefinitionFromDex,
270
+ // classDefinitionFromSmali,
271
+ // }, {
272
+ // depth: null,
273
+ // });
274
+ t.deepEqual(classDefinitionFromDex, classDefinitionFromSmali);
275
+ });
@@ -0,0 +1,14 @@
1
+ import { type Unparser } from '../unparser.js';
2
+ import { type DalvikExecutableAnnotation, type DalvikExecutableClassAnnotations, type DalvikExecutableEncodedValue, type DalvikExecutableField, type DalvikExecutableMethod } from '../dalvikExecutable.js';
3
+ import { WriteLater } from '../unparserContext.js';
4
+ export declare function createAnnotationUnparsers(getStringIndex: (str: string | undefined) => number, getTypeIndex: (typeDescriptor: string | undefined) => number, getFieldIndex: (field: DalvikExecutableField) => number, getMethodIndex: (method: DalvikExecutableMethod) => number, encodedValueUnparser: Unparser<DalvikExecutableEncodedValue, Uint8Array>): {
5
+ annotationItemUnparser: Unparser<DalvikExecutableAnnotation, Uint8Array<ArrayBufferLike>>;
6
+ annotationSetItemUnparser: (annotationItemOffsetWriteLaters: Array<WriteLater<Uint8Array, number>>) => Unparser<DalvikExecutableAnnotation[], Uint8Array>;
7
+ annotationSetRefListUnparser: (annotationSetOffsetWriteLaters: Array<WriteLater<Uint8Array, number> | null>) => Unparser<DalvikExecutableAnnotation[][], Uint8Array>;
8
+ annotationsDirectoryItemUnparser: (annotationOffsetWriteLaters: {
9
+ classAnnotationsOffsetWriteLater?: WriteLater<Uint8Array, number>;
10
+ fieldAnnotationsOffsetWriteLaters?: Array<WriteLater<Uint8Array, number> | null>;
11
+ methodAnnotationsOffsetWriteLaters?: Array<WriteLater<Uint8Array, number>>;
12
+ parameterAnnotationsOffsetWriteLaters?: Array<WriteLater<Uint8Array, number>>;
13
+ }) => Unparser<DalvikExecutableClassAnnotations, Uint8Array>;
14
+ };
@@ -0,0 +1,97 @@
1
+ async function* yieldAndCapture(gen) {
2
+ let value;
3
+ for await (value of gen) {
4
+ yield value;
5
+ }
6
+ return value;
7
+ }
8
+ import { ubyteUnparser, uintUnparser } from '../dalvikBytecodeUnparser/formatUnparsers.js';
9
+ import { alignmentUnparser, uleb128Unparser } from './utils.js';
10
+ export function createAnnotationUnparsers(getStringIndex, getTypeIndex, getFieldIndex, getMethodIndex, encodedValueUnparser) {
11
+ const annotationItemUnparser = async function* (input, unparserContext) {
12
+ const visibilityByte = input.visibility === 'build' ? 0x00 : input.visibility === 'runtime' ? 0x01 : 0x02;
13
+ yield* ubyteUnparser(visibilityByte, unparserContext);
14
+ const typeIndex = getTypeIndex(input.type);
15
+ yield* uleb128Unparser(typeIndex, unparserContext);
16
+ yield* uleb128Unparser(input.elements.length, unparserContext);
17
+ for (const element of input.elements) {
18
+ const nameIndex = getStringIndex(element.name);
19
+ yield* uleb128Unparser(nameIndex, unparserContext);
20
+ yield* encodedValueUnparser(element.value, unparserContext);
21
+ }
22
+ };
23
+ const annotationSetItemUnparser = (annotationItemOffsetWriteLaters) => {
24
+ return async function* (input, unparserContext) {
25
+ yield* alignmentUnparser(4)(undefined, unparserContext);
26
+ yield* uintUnparser(input.length, unparserContext);
27
+ for (const annotation of input) {
28
+ const annotationOffsetWriteLater = yield* yieldAndCapture(unparserContext.writeLater(4));
29
+ annotationItemOffsetWriteLaters.push(annotationOffsetWriteLater);
30
+ }
31
+ };
32
+ };
33
+ const annotationSetRefListUnparser = (annotationSetOffsetWriteLaters) => {
34
+ return async function* (input, unparserContext) {
35
+ yield* alignmentUnparser(4)(undefined, unparserContext);
36
+ yield* uintUnparser(input.length, unparserContext);
37
+ for (const annotationSet of input) {
38
+ if (annotationSet.length > 0) {
39
+ const annotationSetOffsetWriteLater = yield* yieldAndCapture(unparserContext.writeLater(4));
40
+ annotationSetOffsetWriteLaters.push(annotationSetOffsetWriteLater);
41
+ }
42
+ else {
43
+ annotationSetOffsetWriteLaters.push(null);
44
+ yield* uintUnparser(0, unparserContext);
45
+ }
46
+ }
47
+ };
48
+ };
49
+ const annotationsDirectoryItemUnparser = (annotationOffsetWriteLaters) => {
50
+ return async function* (input, unparserContext) {
51
+ yield* alignmentUnparser(4)(undefined, unparserContext);
52
+ if (input.classAnnotations.length > 0) {
53
+ const classAnnotationsOffsetWriteLater = yield* yieldAndCapture(unparserContext.writeLater(4));
54
+ annotationOffsetWriteLaters.classAnnotationsOffsetWriteLater = classAnnotationsOffsetWriteLater;
55
+ }
56
+ else {
57
+ yield* uintUnparser(0, unparserContext);
58
+ }
59
+ yield* uintUnparser(input.fieldAnnotations.length, unparserContext);
60
+ yield* uintUnparser(input.methodAnnotations.length, unparserContext);
61
+ yield* uintUnparser(input.parameterAnnotations.length, unparserContext);
62
+ annotationOffsetWriteLaters.fieldAnnotationsOffsetWriteLaters = [];
63
+ for (const fieldAnnotation of input.fieldAnnotations) {
64
+ const fieldIndex = getFieldIndex(fieldAnnotation.field);
65
+ yield* uintUnparser(fieldIndex, unparserContext);
66
+ if (fieldAnnotation.annotations && fieldAnnotation.annotations.length > 0) {
67
+ const annotationsOffsetWriteLater = yield* yieldAndCapture(unparserContext.writeLater(4));
68
+ annotationOffsetWriteLaters.fieldAnnotationsOffsetWriteLaters.push(annotationsOffsetWriteLater);
69
+ }
70
+ else {
71
+ annotationOffsetWriteLaters.fieldAnnotationsOffsetWriteLaters.push(null);
72
+ yield* uintUnparser(0, unparserContext);
73
+ }
74
+ }
75
+ annotationOffsetWriteLaters.methodAnnotationsOffsetWriteLaters = [];
76
+ for (const methodAnnotation of input.methodAnnotations) {
77
+ const methodIndex = getMethodIndex(methodAnnotation.method);
78
+ yield* uintUnparser(methodIndex, unparserContext);
79
+ const annotationsOffsetWriteLater = yield* yieldAndCapture(unparserContext.writeLater(4));
80
+ annotationOffsetWriteLaters.methodAnnotationsOffsetWriteLaters.push(annotationsOffsetWriteLater);
81
+ }
82
+ annotationOffsetWriteLaters.parameterAnnotationsOffsetWriteLaters = [];
83
+ for (const paramAnnotation of input.parameterAnnotations) {
84
+ const methodIndex = getMethodIndex(paramAnnotation.method);
85
+ yield* uintUnparser(methodIndex, unparserContext);
86
+ const annotationsOffsetWriteLater = yield* yieldAndCapture(unparserContext.writeLater(4));
87
+ annotationOffsetWriteLaters.parameterAnnotationsOffsetWriteLaters.push(annotationsOffsetWriteLater);
88
+ }
89
+ };
90
+ };
91
+ return {
92
+ annotationItemUnparser,
93
+ annotationSetItemUnparser,
94
+ annotationSetRefListUnparser,
95
+ annotationsDirectoryItemUnparser,
96
+ };
97
+ }
@@ -0,0 +1,49 @@
1
+ import { type DalvikExecutableField, type DalvikExecutableMethod, type DalvikExecutablePrototype } from '../dalvikExecutable.js';
2
+ export declare class StringPoolBuilder {
3
+ private strings;
4
+ private stringToIndex;
5
+ add(str: string): number;
6
+ getIndex(str: string): number | undefined;
7
+ getStrings(): string[];
8
+ size(): number;
9
+ }
10
+ export declare class TypePoolBuilder {
11
+ private types;
12
+ private typeToIndex;
13
+ add(typeDescriptor: string): number;
14
+ getIndex(typeDescriptor: string): number | undefined;
15
+ getTypes(): string[];
16
+ size(): number;
17
+ }
18
+ export declare class ProtoPoolBuilder {
19
+ private protos;
20
+ private protoToIndex;
21
+ add(proto: DalvikExecutablePrototype): number;
22
+ getIndex(proto: DalvikExecutablePrototype): number | undefined;
23
+ getProtos(): DalvikExecutablePrototype[];
24
+ size(): number;
25
+ }
26
+ export declare class FieldPoolBuilder {
27
+ private fields;
28
+ private fieldToIndex;
29
+ add(field: DalvikExecutableField): number;
30
+ getIndex(field: DalvikExecutableField): number | undefined;
31
+ getFields(): DalvikExecutableField[];
32
+ size(): number;
33
+ }
34
+ export declare class MethodPoolBuilder {
35
+ private methods;
36
+ private methodToIndex;
37
+ add(method: DalvikExecutableMethod): number;
38
+ getIndex(method: DalvikExecutableMethod): number | undefined;
39
+ getMethods(): DalvikExecutableMethod[];
40
+ size(): number;
41
+ }
42
+ export interface PoolBuilders {
43
+ stringPool: StringPoolBuilder;
44
+ typePool: TypePoolBuilder;
45
+ protoPool: ProtoPoolBuilder;
46
+ fieldPool: FieldPoolBuilder;
47
+ methodPool: MethodPoolBuilder;
48
+ }
49
+ export declare function createPoolBuilders(): PoolBuilders;
@@ -0,0 +1,140 @@
1
+ export class StringPoolBuilder {
2
+ strings = [];
3
+ stringToIndex = new Map();
4
+ add(str) {
5
+ const existing = this.stringToIndex.get(str);
6
+ if (existing !== undefined) {
7
+ return existing;
8
+ }
9
+ const index = this.strings.length;
10
+ this.strings.push(str);
11
+ this.stringToIndex.set(str, index);
12
+ return index;
13
+ }
14
+ getIndex(str) {
15
+ return this.stringToIndex.get(str);
16
+ }
17
+ getStrings() {
18
+ return this.strings;
19
+ }
20
+ size() {
21
+ return this.strings.length;
22
+ }
23
+ }
24
+ export class TypePoolBuilder {
25
+ types = [];
26
+ typeToIndex = new Map();
27
+ add(typeDescriptor) {
28
+ const existing = this.typeToIndex.get(typeDescriptor);
29
+ if (existing !== undefined) {
30
+ return existing;
31
+ }
32
+ const index = this.types.length;
33
+ this.types.push(typeDescriptor);
34
+ this.typeToIndex.set(typeDescriptor, index);
35
+ return index;
36
+ }
37
+ getIndex(typeDescriptor) {
38
+ return this.typeToIndex.get(typeDescriptor);
39
+ }
40
+ getTypes() {
41
+ return this.types;
42
+ }
43
+ size() {
44
+ return this.types.length;
45
+ }
46
+ }
47
+ function prototypeKey(proto) {
48
+ return `${proto.shorty}:${proto.returnType}:(${proto.parameters.join(',')})`;
49
+ }
50
+ export class ProtoPoolBuilder {
51
+ protos = [];
52
+ protoToIndex = new Map();
53
+ add(proto) {
54
+ const key = prototypeKey(proto);
55
+ const existing = this.protoToIndex.get(key);
56
+ if (existing !== undefined) {
57
+ return existing;
58
+ }
59
+ const index = this.protos.length;
60
+ this.protos.push(proto);
61
+ this.protoToIndex.set(key, index);
62
+ return index;
63
+ }
64
+ getIndex(proto) {
65
+ const key = prototypeKey(proto);
66
+ return this.protoToIndex.get(key);
67
+ }
68
+ getProtos() {
69
+ return this.protos;
70
+ }
71
+ size() {
72
+ return this.protos.length;
73
+ }
74
+ }
75
+ function fieldKey(field) {
76
+ return `${field.class}:${field.type}:${field.name}`;
77
+ }
78
+ export class FieldPoolBuilder {
79
+ fields = [];
80
+ fieldToIndex = new Map();
81
+ add(field) {
82
+ const key = fieldKey(field);
83
+ const existing = this.fieldToIndex.get(key);
84
+ if (existing !== undefined) {
85
+ return existing;
86
+ }
87
+ const index = this.fields.length;
88
+ this.fields.push(field);
89
+ this.fieldToIndex.set(key, index);
90
+ return index;
91
+ }
92
+ getIndex(field) {
93
+ const key = fieldKey(field);
94
+ return this.fieldToIndex.get(key);
95
+ }
96
+ getFields() {
97
+ return this.fields;
98
+ }
99
+ size() {
100
+ return this.fields.length;
101
+ }
102
+ }
103
+ function methodKey(method) {
104
+ const protoKey = prototypeKey(method.prototype);
105
+ return `${method.class}:${protoKey}:${method.name}`;
106
+ }
107
+ export class MethodPoolBuilder {
108
+ methods = [];
109
+ methodToIndex = new Map();
110
+ add(method) {
111
+ const key = methodKey(method);
112
+ const existing = this.methodToIndex.get(key);
113
+ if (existing !== undefined) {
114
+ return existing;
115
+ }
116
+ const index = this.methods.length;
117
+ this.methods.push(method);
118
+ this.methodToIndex.set(key, index);
119
+ return index;
120
+ }
121
+ getIndex(method) {
122
+ const key = methodKey(method);
123
+ return this.methodToIndex.get(key);
124
+ }
125
+ getMethods() {
126
+ return this.methods;
127
+ }
128
+ size() {
129
+ return this.methods.length;
130
+ }
131
+ }
132
+ export function createPoolBuilders() {
133
+ return {
134
+ stringPool: new StringPoolBuilder(),
135
+ typePool: new TypePoolBuilder(),
136
+ protoPool: new ProtoPoolBuilder(),
137
+ fieldPool: new FieldPoolBuilder(),
138
+ methodPool: new MethodPoolBuilder(),
139
+ };
140
+ }
@@ -0,0 +1,4 @@
1
+ import { type DalvikExecutable } from '../dalvikExecutable.js';
2
+ import { type DalvikBytecode } from '../dalvikBytecodeParser.js';
3
+ import { type PoolBuilders } from './poolBuilders.js';
4
+ export declare function scanForPoolReferences(dalvikExecutable: DalvikExecutable<DalvikBytecode>, poolBuilders: PoolBuilders): void;