@futpib/parser 1.0.3 → 1.0.6

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 (262) hide show
  1. package/.claude/settings.local.json +24 -0
  2. package/.github/workflows/main.yml +1 -0
  3. package/build/androidPackageParser.js +30 -32
  4. package/build/arbitraryDalvikBytecode.d.ts +3 -3
  5. package/build/arbitraryDalvikBytecode.js +33 -27
  6. package/build/arbitraryDalvikExecutable.js +55 -17
  7. package/build/arbitraryJava.d.ts +31 -0
  8. package/build/arbitraryJava.js +532 -0
  9. package/build/arbitraryJavaScript.d.ts +3 -0
  10. package/build/arbitraryJavaScript.js +263 -0
  11. package/build/arbitraryJavascript.d.ts +3 -0
  12. package/build/arbitraryJavascript.js +263 -0
  13. package/build/arbitraryZig.d.ts +3 -0
  14. package/build/arbitraryZig.js +240 -0
  15. package/build/arbitraryZipStream.d.ts +1 -1
  16. package/build/arrayParser.js +72 -13
  17. package/build/backsmali.d.ts +4 -3
  18. package/build/backsmali.js +26 -6
  19. package/build/bash.d.ts +89 -0
  20. package/build/bash.js +1 -0
  21. package/build/bashParser.d.ts +6 -0
  22. package/build/bashParser.js +335 -0
  23. package/build/bashParser.test.d.ts +1 -0
  24. package/build/bashParser.test.js +343 -0
  25. package/build/bashParserEdgeCases.test.d.ts +1 -0
  26. package/build/bashParserEdgeCases.test.js +117 -0
  27. package/build/dalvikBytecodeParser/addressConversion.d.ts +110 -0
  28. package/build/dalvikBytecodeParser/addressConversion.js +334 -0
  29. package/build/dalvikBytecodeParser/formatParsers.d.ts +7 -6
  30. package/build/dalvikBytecodeParser/formatParsers.js +13 -14
  31. package/build/dalvikBytecodeParser.d.ts +60 -31
  32. package/build/dalvikBytecodeParser.js +92 -35
  33. package/build/dalvikBytecodeParser.test-d.d.ts +1 -0
  34. package/build/dalvikBytecodeParser.test-d.js +268 -0
  35. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +9 -8
  36. package/build/dalvikBytecodeUnparser/formatUnparsers.js +13 -12
  37. package/build/dalvikBytecodeUnparser.d.ts +2 -2
  38. package/build/dalvikBytecodeUnparser.js +23 -23
  39. package/build/dalvikBytecodeUnparser.test.js +7 -7
  40. package/build/dalvikExecutable.d.ts +3 -3
  41. package/build/dalvikExecutable.test-d.d.ts +1 -0
  42. package/build/dalvikExecutable.test-d.js +59 -0
  43. package/build/dalvikExecutableParser/typedNumbers.d.ts +18 -0
  44. package/build/dalvikExecutableParser/typedNumbers.js +3 -0
  45. package/build/dalvikExecutableParser.d.ts +2 -1
  46. package/build/dalvikExecutableParser.js +96 -77
  47. package/build/dalvikExecutableParser.test.js +24 -3
  48. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +3 -0
  49. package/build/dalvikExecutableUnparser/poolScanners.d.ts +2 -2
  50. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +3 -3
  51. package/build/dalvikExecutableUnparser/sectionUnparsers.js +26 -11
  52. package/build/dalvikExecutableUnparser.d.ts +2 -2
  53. package/build/dalvikExecutableUnparser.test.js +2 -1
  54. package/build/disjunctionParser.d.ts +5 -3
  55. package/build/disjunctionParser.js +79 -17
  56. package/build/disjunctionParser.test-d.d.ts +1 -0
  57. package/build/disjunctionParser.test-d.js +72 -0
  58. package/build/elementSwitchParser.d.ts +4 -0
  59. package/build/{exactElementSwitchParser.js → elementSwitchParser.js} +3 -4
  60. package/build/elementSwitchParser.test-d.d.ts +1 -0
  61. package/build/elementSwitchParser.test-d.js +44 -0
  62. package/build/exactSequenceParser.d.ts +4 -2
  63. package/build/exactSequenceParser.test-d.d.ts +1 -0
  64. package/build/exactSequenceParser.test-d.js +36 -0
  65. package/build/fetchCid.js +2 -66
  66. package/build/index.d.ts +25 -2
  67. package/build/index.js +23 -1
  68. package/build/index.test.js +16 -1
  69. package/build/inputReader.d.ts +10 -0
  70. package/build/inputReader.js +36 -0
  71. package/build/java.d.ts +502 -0
  72. package/build/java.js +2 -0
  73. package/build/javaKeyStoreParser.js +14 -17
  74. package/build/javaParser.d.ts +51 -0
  75. package/build/javaParser.js +1538 -0
  76. package/build/javaParser.test.d.ts +1 -0
  77. package/build/javaParser.test.js +1287 -0
  78. package/build/javaScript.d.ts +35 -0
  79. package/build/javaScript.js +1 -0
  80. package/build/javaScriptParser.d.ts +9 -0
  81. package/build/javaScriptParser.js +34 -0
  82. package/build/javaScriptUnparser.d.ts +3 -0
  83. package/build/javaScriptUnparser.js +4 -0
  84. package/build/javaScriptUnparser.test.d.ts +1 -0
  85. package/build/javaScriptUnparser.test.js +24 -0
  86. package/build/javaUnparser.d.ts +2 -0
  87. package/build/javaUnparser.js +519 -0
  88. package/build/javaUnparser.test.d.ts +1 -0
  89. package/build/javaUnparser.test.js +24 -0
  90. package/build/javascript.d.ts +35 -0
  91. package/build/javascript.js +1 -0
  92. package/build/javascriptParser.d.ts +9 -0
  93. package/build/javascriptParser.js +34 -0
  94. package/build/javascriptUnparser.d.ts +3 -0
  95. package/build/javascriptUnparser.js +4 -0
  96. package/build/javascriptUnparser.test.d.ts +1 -0
  97. package/build/javascriptUnparser.test.js +24 -0
  98. package/build/jsonParser.js +2 -12
  99. package/build/lazyMessageError.d.ts +3 -0
  100. package/build/lookaheadParser.js +60 -3
  101. package/build/negativeLookaheadParser.js +70 -11
  102. package/build/nonEmptyArrayParser.js +72 -13
  103. package/build/objectParser.d.ts +12 -0
  104. package/build/objectParser.js +31 -0
  105. package/build/objectParser.test-d.d.ts +1 -0
  106. package/build/objectParser.test-d.js +112 -0
  107. package/build/objectParser.test.d.ts +1 -0
  108. package/build/objectParser.test.js +55 -0
  109. package/build/optionalParser.js +69 -10
  110. package/build/parser.d.ts +4 -0
  111. package/build/parser.js +3 -1
  112. package/build/parser.test.js +114 -1
  113. package/build/parserConsumedSequenceParser.js +66 -7
  114. package/build/parserContext.d.ts +6 -0
  115. package/build/parserContext.js +20 -11
  116. package/build/parserError.d.ts +119 -27
  117. package/build/parserError.js +16 -8
  118. package/build/regexpParser.d.ts +2 -0
  119. package/build/regexpParser.js +101 -0
  120. package/build/regexpParser.test.d.ts +1 -0
  121. package/build/regexpParser.test.js +114 -0
  122. package/build/regularExpression.d.ts +63 -0
  123. package/build/regularExpression.js +1 -0
  124. package/build/regularExpressionParser.d.ts +3 -0
  125. package/build/regularExpressionParser.js +600 -0
  126. package/build/regularExpressionParser.test.d.ts +1 -0
  127. package/build/regularExpressionParser.test.js +89 -0
  128. package/build/separatedArrayParser.js +73 -14
  129. package/build/separatedNonEmptyArrayParser.js +73 -14
  130. package/build/sliceBoundedParser.js +62 -5
  131. package/build/smaliParser.d.ts +7 -7
  132. package/build/smaliParser.js +185 -268
  133. package/build/smaliParser.test.js +58 -0
  134. package/build/stringEscapes.d.ts +5 -0
  135. package/build/stringEscapes.js +244 -0
  136. package/build/symbolicExpression.d.ts +29 -0
  137. package/build/symbolicExpression.js +1 -0
  138. package/build/symbolicExpressionParser.d.ts +4 -0
  139. package/build/symbolicExpressionParser.js +123 -0
  140. package/build/symbolicExpressionParser.test.d.ts +1 -0
  141. package/build/symbolicExpressionParser.test.js +289 -0
  142. package/build/terminatedArrayParser.js +113 -38
  143. package/build/terminatedArrayParser.test.js +4 -2
  144. package/build/tupleParser.d.ts +7 -15
  145. package/build/tupleParser.js +1 -0
  146. package/build/unionParser.d.ts +5 -3
  147. package/build/unionParser.js +7 -2
  148. package/build/unionParser.test-d.d.ts +1 -0
  149. package/build/unionParser.test-d.js +72 -0
  150. package/build/unionParser.test.js +10 -11
  151. package/build/zig.d.ts +280 -0
  152. package/build/zig.js +2 -0
  153. package/build/zigParser.d.ts +3 -0
  154. package/build/zigParser.js +1119 -0
  155. package/build/zigParser.test.d.ts +1 -0
  156. package/build/zigParser.test.js +1590 -0
  157. package/build/zigUnparser.d.ts +2 -0
  158. package/build/zigUnparser.js +460 -0
  159. package/build/zigUnparser.test.d.ts +1 -0
  160. package/build/zigUnparser.test.js +24 -0
  161. package/build/zipParser.js +19 -32
  162. package/build/zipUnparser.js +19 -7
  163. package/build/zipUnparser.test.js +1 -1
  164. package/node_modules-@types/s-expression/index.d.ts +5 -0
  165. package/package.json +25 -6
  166. package/src/androidPackageParser.ts +33 -60
  167. package/src/arbitraryDalvikBytecode.ts +39 -31
  168. package/src/arbitraryDalvikExecutable.ts +65 -20
  169. package/src/arbitraryJava.ts +804 -0
  170. package/src/arbitraryJavaScript.ts +410 -0
  171. package/src/arbitraryZig.ts +380 -0
  172. package/src/arrayParser.ts +1 -3
  173. package/src/backsmali.ts +35 -4
  174. package/src/bash.ts +127 -0
  175. package/src/bashParser.test.ts +590 -0
  176. package/src/bashParser.ts +498 -0
  177. package/src/dalvikBytecodeParser/addressConversion.ts +496 -0
  178. package/src/dalvikBytecodeParser/formatParsers.ts +19 -29
  179. package/src/dalvikBytecodeParser.test-d.ts +310 -0
  180. package/src/dalvikBytecodeParser.ts +194 -69
  181. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +27 -26
  182. package/src/dalvikBytecodeUnparser.test.ts +7 -7
  183. package/src/dalvikBytecodeUnparser.ts +31 -30
  184. package/src/dalvikExecutable.test-d.ts +132 -0
  185. package/src/dalvikExecutable.ts +3 -3
  186. package/src/dalvikExecutableParser/typedNumbers.ts +11 -0
  187. package/src/dalvikExecutableParser.test.ts +37 -3
  188. package/src/dalvikExecutableParser.test.ts.md +163 -2
  189. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  190. package/src/dalvikExecutableParser.ts +121 -139
  191. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +4 -0
  192. package/src/dalvikExecutableUnparser/poolScanners.ts +6 -6
  193. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +38 -14
  194. package/src/dalvikExecutableUnparser.test.ts +3 -2
  195. package/src/dalvikExecutableUnparser.ts +4 -4
  196. package/src/disjunctionParser.test-d.ts +105 -0
  197. package/src/disjunctionParser.ts +18 -15
  198. package/src/elementSwitchParser.test-d.ts +74 -0
  199. package/src/elementSwitchParser.ts +51 -0
  200. package/src/exactSequenceParser.test-d.ts +43 -0
  201. package/src/exactSequenceParser.ts +13 -8
  202. package/src/fetchCid.ts +2 -76
  203. package/src/index.test.ts +22 -1
  204. package/src/index.ts +119 -2
  205. package/src/inputReader.ts +53 -0
  206. package/src/java.ts +708 -0
  207. package/src/javaKeyStoreParser.ts +18 -32
  208. package/src/javaParser.test.ts +1592 -0
  209. package/src/javaParser.ts +2640 -0
  210. package/src/javaScript.ts +36 -0
  211. package/src/javaScriptParser.ts +57 -0
  212. package/src/javaScriptUnparser.test.ts +37 -0
  213. package/src/javaScriptUnparser.ts +7 -0
  214. package/src/javaUnparser.test.ts +37 -0
  215. package/src/javaUnparser.ts +640 -0
  216. package/src/jsonParser.ts +6 -27
  217. package/src/lookaheadParser.ts +2 -6
  218. package/src/negativeLookaheadParser.ts +1 -3
  219. package/src/nonEmptyArrayParser.ts +1 -3
  220. package/src/objectParser.test-d.ts +152 -0
  221. package/src/objectParser.test.ts +71 -0
  222. package/src/objectParser.ts +69 -0
  223. package/src/optionalParser.ts +1 -3
  224. package/src/parser.test.ts +151 -4
  225. package/src/parser.ts +11 -1
  226. package/src/parserConsumedSequenceParser.ts +2 -4
  227. package/src/parserContext.ts +26 -11
  228. package/src/parserError.ts +17 -3
  229. package/src/regexpParser.test.ts +264 -0
  230. package/src/regexpParser.ts +126 -0
  231. package/src/regularExpression.ts +24 -0
  232. package/src/regularExpressionParser.test.ts +102 -0
  233. package/src/regularExpressionParser.ts +920 -0
  234. package/src/separatedArrayParser.ts +1 -3
  235. package/src/separatedNonEmptyArrayParser.ts +1 -3
  236. package/src/sliceBoundedParser.test.ts +2 -2
  237. package/src/sliceBoundedParser.ts +15 -19
  238. package/src/smaliParser.test.ts +64 -0
  239. package/src/smaliParser.test.ts.md +12 -12
  240. package/src/smaliParser.test.ts.snap +0 -0
  241. package/src/smaliParser.ts +246 -534
  242. package/src/stringEscapes.ts +253 -0
  243. package/src/symbolicExpression.ts +17 -0
  244. package/src/symbolicExpressionParser.test.ts +466 -0
  245. package/src/symbolicExpressionParser.ts +190 -0
  246. package/src/terminatedArrayParser.test.ts +9 -6
  247. package/src/terminatedArrayParser.ts +25 -29
  248. package/src/tupleParser.ts +21 -18
  249. package/src/unionParser.test-d.ts +105 -0
  250. package/src/unionParser.test.ts +18 -17
  251. package/src/unionParser.ts +28 -16
  252. package/src/zig.ts +411 -0
  253. package/src/zigParser.test.ts +1693 -0
  254. package/src/zigParser.ts +1745 -0
  255. package/src/zigUnparser.test.ts +37 -0
  256. package/src/zigUnparser.ts +615 -0
  257. package/src/zipParser.ts +20 -56
  258. package/src/zipUnparser.test.ts +1 -1
  259. package/src/zipUnparser.ts +22 -7
  260. package/tsconfig.json +2 -2
  261. package/build/exactElementSwitchParser.d.ts +0 -3
  262. package/src/exactElementSwitchParser.ts +0 -41
@@ -0,0 +1,24 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npx tsc:*)",
5
+ "Bash(npx ava:*)",
6
+ "Bash(npx tsd:*)",
7
+ "Bash(git show:*)",
8
+ "Bash(node -e:*)",
9
+ "WebFetch(domain:registry.npmjs.org)",
10
+ "WebFetch(domain:raw.githubusercontent.com)",
11
+ "WebFetch(domain:github.com)",
12
+ "Bash(git clone:*)",
13
+ "WebFetch(domain:source.android.com)",
14
+ "Bash(baksmali help:*)",
15
+ "Bash(yarn ava:*)",
16
+ "Bash(yarn tsc:*)",
17
+ "Bash(SEED=42 yarn ava:*)",
18
+ "Bash(SEED=12345 yarn ava:*)",
19
+ "Bash(SEED=999999 yarn ava:*)"
20
+ ],
21
+ "deny": [],
22
+ "ask": []
23
+ }
24
+ }
@@ -38,6 +38,7 @@ jobs:
38
38
  yarn-cache-${{ runner.os }}-
39
39
  - run: yarn install --immutable
40
40
  - run: yarn build
41
+ - run: yarn tsd
41
42
  - run: yarn test
42
43
  - name: Generate coverage report
43
44
  if: matrix.node-version == 24
@@ -11,6 +11,7 @@ import { createExactSequenceParser } from './exactSequenceParser.js';
11
11
  import { createSliceBoundedParser } from './sliceBoundedParser.js';
12
12
  import { createDisjunctionParser } from './disjunctionParser.js';
13
13
  import { createExactElementParser } from './exactElementParser.js';
14
+ import { createObjectParser } from './objectParser.js';
14
15
  import { createParserConsumedSequenceParser } from './parserConsumedSequenceParser.js';
15
16
  // https://source.android.com/docs/security/features/androidPackagesigning/v2#androidPackage-signing-block
16
17
  const uint32LEParser = promiseCompose(createFixedLengthSequenceParser(4), array => Buffer.from(array).readUInt32LE());
@@ -30,16 +31,20 @@ const createAndroidPackageSigningBlockZeroPaddingPairInnerParser = (length) => {
30
31
  return androidPackageSigningBlockZeroPaddingPairInnerParser;
31
32
  };
32
33
  const createAndroidPackageSigningBlockSignatureV2PairInnerParser = (length) => {
33
- const androidPackageSigningBlockSignatureV2PairInnerParser = promiseCompose(createTupleParser([
34
- createExactSequenceParser(Buffer.from('1a870971', 'hex')),
35
- androidPackageSignatureV2SignersParser,
36
- ]), ([_magic, signers = []]) => ({ type: 'signatureV2', signers }));
34
+ const androidPackageSigningBlockSignatureV2PairInnerParser = createObjectParser({
35
+ type: 'signatureV2',
36
+ _magic: createExactSequenceParser(Buffer.from('1a870971', 'hex')),
37
+ signers: androidPackageSignatureV2SignersParser,
38
+ });
37
39
  return setParserName(androidPackageSigningBlockSignatureV2PairInnerParser, 'androidPackageSigningBlockSignatureV2PairInnerParser');
38
40
  };
39
- const createAndroidPackageSigningBlockGenericPairInnerParser = (length) => promiseCompose(createTupleParser([
40
- uint32LEParser,
41
- createFixedLengthSequenceParser(length - 4),
42
- ]), ([id, value]) => ({ type: 'generic', pair: { id, value } }));
41
+ const createAndroidPackageSigningBlockGenericPairInnerParser = (length) => createObjectParser({
42
+ type: 'generic',
43
+ pair: createObjectParser({
44
+ id: uint32LEParser,
45
+ value: createFixedLengthSequenceParser(length - 4),
46
+ }),
47
+ });
43
48
  const createAndroidPackageSigningBlockPairInnerParser = (length) => {
44
49
  const androidPackageSigningBlockPairInnerParser = promiseCompose(createTupleParser([
45
50
  parserContext => {
@@ -82,20 +87,20 @@ export const androidPackageSigningBlockParser = createUint64LengthPrefixedParser
82
87
  pairs: genericPairs,
83
88
  };
84
89
  }));
85
- const androidPackageSignatureV2DigestParser = createUint32LengthPrefixedParser(pairLength => promiseCompose(createTupleParser([
86
- uint32LEParser,
87
- createUint32LengthPrefixedParser(digestLength => createFixedLengthSequenceParser(digestLength)),
88
- ]), ([signatureAlgorithmId, digest]) => ({ signatureAlgorithmId, digest })));
90
+ const androidPackageSignatureV2DigestParser = createUint32LengthPrefixedParser(pairLength => createObjectParser({
91
+ signatureAlgorithmId: uint32LEParser,
92
+ digest: createUint32LengthPrefixedParser(digestLength => createFixedLengthSequenceParser(digestLength)),
93
+ }));
89
94
  const androidPackageSignatureV2DigestsParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2DigestParser);
90
95
  setParserName(androidPackageSignatureV2DigestsParser, 'androidPackageSignatureV2DigestsParser');
91
96
  const androidPackageSignatureV2CertificateParser = createUint32LengthPrefixedParser(certificateLength => createFixedLengthSequenceParser(certificateLength));
92
97
  setParserName(androidPackageSignatureV2CertificateParser, 'androidPackageSignatureV2CertificateParser');
93
98
  const androidPackageSignatureV2CertificatesParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2CertificateParser);
94
99
  setParserName(androidPackageSignatureV2CertificatesParser, 'androidPackageSignatureV2CertificatesParser');
95
- const androidPackageSignatureV2AdditionalAttributeParser = createUint32LengthPrefixedParser(pairLength => promiseCompose(createTupleParser([
96
- uint32LEParser,
97
- createFixedLengthSequenceParser(pairLength - 4),
98
- ]), ([id, value]) => ({ id, value })));
100
+ const androidPackageSignatureV2AdditionalAttributeParser = createUint32LengthPrefixedParser(pairLength => createObjectParser({
101
+ id: uint32LEParser,
102
+ value: createFixedLengthSequenceParser(pairLength - 4),
103
+ }));
99
104
  setParserName(androidPackageSignatureV2AdditionalAttributeParser, 'androidPackageSignatureV2AdditionalAttributeParser');
100
105
  const androidPackageSignatureV2AdditionalAttributesParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2AdditionalAttributeParser);
101
106
  setParserName(androidPackageSignatureV2AdditionalAttributesParser, 'androidPackageSignatureV2AdditionalAttributesParser');
@@ -111,26 +116,19 @@ const androidPackageSignatureV2SignedDataParser = createUint32LengthPrefixedSlic
111
116
  zeroPaddingLength: zeroPadding.length,
112
117
  })));
113
118
  setParserName(androidPackageSignatureV2SignedDataParser, 'androidPackageSignatureV2SignedDataParser');
114
- const androidPackageSignatureV2SignatureParser = createUint32LengthPrefixedParser(signatureLength => promiseCompose(createTupleParser([
115
- uint32LEParser,
116
- createUint32LengthPrefixedParser(signatureLength => createFixedLengthSequenceParser(signatureLength)),
117
- ]), ([signatureAlgorithmId, signature,]) => ({
118
- signatureAlgorithmId,
119
- signature,
120
- })));
119
+ const androidPackageSignatureV2SignatureParser = createUint32LengthPrefixedParser(signatureLength => createObjectParser({
120
+ signatureAlgorithmId: uint32LEParser,
121
+ signature: createUint32LengthPrefixedParser(signatureLength => createFixedLengthSequenceParser(signatureLength)),
122
+ }));
121
123
  const androidPackageSignatureV2SignaturesParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2SignatureParser);
122
124
  setParserName(androidPackageSignatureV2SignaturesParser, 'androidPackageSignatureV2SignaturesParser');
123
125
  const androidPackageSignatureV2PublicKeyParser = createUint32LengthPrefixedParser(publicKeyLength => createFixedLengthSequenceParser(publicKeyLength));
124
126
  setParserName(androidPackageSignatureV2PublicKeyParser, 'androidPackageSignatureV2PublicKeyParser');
125
- const androidPackageSignatureV2SignerParser = createUint32LengthPrefixedSliceBoundedParser(promiseCompose(createTupleParser([
126
- androidPackageSignatureV2SignedDataParser,
127
- androidPackageSignatureV2SignaturesParser,
128
- androidPackageSignatureV2PublicKeyParser,
129
- ]), ([signedData, signatures = [], publicKey,]) => ({
130
- signedData,
131
- signatures,
132
- publicKey,
133
- })));
127
+ const androidPackageSignatureV2SignerParser = createUint32LengthPrefixedSliceBoundedParser(createObjectParser({
128
+ signedData: androidPackageSignatureV2SignedDataParser,
129
+ signatures: androidPackageSignatureV2SignaturesParser,
130
+ publicKey: androidPackageSignatureV2PublicKeyParser,
131
+ }));
134
132
  setParserName(androidPackageSignatureV2SignerParser, 'androidPackageSignatureV2SignerParser');
135
133
  const androidPackageSignatureV2SignersParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2SignerParser);
136
134
  setParserName(androidPackageSignatureV2SignersParser, 'androidPackageSignatureV2SignersParser');
@@ -1,4 +1,4 @@
1
1
  import * as fc from 'fast-check';
2
- import { type DalvikBytecode, type DalvikBytecodeOperation } from './dalvikBytecodeParser.js';
3
- export declare const arbitraryDalvikBytecodeOperation: fc.Arbitrary<DalvikBytecodeOperation>;
4
- export declare const arbitraryDalvikBytecode: fc.Arbitrary<DalvikBytecode>;
2
+ import { type RawDalvikBytecode, type RawDalvikBytecodeOperation } from './dalvikBytecodeParser.js';
3
+ export declare const arbitraryRawDalvikBytecodeOperation: fc.Arbitrary<RawDalvikBytecodeOperation>;
4
+ export declare const arbitraryRawDalvikBytecode: fc.Arbitrary<RawDalvikBytecode>;
@@ -1,5 +1,5 @@
1
1
  import * as fc from 'fast-check';
2
- import { isoIndexIntoStringIds, isoIndexIntoTypeIds, isoIndexIntoMethodIds, isoIndexIntoFieldIds, isoIndexIntoPrototypeIds, } from './dalvikExecutableParser/typedNumbers.js';
2
+ import { isoIndexIntoStringIds, isoIndexIntoTypeIds, isoIndexIntoMethodIds, isoIndexIntoFieldIds, isoIndexIntoPrototypeIds, isoCodeUnit, } from './dalvikExecutableParser/typedNumbers.js';
3
3
  // Arbitrary generators for typed indexes
4
4
  const arbitraryIndexIntoStringIds = fc
5
5
  .nat({ max: 65535 })
@@ -26,10 +26,16 @@ const arbitraryByteValue = fc.integer({ min: -128, max: 127 }); // 8-bit signed
26
26
  const arbitraryShortValue = fc.integer({ min: -32768, max: 32767 }); // 16-bit signed
27
27
  const arbitraryIntValue = fc.integer({ min: -2147483648, max: 2147483647 }); // 32-bit signed
28
28
  const arbitraryLongValue = fc.bigInt({ min: -9223372036854775808n, max: 9223372036854775807n }); // 64-bit signed
29
- // Arbitrary branch offsets (relative)
30
- const arbitraryBranchOffset8 = fc.integer({ min: -128, max: 127 });
31
- const arbitraryBranchOffset16 = fc.integer({ min: -32768, max: 32767 });
32
- const arbitraryBranchOffset32 = fc.integer({ min: -2147483648, max: 2147483647 });
29
+ // Arbitrary branch offsets (relative) - wrapped as CodeUnit
30
+ const arbitraryBranchOffsetCodeUnit8 = fc
31
+ .integer({ min: -128, max: 127 })
32
+ .map(n => isoCodeUnit.wrap(n));
33
+ const arbitraryBranchOffsetCodeUnit16 = fc
34
+ .integer({ min: -32768, max: 32767 })
35
+ .map(n => isoCodeUnit.wrap(n));
36
+ const arbitraryBranchOffsetCodeUnit32 = fc
37
+ .integer({ min: -2147483648, max: 2147483647 })
38
+ .map(n => isoCodeUnit.wrap(n));
33
39
  // No-operation
34
40
  const arbitraryNop = fc.constant({
35
41
  operation: 'nop',
@@ -205,31 +211,31 @@ const arbitraryThrow = fc.record({
205
211
  // Goto operations
206
212
  const arbitraryGoto = fc.record({
207
213
  operation: fc.constant('goto'),
208
- branchOffset: arbitraryBranchOffset8,
214
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit8,
209
215
  });
210
216
  const arbitraryGoto16 = fc.record({
211
217
  operation: fc.constant('goto/16'),
212
- branchOffset: arbitraryBranchOffset16,
218
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
213
219
  });
214
220
  const arbitraryGoto32 = fc.record({
215
221
  operation: fc.constant('goto/32'),
216
- branchOffset: arbitraryBranchOffset32,
222
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit32,
217
223
  });
218
224
  // Switch operations
219
225
  const arbitraryPackedSwitch = fc.record({
220
226
  operation: fc.constant('packed-switch'),
221
227
  registers: fc.tuple(arbitraryRegister8),
222
- branchOffset: arbitraryBranchOffset32,
228
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit32,
223
229
  });
224
230
  const arbitrarySparseSwitch = fc.record({
225
231
  operation: fc.constant('sparse-switch'),
226
232
  registers: fc.tuple(arbitraryRegister8),
227
- branchOffset: arbitraryBranchOffset32,
233
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit32,
228
234
  });
229
235
  const arbitraryFillArrayData = fc.record({
230
236
  operation: fc.constant('fill-array-data'),
231
237
  registers: fc.tuple(arbitraryRegister8),
232
- branchOffset: arbitraryBranchOffset32,
238
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit32,
233
239
  });
234
240
  // Payload operations
235
241
  const arbitraryPackedSwitchPayload = fc
@@ -237,14 +243,14 @@ const arbitraryPackedSwitchPayload = fc
237
243
  .chain(size => fc.record({
238
244
  operation: fc.constant('packed-switch-payload'),
239
245
  value: arbitraryIntValue,
240
- branchOffsets: fc.array(arbitraryBranchOffset32, { minLength: size, maxLength: size }),
246
+ branchOffsetsCodeUnit: fc.array(arbitraryBranchOffsetCodeUnit32, { minLength: size, maxLength: size }),
241
247
  }));
242
248
  const arbitrarySparseSwitchPayload = fc
243
249
  .nat({ max: 20 })
244
250
  .chain(size => fc.record({
245
251
  operation: fc.constant('sparse-switch-payload'),
246
252
  keys: fc.array(arbitraryIntValue, { minLength: size, maxLength: size }),
247
- branchOffsets: fc.array(arbitraryBranchOffset32, { minLength: size, maxLength: size }),
253
+ branchOffsetsCodeUnit: fc.array(arbitraryBranchOffsetCodeUnit32, { minLength: size, maxLength: size }),
248
254
  }));
249
255
  const arbitraryFillArrayDataPayload = fc
250
256
  .record({
@@ -262,63 +268,63 @@ const arbitraryFillArrayDataPayload = fc
262
268
  const arbitraryIfEqual = fc.record({
263
269
  operation: fc.constant('if-eq'),
264
270
  registers: fc.tuple(arbitraryRegister4, arbitraryRegister4).map(([a, b]) => [a, b].sort((x, y) => x - y)),
265
- branchOffset: arbitraryBranchOffset16,
271
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
266
272
  });
267
273
  const arbitraryIfNotEqual = fc.record({
268
274
  operation: fc.constant('if-ne'),
269
275
  registers: fc.tuple(arbitraryRegister4, arbitraryRegister4).map(([a, b]) => [a, b].sort((x, y) => x - y)),
270
- branchOffset: arbitraryBranchOffset16,
276
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
271
277
  });
272
278
  const arbitraryIfLessThan = fc.record({
273
279
  operation: fc.constant('if-lt'),
274
280
  registers: fc.tuple(arbitraryRegister4, arbitraryRegister4),
275
- branchOffset: arbitraryBranchOffset16,
281
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
276
282
  });
277
283
  const arbitraryIfGreaterThanOrEqualTo = fc.record({
278
284
  operation: fc.constant('if-ge'),
279
285
  registers: fc.tuple(arbitraryRegister4, arbitraryRegister4),
280
- branchOffset: arbitraryBranchOffset16,
286
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
281
287
  });
282
288
  const arbitraryIfGreaterThan = fc.record({
283
289
  operation: fc.constant('if-gt'),
284
290
  registers: fc.tuple(arbitraryRegister4, arbitraryRegister4),
285
- branchOffset: arbitraryBranchOffset16,
291
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
286
292
  });
287
293
  const arbitraryIfLessThanOrEqualTo = fc.record({
288
294
  operation: fc.constant('if-le'),
289
295
  registers: fc.tuple(arbitraryRegister4, arbitraryRegister4),
290
- branchOffset: arbitraryBranchOffset16,
296
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
291
297
  });
292
298
  // If-test-zero operations (Format 21t)
293
299
  const arbitraryIfEqualZero = fc.record({
294
300
  operation: fc.constant('if-eqz'),
295
301
  registers: fc.tuple(arbitraryRegister8),
296
- branchOffset: arbitraryBranchOffset16,
302
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
297
303
  });
298
304
  const arbitraryIfNotEqualZero = fc.record({
299
305
  operation: fc.constant('if-nez'),
300
306
  registers: fc.tuple(arbitraryRegister8),
301
- branchOffset: arbitraryBranchOffset16,
307
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
302
308
  });
303
309
  const arbitraryIfLessThanZero = fc.record({
304
310
  operation: fc.constant('if-ltz'),
305
311
  registers: fc.tuple(arbitraryRegister8),
306
- branchOffset: arbitraryBranchOffset16,
312
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
307
313
  });
308
314
  const arbitraryIfGreaterThanOrEqualToZero = fc.record({
309
315
  operation: fc.constant('if-gez'),
310
316
  registers: fc.tuple(arbitraryRegister8),
311
- branchOffset: arbitraryBranchOffset16,
317
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
312
318
  });
313
319
  const arbitraryIfGreaterThanZero = fc.record({
314
320
  operation: fc.constant('if-gtz'),
315
321
  registers: fc.tuple(arbitraryRegister8),
316
- branchOffset: arbitraryBranchOffset16,
322
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
317
323
  });
318
324
  const arbitraryIfLessThanOrEqualToZero = fc.record({
319
325
  operation: fc.constant('if-lez'),
320
326
  registers: fc.tuple(arbitraryRegister8),
321
- branchOffset: arbitraryBranchOffset16,
327
+ branchOffsetCodeUnit: arbitraryBranchOffsetCodeUnit16,
322
328
  });
323
329
  // Array element operations (Format 23x)
324
330
  const createArbitraryArrayElementOperation = (operation) => fc.record({
@@ -593,7 +599,7 @@ const arbitraryIntToByte = createArbitraryUnaryOperation('int-to-byte');
593
599
  const arbitraryIntToChar = createArbitraryUnaryOperation('int-to-char');
594
600
  const arbitraryIntToShort = createArbitraryUnaryOperation('int-to-short');
595
601
  // Combine all operations
596
- export const arbitraryDalvikBytecodeOperation = fc.oneof(arbitraryNop,
602
+ export const arbitraryRawDalvikBytecodeOperation = fc.oneof(arbitraryNop,
597
603
  // Move operations
598
604
  arbitraryMove, arbitraryMoveWide, arbitraryMoveObject, arbitraryMoveFrom16, arbitraryMoveWideFrom16, arbitraryMoveObjectFrom16, arbitraryMoveWide16, arbitraryMoveResult, arbitraryMoveResultWide, arbitraryMoveResultObject, arbitraryMoveException,
599
605
  // Return operations
@@ -637,4 +643,4 @@ arbitraryAddIntLiteral16, arbitraryReverseSubtractIntLiteral16, arbitraryMultipl
637
643
  // Unary operations
638
644
  arbitraryNegateInt, arbitraryNotInt, arbitraryNegateLong, arbitraryNotLong, arbitraryNegateFloat, arbitraryNegateDouble, arbitraryIntToLong, arbitraryIntToFloat, arbitraryIntToDouble, arbitraryLongToInt, arbitraryLongToFloat, arbitraryLongToDouble, arbitraryFloatToInt, arbitraryFloatToLong, arbitraryFloatToDouble, arbitraryDoubleToInt, arbitraryDoubleToLong, arbitraryDoubleToFloat, arbitraryIntToByte, arbitraryIntToChar, arbitraryIntToShort);
639
645
  // Arbitrary for complete Dalvik bytecode (array of operations)
640
- export const arbitraryDalvikBytecode = fc.array(arbitraryDalvikBytecodeOperation, { minLength: 0, maxLength: 100 });
646
+ export const arbitraryRawDalvikBytecode = fc.array(arbitraryRawDalvikBytecodeOperation, { minLength: 0, maxLength: 100 });
@@ -172,32 +172,70 @@ const arbitraryDalvikExecutableDebugInfo = fc.record({
172
172
  parameterNames: fc.array(fc.option(arbitraryJavaIdentifier, { nil: undefined }), { maxLength: 5 }),
173
173
  bytecode: fc.array(arbitraryDalvikExecutableDebugByteCodeValue, { maxLength: 10 }),
174
174
  });
175
- const arbitraryDalvikExecutableEncodedTypeAddressPair = fc.record({
176
- type: arbitraryDalvikClassName,
177
- address: fc.nat({ max: 65535 }),
178
- });
179
- const arbitraryDalvikExecutableEncodedCatchHandler = fc.record({
180
- handlers: fc.array(arbitraryDalvikExecutableEncodedTypeAddressPair, { maxLength: 3 }),
181
- catchAllAddress: fc.option(fc.nat({ max: 65535 }), { nil: undefined }),
182
- }).filter(handler => {
183
- // A handler must have at least one typed handler OR a catch-all address
184
- return handler.handlers.length > 0 || handler.catchAllAddress !== undefined;
185
- });
186
- const arbitraryDalvikExecutableTry = fc.record({
187
- startAddress: fc.nat({ max: 65535 }),
188
- instructionCount: fc.nat({ max: 255 }),
189
- handler: arbitraryDalvikExecutableEncodedCatchHandler,
190
- });
175
+ // Factory function to create arbitrary try blocks that are valid for given instruction count
176
+ // Since addresses are now instruction indices, they must be within [0, instructionCount]
177
+ function createArbitraryDalvikExecutableTry(instructionCount) {
178
+ // If no instructions, we can't have meaningful try blocks
179
+ if (instructionCount === 0) {
180
+ // Return a try block that covers the "after last instruction" position (index 0)
181
+ const arbitraryEmptyHandler = fc.record({
182
+ handlers: fc.constant([]),
183
+ catchAllInstructionIndex: fc.constant(0),
184
+ });
185
+ return fc.record({
186
+ startInstructionIndex: fc.constant(0),
187
+ instructionCount: fc.constant(0),
188
+ handler: arbitraryEmptyHandler,
189
+ });
190
+ }
191
+ // Addresses must be in range [0, instructionCount] (inclusive, since handler can point to end)
192
+ const maxAddress = instructionCount;
193
+ const arbitraryDalvikExecutableEncodedTypeAddressPair = fc.record({
194
+ type: arbitraryDalvikClassName,
195
+ handlerInstructionIndex: fc.nat({ max: maxAddress }),
196
+ });
197
+ const arbitraryDalvikExecutableEncodedCatchHandler = fc.record({
198
+ handlers: fc.array(arbitraryDalvikExecutableEncodedTypeAddressPair, { maxLength: 3 }),
199
+ catchAllInstructionIndex: fc.option(fc.nat({ max: maxAddress }), { nil: undefined }),
200
+ }).filter(handler => {
201
+ // A handler must have at least one typed handler OR a catch-all address
202
+ return handler.handlers.length > 0 || handler.catchAllInstructionIndex !== undefined;
203
+ });
204
+ // startInstructionIndex + instructionCount must not exceed instructionCount (the total)
205
+ return fc.tuple(fc.nat({ max: instructionCount }), fc.nat({ max: instructionCount })).chain(([start, count]) => {
206
+ // Adjust count so start + count <= instructionCount
207
+ const adjustedCount = Math.min(count, instructionCount - start);
208
+ return fc.record({
209
+ startInstructionIndex: fc.constant(start),
210
+ instructionCount: fc.constant(adjustedCount),
211
+ handler: arbitraryDalvikExecutableEncodedCatchHandler,
212
+ });
213
+ });
214
+ }
215
+ // Helper function to get instruction count from instructions
216
+ // This handles both array and non-array instruction types
217
+ function getInstructionCount(instructions) {
218
+ if (Array.isArray(instructions)) {
219
+ return instructions.length;
220
+ }
221
+ return 0; // Non-array instructions default to 0
222
+ }
191
223
  // Generic factory function for DalvikExecutable
192
224
  export const createArbitraryDalvikExecutable = (arbitraryInstructions) => {
193
225
  // Code generator using provided instructions arbitrary
226
+ // First generate instructions, then generate valid tries based on instruction count
194
227
  const arbitraryDalvikExecutableCode = fc.record({
195
228
  registersSize: fc.nat({ max: 65535 }),
196
229
  insSize: fc.nat({ max: 255 }),
197
230
  outsSize: fc.nat({ max: 255 }),
198
231
  debugInfo: fc.option(arbitraryDalvikExecutableDebugInfo, { nil: undefined }),
199
232
  instructions: arbitraryInstructions,
200
- tries: fc.array(arbitraryDalvikExecutableTry, { maxLength: 2 }),
233
+ }).chain(partialCode => {
234
+ const instructionCount = getInstructionCount(partialCode.instructions);
235
+ return fc.array(createArbitraryDalvikExecutableTry(instructionCount), { maxLength: 2 }).map(tries => ({
236
+ ...partialCode,
237
+ tries,
238
+ }));
201
239
  });
202
240
  // Method with access and code
203
241
  const arbitraryDalvikExecutableMethodWithAccess = fc.record({
@@ -0,0 +1,31 @@
1
+ import * as fc from 'fast-check';
2
+ export declare const arbitraryJavaCompilationUnit: fc.Arbitrary<{
3
+ type: "CompilationUnit";
4
+ packageDeclaration: {
5
+ type: "PackageDeclaration";
6
+ annotations: {
7
+ type: "MarkerAnnotationExpr";
8
+ name: {
9
+ type: "Name";
10
+ identifier: string;
11
+ qualifier?: unknown;
12
+ };
13
+ }[];
14
+ name: {
15
+ type: "Name";
16
+ identifier: string;
17
+ qualifier?: unknown;
18
+ };
19
+ } | undefined;
20
+ imports: {
21
+ type: "ImportDeclaration";
22
+ isStatic: boolean;
23
+ isAsterisk: boolean;
24
+ name: {
25
+ type: "Name";
26
+ identifier: string;
27
+ qualifier?: unknown;
28
+ };
29
+ }[];
30
+ types: unknown[];
31
+ }>;