@futpib/parser 1.0.1 → 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 (304) 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} +6 -6
  7. package/build/androidPackageUnparser.d.ts +4 -0
  8. package/build/{apkUnparser.js → androidPackageUnparser.js} +23 -23
  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/arrayParser.test.js +3 -3
  13. package/build/backsmali.d.ts +1 -0
  14. package/build/backsmali.js +22 -0
  15. package/build/bsonParser.js +6 -2
  16. package/build/customInvariant.d.ts +1 -1
  17. package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
  18. package/build/dalvikBytecodeParser/formatParsers.js +169 -0
  19. package/build/dalvikBytecodeParser.d.ts +107 -0
  20. package/build/dalvikBytecodeParser.js +836 -0
  21. package/build/dalvikExecutable.d.ts +158 -0
  22. package/build/dalvikExecutable.js +20 -0
  23. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  24. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  25. package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
  26. package/build/dalvikExecutableParser/typeParsers.js +34 -0
  27. package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
  28. package/build/dalvikExecutableParser/typedNumbers.js +19 -0
  29. package/build/dalvikExecutableParser.d.ts +5 -0
  30. package/build/dalvikExecutableParser.js +1439 -0
  31. package/build/dalvikExecutableParser.test.js +70 -0
  32. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
  33. package/build/debugLogInputParser.d.ts +4 -0
  34. package/build/debugLogInputParser.js +16 -0
  35. package/build/debugLogParser.js +14 -3
  36. package/build/disjunctionParser.d.ts +2 -1
  37. package/build/disjunctionParser.js +4 -2
  38. package/build/elementTerminatedArrayParser.d.ts +3 -0
  39. package/build/elementTerminatedArrayParser.js +18 -0
  40. package/build/elementTerminatedArrayParser.test.js +52 -0
  41. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  42. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  43. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  44. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  45. package/build/elementTerminatedSequenceParser.js +27 -0
  46. package/build/elementTerminatedSequenceParser.test.js +34 -0
  47. package/build/exactElementParser.js +10 -5
  48. package/build/exactSequenceParser.d.ts +2 -1
  49. package/build/exactSequenceParser.js +12 -2
  50. package/build/fetchCid.d.ts +1 -0
  51. package/build/fetchCid.js +107 -0
  52. package/build/fixedLengthSequenceParser.d.ts +1 -0
  53. package/build/fixedLengthSequenceParser.js +18 -1
  54. package/build/fixedLengthSequenceParser.test.js +41 -0
  55. package/build/hasExecutable.d.ts +1 -0
  56. package/build/hasExecutable.js +8 -0
  57. package/build/highResolutionTimer.d.ts +16 -0
  58. package/build/highResolutionTimer.js +42 -0
  59. package/build/inputReader.d.ts +11 -0
  60. package/build/inputReader.js +37 -0
  61. package/build/inputReader.test.js +165 -0
  62. package/build/inputReaderState.d.ts +10 -0
  63. package/build/inputReaderState.js +16 -0
  64. package/build/inspect.d.ts +1 -0
  65. package/build/inspect.js +7 -0
  66. package/build/javaKeyStoreParser.test.js +2 -2
  67. package/build/jsonParser.d.ts +2 -0
  68. package/build/jsonParser.js +11 -14
  69. package/build/leb128Parser.d.ts +7 -0
  70. package/build/leb128Parser.js +82 -0
  71. package/build/leb128Parser.test.js +107 -0
  72. package/build/lookaheadParser.d.ts +2 -0
  73. package/build/lookaheadParser.js +14 -0
  74. package/build/negativeLookaheadParser.js +21 -15
  75. package/build/negativeLookaheadParser.test.js +30 -0
  76. package/build/nonEmptyArrayParser.d.ts +2 -0
  77. package/build/nonEmptyArrayParser.js +32 -0
  78. package/build/nonEmptyArrayParser.test.js +16 -0
  79. package/build/parser.d.ts +10 -1
  80. package/build/parser.js +66 -31
  81. package/build/parser.test.js +79 -12
  82. package/build/parserAccessorParser.js +9 -1
  83. package/build/parserConsumedSequenceParser.js +20 -15
  84. package/build/parserContext.d.ts +14 -0
  85. package/build/parserContext.js +56 -27
  86. package/build/parserContext.test.js +27 -0
  87. package/build/parserCreatorCompose.d.ts +1 -0
  88. package/build/parserCreatorCompose.js +8 -2
  89. package/build/parserError.d.ts +6 -0
  90. package/build/parserError.js +6 -6
  91. package/build/parserInputCompanion.d.ts +15 -0
  92. package/build/parserInputCompanion.js +38 -0
  93. package/build/promiseCompose.d.ts +1 -1
  94. package/build/promiseCompose.js +12 -1
  95. package/build/promiseSettled.d.ts +1 -0
  96. package/build/promiseSettled.js +4 -0
  97. package/build/separatedArrayParser.d.ts +2 -0
  98. package/build/separatedArrayParser.js +39 -0
  99. package/build/separatedArrayParser.test.d.ts +1 -0
  100. package/build/separatedArrayParser.test.js +21 -0
  101. package/build/sequenceBuffer.d.ts +10 -0
  102. package/build/sequenceBuffer.js +54 -2
  103. package/build/sequenceBuffer.test.js +57 -0
  104. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  105. package/build/sequenceTerminatedSequenceParser.js +32 -0
  106. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  107. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  108. package/build/skipParser.d.ts +1 -1
  109. package/build/skipParser.js +4 -2
  110. package/build/skipToParser.d.ts +2 -0
  111. package/build/skipToParser.js +11 -0
  112. package/build/sliceBoundedParser.d.ts +1 -1
  113. package/build/sliceBoundedParser.js +7 -2
  114. package/build/sliceBoundedParser.test.js +35 -1
  115. package/build/smali.d.ts +1 -0
  116. package/build/smali.js +17 -0
  117. package/build/smaliParser.d.ts +12 -0
  118. package/build/smaliParser.js +656 -0
  119. package/build/smaliParser.test.d.ts +1 -0
  120. package/build/smaliParser.test.js +115 -0
  121. package/build/terminatedArrayParser.d.ts +3 -1
  122. package/build/terminatedArrayParser.js +79 -2
  123. package/build/terminatedArrayParser.test.d.ts +1 -0
  124. package/build/terminatedArrayParser.test.js +131 -0
  125. package/build/toAsyncIterable.d.ts +1 -0
  126. package/build/toAsyncIterable.js +7 -0
  127. package/build/toAsyncIterator.d.ts +1 -0
  128. package/build/toAsyncIterator.js +33 -0
  129. package/build/tupleParser.d.ts +4 -0
  130. package/build/tupleParser.js +1 -5
  131. package/build/unionParser.d.ts +2 -1
  132. package/build/unionParser.js +27 -12
  133. package/build/unionParser.test.d.ts +1 -0
  134. package/build/unionParser.test.js +60 -0
  135. package/build/zipParser.d.ts +7 -2
  136. package/build/zipParser.js +36 -12
  137. package/build/zipUnparser.d.ts +4 -1
  138. package/build/zipUnparser.js +55 -26
  139. package/build/zipUnparser.test.js +14 -14
  140. package/package.json +23 -7
  141. package/src/allSettledStream.test.ts +40 -0
  142. package/src/allSettledStream.ts +47 -15
  143. package/src/androidPackage.ts +48 -0
  144. package/src/{apkParser.test.ts → androidPackageParser.test.ts} +6 -7
  145. package/src/{apkParser.test.ts.md → androidPackageParser.test.ts.md} +4 -4
  146. package/src/androidPackageParser.test.ts.snap +0 -0
  147. package/src/androidPackageParser.ts +440 -0
  148. package/src/androidPackageUnparser.test.ts +36 -0
  149. package/src/androidPackageUnparser.ts +120 -0
  150. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  151. package/src/arrayParser.test.ts +3 -3
  152. package/src/backsmali.ts +30 -0
  153. package/src/bsonParser.ts +13 -2
  154. package/src/customInvariant.ts +1 -1
  155. package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
  156. package/src/dalvikBytecodeParser.ts +2074 -0
  157. package/src/dalvikExecutable.ts +220 -0
  158. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  159. package/src/dalvikExecutableParser/typeParsers.ts +65 -0
  160. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  161. package/src/dalvikExecutableParser.test.ts +89 -0
  162. package/src/dalvikExecutableParser.test.ts.md +634 -0
  163. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  164. package/src/dalvikExecutableParser.ts +2768 -0
  165. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
  166. package/src/debugLogInputParser.ts +28 -0
  167. package/src/debugLogParser.ts +19 -3
  168. package/src/disjunctionParser.ts +10 -5
  169. package/src/elementTerminatedArrayParser.test.ts +99 -0
  170. package/src/elementTerminatedArrayParser.ts +31 -0
  171. package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
  172. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  173. package/src/elementTerminatedSequenceParser.test.ts +54 -0
  174. package/src/elementTerminatedSequenceParser.ts +43 -0
  175. package/src/exactElementParser.ts +17 -11
  176. package/src/exactSequenceParser.ts +23 -2
  177. package/src/fetchCid.ts +125 -0
  178. package/src/fixedLengthSequenceParser.test.ts +77 -0
  179. package/src/fixedLengthSequenceParser.ts +28 -1
  180. package/src/hasExecutable.ts +11 -0
  181. package/src/highResolutionTimer.ts +49 -0
  182. package/src/inputReader.test.ts +209 -0
  183. package/src/inputReader.ts +75 -0
  184. package/src/inputReaderState.ts +33 -0
  185. package/src/inspect.ts +9 -0
  186. package/src/javaKeyStoreParser.test.ts +2 -3
  187. package/src/jsonParser.ts +13 -25
  188. package/src/leb128Parser.test.ts +171 -0
  189. package/src/leb128Parser.ts +125 -0
  190. package/src/lookaheadParser.ts +19 -0
  191. package/src/negativeLookaheadParser.test.ts +53 -0
  192. package/src/negativeLookaheadParser.ts +26 -14
  193. package/src/nonEmptyArrayParser.test.ts +20 -0
  194. package/src/nonEmptyArrayParser.ts +44 -0
  195. package/src/optionalParser.ts +1 -0
  196. package/src/parser.test.ts +131 -12
  197. package/src/parser.test.ts.md +21 -21
  198. package/src/parser.test.ts.snap +0 -0
  199. package/src/parser.ts +149 -45
  200. package/src/parserAccessorParser.ts +12 -2
  201. package/src/parserConsumedSequenceParser.ts +25 -16
  202. package/src/parserContext.test.ts +31 -0
  203. package/src/parserContext.ts +109 -37
  204. package/src/parserCreatorCompose.ts +20 -2
  205. package/src/parserError.ts +9 -6
  206. package/src/parserInputCompanion.ts +55 -0
  207. package/src/promiseCompose.ts +17 -3
  208. package/src/promiseSettled.ts +6 -0
  209. package/src/separatedArrayParser.test.ts +34 -0
  210. package/src/separatedArrayParser.ts +55 -0
  211. package/src/sequenceBuffer.test.ts +70 -0
  212. package/src/sequenceBuffer.ts +88 -2
  213. package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
  214. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  215. package/src/skipParser.ts +7 -5
  216. package/src/skipToParser.ts +16 -0
  217. package/src/sliceBoundedParser.test.ts +43 -1
  218. package/src/sliceBoundedParser.ts +19 -1
  219. package/src/smali.ts +24 -0
  220. package/src/smaliParser.test.ts +132 -0
  221. package/src/smaliParser.test.ts.md +2320 -0
  222. package/src/smaliParser.test.ts.snap +0 -0
  223. package/src/smaliParser.ts +1166 -0
  224. package/src/terminatedArrayParser.test.ts +258 -0
  225. package/src/terminatedArrayParser.ts +108 -3
  226. package/src/toAsyncIterable.ts +7 -0
  227. package/src/toAsyncIterator.ts +48 -0
  228. package/src/tupleParser.ts +8 -5
  229. package/src/unionParser.test.ts +79 -0
  230. package/src/unionParser.ts +44 -16
  231. package/src/zipParser.ts +77 -18
  232. package/src/zipUnparser.test.ts +18 -18
  233. package/src/zipUnparser.ts +88 -27
  234. package/build/apk.d.ts +0 -39
  235. package/build/apkParser.d.ts +0 -16
  236. package/build/apkParser.js +0 -164
  237. package/build/apkUnparser.d.ts +0 -4
  238. package/build/apkUnparser.test.js +0 -26
  239. package/build/arbitraryDosDate.d.ts +0 -2
  240. package/build/arbitraryDosDate.js +0 -8
  241. package/build/arbitraryZipEntry.d.ts +0 -3
  242. package/build/arbitraryZipEntry.js +0 -26
  243. package/build/createDisjunctionParser.d.ts +0 -2
  244. package/build/createDisjunctionParser.js +0 -47
  245. package/build/createExactParser.d.ts +0 -2
  246. package/build/createExactParser.js +0 -12
  247. package/build/createSequentialUnionParser.d.ts +0 -2
  248. package/build/createSequentialUnionParser.js +0 -69
  249. package/build/fixedLengthChunkParser.d.ts +0 -2
  250. package/build/fixedLengthChunkParser.js +0 -12
  251. package/build/fixedLengthParser.d.ts +0 -2
  252. package/build/fixedLengthParser.js +0 -12
  253. package/build/inputChunkBuffer.d.ts +0 -15
  254. package/build/inputChunkBuffer.js +0 -40
  255. package/build/inputChunkBuffer.test.js +0 -34
  256. package/build/inputCompanion.d.ts +0 -18
  257. package/build/inputCompanion.js +0 -28
  258. package/build/invariantDefined.d.ts +0 -1
  259. package/build/invariantDefined.js +0 -5
  260. package/build/invariantIdentity.d.ts +0 -3
  261. package/build/invariantIdentity.js +0 -5
  262. package/build/javaKeystoreParser.d.ts +0 -2
  263. package/build/javaKeystoreParser.js +0 -7
  264. package/build/jsonParser2.d.ts +0 -3
  265. package/build/jsonParser2.js +0 -52
  266. package/build/jsonParser2.test.js +0 -22
  267. package/build/negativeLookahead.d.ts +0 -2
  268. package/build/negativeLookahead.js +0 -18
  269. package/build/parserCompose.d.ts +0 -3
  270. package/build/parserCompose.js +0 -7
  271. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  272. package/build/parserImplementationInvariantInvariant.js +0 -15
  273. package/build/parserInvariant.d.ts +0 -4
  274. package/build/parserInvariant.js +0 -11
  275. package/build/promiseFish.d.ts +0 -1
  276. package/build/promiseFish.js +0 -3
  277. package/build/sequenceParser.d.ts +0 -3
  278. package/build/sequenceParser.js +0 -10
  279. package/build/terminatedSequenceParser.d.ts +0 -2
  280. package/build/terminatedSequenceParser.js +0 -24
  281. package/build/unparserInputCompanion.d.ts +0 -15
  282. package/build/unparserInputCompanion.js +0 -13
  283. package/build/zipEntry.d.ts +0 -28
  284. package/build/zipFile.d.ts +0 -32
  285. package/build/zipFileEntry.d.ts +0 -6
  286. package/src/apk.ts +0 -48
  287. package/src/apkParser.test.ts.snap +0 -0
  288. package/src/apkParser.ts +0 -392
  289. package/src/apkUnparser.test.ts +0 -37
  290. package/src/apkUnparser.ts +0 -120
  291. package/src/invariantDefined.ts +0 -6
  292. package/src/invariantIdentity.ts +0 -8
  293. /package/build/{apk.js → androidPackage.js} +0 -0
  294. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  295. /package/build/{apkUnparser.test.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  296. /package/build/{arbitraryDosPermissions.d.ts → dalvikExecutableParser.test.d.ts} +0 -0
  297. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  298. /package/build/{inputChunkBuffer.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  299. /package/build/{jsonParser2.test.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  300. /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceParser.test.d.ts} +0 -0
  301. /package/build/{parserParsingInvariant.js → fixedLengthSequenceParser.test.d.ts} +0 -0
  302. /package/build/{zipEntry.js → leb128Parser.test.d.ts} +0 -0
  303. /package/build/{zipFile.js → negativeLookaheadParser.test.d.ts} +0 -0
  304. /package/build/{zipFileEntry.js → nonEmptyArrayParser.test.d.ts} +0 -0
@@ -0,0 +1,346 @@
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 { baksmaliClass } from './backsmali.js';
8
+ import { smaliParser } from './smaliParser.js';
9
+ import { smaliClass } from './smali.js';
10
+
11
+ const hasBaksmaliPromise = hasExecutable('baksmali');
12
+ const hasSmaliPromise = hasExecutable('smali');
13
+
14
+ type ObjectPath = (string | symbol | number)[];
15
+
16
+ function objectWalk(object: unknown, f: (path: ObjectPath, value: unknown) => void, initialPath: ObjectPath = []) {
17
+ f(initialPath, object);
18
+
19
+ if (
20
+ !object
21
+ || typeof object !== 'object'
22
+ ) {
23
+ return;
24
+ }
25
+
26
+ if (Array.isArray(object)) {
27
+ for (const [ index, value ] of object.entries()) {
28
+ objectWalk(value, f, [ ...initialPath, index ]);
29
+ }
30
+ } else {
31
+ for (const [ key, value ] of Object.entries(object)) {
32
+ objectWalk(value, f, [ ...initialPath, key ]);
33
+ }
34
+ }
35
+ }
36
+
37
+ for (const [ dexCid, smaliFilePaths ] of [
38
+ [
39
+ 'bafkreibb4gsprc3fvmnyqx6obswvm7e7wngnfj64gz65ey72r7xgyzymt4',
40
+ [
41
+ 'pl/czak/minimal/MainActivity',
42
+ ],
43
+ ],
44
+ // [
45
+ // 'bafybeiebe27ylo53trgitu6fqfbmba43c4ivxj3nt4kumsilkucpbdxtqq',
46
+ // [
47
+ // 'd/m',
48
+ // ],
49
+ // ],
50
+ // [ 'bafybeiebe27ylo53trgitu6fqfbmba43c4ivxj3nt4kumsilkucpbdxtqq' ],
51
+ // [
52
+ // 'bafybeibbupm7uzhuq4pa674rb2amxsenbdaoijigmaf4onaodaql4mh7yy',
53
+ // [
54
+ // 'com/journeyapps/barcodescanner/CaptureActivity',
55
+ // ],
56
+ // ],
57
+ // [ 'bafybeicb3qajmwy6li7hche2nkucvytaxcyxhwhphmi73tgydjzmyoqoda' ],
58
+ ] as const) {
59
+ for (const smaliFilePath of smaliFilePaths) {
60
+ test.serial(
61
+ 'parse(dex) against parse(smali(dex))' + dexCid + ' ' + smaliFilePath,
62
+ async t => {
63
+ const hasBaksmali = await hasBaksmaliPromise;
64
+
65
+ if (!hasBaksmali) {
66
+ t.pass('skipping test because baksmali is not available');
67
+
68
+ return;
69
+ }
70
+
71
+ const dexStream = await fetchCid(dexCid);
72
+
73
+ const smali = await baksmaliClass(dexStream, smaliFilePath);
74
+
75
+ const classDefinitionFromSmali = await runParser(smaliParser, smali, stringParserInputCompanion, {
76
+ errorJoinMode: 'all',
77
+ });
78
+
79
+ const dexStream2 = await fetchCid(dexCid);
80
+
81
+ const executableFromDex = await runParser(dalvikExecutableParser, dexStream2, uint8ArrayParserInputCompanion, {
82
+ errorJoinMode: 'all',
83
+ });
84
+
85
+ const classDefinitionFromDex = executableFromDex.classDefinitions.find(classDefinition => classDefinition.class === classDefinitionFromSmali.class);
86
+
87
+ // console.log(smali);
88
+
89
+ // console.dir({
90
+ // classDefinitionFromDex,
91
+ // classDefinitionFromSmali,
92
+ // }, {
93
+ // depth: null,
94
+ // });
95
+
96
+ objectWalk(classDefinitionFromDex, (_path, value) => {
97
+ if (
98
+ value
99
+ && typeof value === 'object'
100
+ && 'debugInfo' in value
101
+ ) {
102
+ value.debugInfo = undefined;
103
+ }
104
+ });
105
+
106
+ t.deepEqual(
107
+ classDefinitionFromDex,
108
+ classDefinitionFromSmali,
109
+ );
110
+ },
111
+ );
112
+ }
113
+ }
114
+
115
+ const smali = `
116
+ .class public Lcom/journeyapps/barcodescanner/CaptureActivity;
117
+ .super Landroid/app/Activity;
118
+ .source "CaptureActivity.java"
119
+
120
+
121
+ # instance fields
122
+ .field private barcodeScannerView:Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;
123
+
124
+ .field private capture:Lcom/journeyapps/barcodescanner/CaptureManager;
125
+
126
+
127
+ # direct methods
128
+ .method public constructor <init>()V
129
+ .registers 1
130
+
131
+ .line 13
132
+ invoke-direct {p0}, Landroid/app/Activity;-><init>()V
133
+
134
+ return-void
135
+ .end method
136
+
137
+
138
+ # virtual methods
139
+ .method protected initializeContent()Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;
140
+ .registers 2
141
+
142
+ sget v0, Lcom/google/zxing/client/android/R$layout;->zxing_capture:I
143
+
144
+ .line 34
145
+ invoke-virtual {p0, v0}, Landroid/app/Activity;->setContentView(I)V
146
+
147
+ sget v0, Lcom/google/zxing/client/android/R$id;->zxing_barcode_scanner:I
148
+
149
+ .line 35
150
+ invoke-virtual {p0, v0}, Landroid/app/Activity;->findViewById(I)Landroid/view/View;
151
+
152
+ move-result-object v0
153
+
154
+ check-cast v0, Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;
155
+
156
+ return-object v0
157
+ .end method
158
+
159
+ .method protected onCreate(Landroid/os/Bundle;)V
160
+ .registers 4
161
+
162
+ .line 19
163
+ invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
164
+
165
+ .line 21
166
+ invoke-virtual {p0}, Lcom/journeyapps/barcodescanner/CaptureActivity;->initializeContent()Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;
167
+
168
+ move-result-object v0
169
+
170
+ iput-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->barcodeScannerView:Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;
171
+
172
+ .line 23
173
+ new-instance v0, Lcom/journeyapps/barcodescanner/CaptureManager;
174
+
175
+ iget-object v1, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->barcodeScannerView:Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;
176
+
177
+ invoke-direct {v0, p0, v1}, Lcom/journeyapps/barcodescanner/CaptureManager;-><init>(Landroid/app/Activity;Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;)V
178
+
179
+ iput-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->capture:Lcom/journeyapps/barcodescanner/CaptureManager;
180
+
181
+ .line 24
182
+ invoke-virtual {p0}, Landroid/app/Activity;->getIntent()Landroid/content/Intent;
183
+
184
+ move-result-object v1
185
+
186
+ invoke-virtual {v0, v1, p1}, Lcom/journeyapps/barcodescanner/CaptureManager;->initializeFromIntent(Landroid/content/Intent;Landroid/os/Bundle;)V
187
+
188
+ iget-object p1, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->capture:Lcom/journeyapps/barcodescanner/CaptureManager;
189
+
190
+ .line 25
191
+ invoke-virtual {p1}, Lcom/journeyapps/barcodescanner/CaptureManager;->decode()V
192
+
193
+ return-void
194
+ .end method
195
+
196
+ .method protected onDestroy()V
197
+ .registers 2
198
+
199
+ .line 52
200
+ invoke-super {p0}, Landroid/app/Activity;->onDestroy()V
201
+
202
+ iget-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->capture:Lcom/journeyapps/barcodescanner/CaptureManager;
203
+
204
+ .line 53
205
+ invoke-virtual {v0}, Lcom/journeyapps/barcodescanner/CaptureManager;->onDestroy()V
206
+
207
+ return-void
208
+ .end method
209
+
210
+ .method public onKeyDown(ILandroid/view/KeyEvent;)Z
211
+ .registers 4
212
+
213
+ iget-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->barcodeScannerView:Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;
214
+
215
+ .line 69
216
+ invoke-virtual {v0, p1, p2}, Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;->onKeyDown(ILandroid/view/KeyEvent;)Z
217
+
218
+ move-result v0
219
+
220
+ if-nez v0, :cond_11
221
+
222
+ invoke-super {p0, p1, p2}, Landroid/app/Activity;->onKeyDown(ILandroid/view/KeyEvent;)Z
223
+
224
+ move-result p1
225
+
226
+ if-eqz p1, :cond_f
227
+
228
+ goto :goto_11
229
+
230
+ :cond_f
231
+ const/4 p1, 0x0
232
+
233
+ goto :goto_12
234
+
235
+ :cond_11
236
+ :goto_11
237
+ const/4 p1, 0x1
238
+
239
+ :goto_12
240
+ return p1
241
+ .end method
242
+
243
+ .method protected onPause()V
244
+ .registers 2
245
+
246
+ .line 46
247
+ invoke-super {p0}, Landroid/app/Activity;->onPause()V
248
+
249
+ iget-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->capture:Lcom/journeyapps/barcodescanner/CaptureManager;
250
+
251
+ .line 47
252
+ invoke-virtual {v0}, Lcom/journeyapps/barcodescanner/CaptureManager;->onPause()V
253
+
254
+ return-void
255
+ .end method
256
+
257
+ .method public onRequestPermissionsResult(I[Ljava/lang/String;[I)V
258
+ .registers 5
259
+
260
+ iget-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->capture:Lcom/journeyapps/barcodescanner/CaptureManager;
261
+
262
+ .line 64
263
+ invoke-virtual {v0, p1, p2, p3}, Lcom/journeyapps/barcodescanner/CaptureManager;->onRequestPermissionsResult(I[Ljava/lang/String;[I)V
264
+
265
+ return-void
266
+ .end method
267
+
268
+ .method protected onResume()V
269
+ .registers 2
270
+
271
+ .line 40
272
+ invoke-super {p0}, Landroid/app/Activity;->onResume()V
273
+
274
+ iget-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->capture:Lcom/journeyapps/barcodescanner/CaptureManager;
275
+
276
+ .line 41
277
+ invoke-virtual {v0}, Lcom/journeyapps/barcodescanner/CaptureManager;->onResume()V
278
+
279
+ return-void
280
+ .end method
281
+
282
+ .method protected onSaveInstanceState(Landroid/os/Bundle;)V
283
+ .registers 3
284
+
285
+ .line 58
286
+ invoke-super {p0, p1}, Landroid/app/Activity;->onSaveInstanceState(Landroid/os/Bundle;)V
287
+
288
+ iget-object v0, p0, Lcom/journeyapps/barcodescanner/CaptureActivity;->capture:Lcom/journeyapps/barcodescanner/CaptureManager;
289
+
290
+ .line 59
291
+ invoke-virtual {v0, p1}, Lcom/journeyapps/barcodescanner/CaptureManager;->onSaveInstanceState(Landroid/os/Bundle;)V
292
+
293
+ return-void
294
+ .end method
295
+ `;
296
+
297
+ test.serial.skip(
298
+ 'parse(dex(smali)) againts parse(smali)',
299
+ async t => {
300
+ const hasSmali = await hasSmaliPromise;
301
+
302
+ if (!hasSmali) {
303
+ t.pass('skipping test because smali is not available');
304
+
305
+ return;
306
+ }
307
+
308
+ const dexBuffer = await smaliClass(async function* () {
309
+ yield smali;
310
+ }());
311
+
312
+ const classDefinitionFromSmali = await runParser(smaliParser, smali, stringParserInputCompanion, {
313
+ errorJoinMode: 'all',
314
+ });
315
+
316
+ const executableFromDex = await runParser(dalvikExecutableParser, dexBuffer, uint8ArrayParserInputCompanion, {
317
+ errorJoinMode: 'all',
318
+ });
319
+
320
+ const classDefinitionFromDex = executableFromDex.classDefinitions.find(classDefinition => classDefinition.class === classDefinitionFromSmali.class);
321
+
322
+ // console.log(smali);
323
+
324
+ console.dir({
325
+ classDefinitionFromDex,
326
+ classDefinitionFromSmali,
327
+ }, {
328
+ depth: null,
329
+ });
330
+
331
+ objectWalk(classDefinitionFromDex, (_path, value) => {
332
+ if (
333
+ value
334
+ && typeof value === 'object'
335
+ && 'debugInfo' in value
336
+ ) {
337
+ value.debugInfo = undefined;
338
+ }
339
+ });
340
+
341
+ t.deepEqual(
342
+ classDefinitionFromDex,
343
+ classDefinitionFromSmali,
344
+ );
345
+ },
346
+ );
@@ -0,0 +1,28 @@
1
+ import { type Parser } from './parser.js';
2
+
3
+ export const createDebugLogInputParser = <Sequence>({
4
+ maxLookahead = 8,
5
+ }: {
6
+ maxLookahead?: number;
7
+ } = {}): Parser<void, Sequence> => async parserContext => {
8
+ let lookahead = maxLookahead;
9
+
10
+ while (lookahead > 0) {
11
+ const sequence = await parserContext.peekSequence(0, lookahead);
12
+
13
+ if (!sequence) {
14
+ lookahead = lookahead - 1;
15
+ continue;
16
+ }
17
+
18
+ let prettySequence: unknown = sequence;
19
+
20
+ if (prettySequence instanceof Uint8Array) {
21
+ prettySequence = Buffer.from(prettySequence).toString('hex');
22
+ }
23
+
24
+ console.log('debugLogInput (position: %s): %s', parserContext.position, prettySequence);
25
+
26
+ break;
27
+ }
28
+ };
@@ -5,13 +5,29 @@ export const createDebugLogParser = <Output, Sequence>(
5
5
  ): Parser<Output, Sequence> => {
6
6
  let idCounter = 0;
7
7
 
8
+ function getLogParserName() {
9
+ const childParserName = getParserName(childParser);
10
+
11
+ if (childParserName !== 'anonymous') {
12
+ return childParserName;
13
+ }
14
+
15
+ const debugLogParserName = getParserName(debugLogParser);
16
+
17
+ if (!debugLogParserName.startsWith('debugLog(')) {
18
+ return debugLogParserName;
19
+ }
20
+
21
+ return 'anonymousDebugLogChild';
22
+ }
23
+
8
24
  const debugLogParser: typeof childParser = async parserContext => {
9
25
  const id = idCounter++;
10
26
  const initialPosition = parserContext.position;
11
27
 
12
28
  console.debug(
13
29
  '%s %s: started (position: %s)',
14
- getParserName(childParser),
30
+ getLogParserName(),
15
31
  id,
16
32
  initialPosition,
17
33
  );
@@ -21,7 +37,7 @@ export const createDebugLogParser = <Output, Sequence>(
21
37
 
22
38
  console.debug(
23
39
  '%s %s: finished (position: %s, consumed: %s): %o',
24
- getParserName(childParser),
40
+ getLogParserName(),
25
41
  id,
26
42
  parserContext.position,
27
43
  parserContext.position - initialPosition,
@@ -32,7 +48,7 @@ export const createDebugLogParser = <Output, Sequence>(
32
48
  } catch (error) {
33
49
  console.debug(
34
50
  '%s %s: failed (position: %s, consumed: %s): %o',
35
- getParserName(childParser),
51
+ getLogParserName(),
36
52
  id,
37
53
  parserContext.position,
38
54
  parserContext.position - initialPosition,
@@ -1,16 +1,19 @@
1
1
  import { getParserName, setParserName, type Parser } from './parser.js';
2
2
  import { ParserParsingFailedError } from './parserError.js';
3
3
  import { parserImplementationInvariant } from './parserImplementationInvariant.js';
4
+ import { promiseSettled } from './promiseSettled.js';
5
+ import { DeriveSequenceElement } from './sequence.js';
4
6
 
5
7
  export const createDisjunctionParser = <
6
8
  Output,
7
9
  Sequence,
10
+ Element = DeriveSequenceElement<Sequence>,
8
11
  >(
9
- childParsers: Array<Parser<any, Sequence, any>>,
10
- ): Parser<Output, Sequence, unknown> => {
12
+ childParsers: Array<Parser<any, Sequence, Element>>,
13
+ ): Parser<Output, Sequence, Element> => {
11
14
  parserImplementationInvariant(childParsers.length > 0, 'Disjunction parser must have at least one child parser.');
12
15
 
13
- const disjunctionParser: Parser<Output, Sequence, unknown> = async parserContext => {
16
+ const disjunctionParser: Parser<Output, Sequence, Element> = async parserContext => {
14
17
  const parserParsingFailedErrors: ParserParsingFailedError[] = [];
15
18
 
16
19
  for (const childParser of childParsers) {
@@ -18,7 +21,7 @@ export const createDisjunctionParser = <
18
21
  debugName: getParserName(childParser, 'anonymousDisjunctionChild'),
19
22
  });
20
23
 
21
- const [ childParserResult ] = await Promise.allSettled([ childParser(childParserContext) ]);
24
+ const childParserResult = await promiseSettled<Output>(childParser(childParserContext));
22
25
 
23
26
  if (childParserResult.status === 'fulfilled') {
24
27
  const successfulParserOutput = childParserResult.value;
@@ -29,6 +32,8 @@ export const createDisjunctionParser = <
29
32
  return successfulParserOutput;
30
33
  }
31
34
 
35
+ childParserContext.dispose();
36
+
32
37
  const error = childParserResult.reason;
33
38
 
34
39
  if (error instanceof ParserParsingFailedError) {
@@ -38,7 +43,7 @@ export const createDisjunctionParser = <
38
43
  }
39
44
  }
40
45
 
41
- parserContext.invariantJoin(
46
+ return parserContext.invariantJoin(
42
47
  false,
43
48
  parserParsingFailedErrors,
44
49
  'No disjunction child parser succeeded.',
@@ -0,0 +1,99 @@
1
+ import test from 'ava';
2
+ import * as fc from 'fast-check';
3
+ import { testProp } from '@fast-check/ava';
4
+ import { createTerminatedArrayParserNaive } from './terminatedArrayParser.js';
5
+ import { Parser, runParser } from './parser.js';
6
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
7
+ import { HighResolutionTotalTimer } from './highResolutionTimer.js';
8
+ import { createElementParser } from './elementParser.js';
9
+ import { createExactSequenceParser } from './exactSequenceParser.js';
10
+ import { createTupleParser } from './tupleParser.js';
11
+ import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
12
+ import { promiseCompose } from './promiseCompose.js';
13
+ import { createElementTerminatedArrayParserUnsafe } from './elementTerminatedArrayParser.js';
14
+
15
+ const naiveTotalTimer = new HighResolutionTotalTimer();
16
+ const elementTotalTimer = new HighResolutionTotalTimer();
17
+
18
+ testProp.serial(
19
+ 'elementTerminatedArrayParserUnsafe',
20
+ [
21
+ fc
22
+ .string({
23
+ minLength: 1,
24
+ })
25
+ .map(string => ({
26
+ string,
27
+ terminator: string.slice(-1)
28
+ }))
29
+ .filter(({ string, terminator }) => string.split(terminator).length === 2)
30
+ ],
31
+ async (t, { string, terminator }) => {
32
+ const terminatedArrayParserNaive = promiseCompose(
33
+ createTerminatedArrayParserNaive(
34
+ promiseCompose(
35
+ createTupleParser([
36
+ createNegativeLookaheadParser(createExactSequenceParser(terminator)),
37
+ createElementParser<string>(),
38
+ ]),
39
+ ([ _, element ]) => element,
40
+ ),
41
+ createExactSequenceParser(terminator),
42
+ ),
43
+ ([ characters ]) => characters,
44
+ );
45
+
46
+ const elementTerminatedArrayParserUnsafe = createElementTerminatedArrayParserUnsafe(
47
+ promiseCompose(
48
+ createTupleParser([
49
+ createNegativeLookaheadParser(createExactSequenceParser(terminator)),
50
+ createElementParser<string>(),
51
+ ]),
52
+ ([ _, element ]) => element,
53
+ ),
54
+ terminator,
55
+ );
56
+
57
+ const createTestWrapperParser = (innerParser: typeof elementTerminatedArrayParserUnsafe): Parser<{
58
+ string: string;
59
+ position: number;
60
+ }, string> => async parserContext => {
61
+ const characters = await innerParser(parserContext);
62
+
63
+ return {
64
+ string: characters.join(''),
65
+ nextPeek: await parserContext.peek(0),
66
+ position: parserContext.position,
67
+ };
68
+ };
69
+
70
+ const actualNaive = await naiveTotalTimer.measureAsync(() => runParser(
71
+ createTestWrapperParser(terminatedArrayParserNaive),
72
+ string,
73
+ stringParserInputCompanion,
74
+ ));
75
+
76
+ t.is(actualNaive.string.length, string.split(terminator)[0].length)
77
+
78
+ const actual = await elementTotalTimer.measureAsync(() => runParser(
79
+ createTestWrapperParser(elementTerminatedArrayParserUnsafe),
80
+ string,
81
+ stringParserInputCompanion,
82
+ ));
83
+
84
+ t.deepEqual(actual, actualNaive);
85
+ },
86
+ {
87
+ verbose: true,
88
+ },
89
+ );
90
+
91
+ test.serial(
92
+ 'elementTerminatedArrayParserUnsafe performance',
93
+ t => {
94
+ t.true(
95
+ elementTotalTimer.time * 4n < naiveTotalTimer.time,
96
+ `Naive: ${naiveTotalTimer.time / 1000000n}ms, Unsafe: ${elementTotalTimer.time / 1000000n}ms`,
97
+ );
98
+ },
99
+ );
@@ -0,0 +1,31 @@
1
+ import { getParserName, Parser, setParserName } from "./parser.js";
2
+ import { DeriveSequenceElement } from "./sequence.js";
3
+
4
+ export const createElementTerminatedArrayParserUnsafe = <ElementOutput, Sequence, Element = DeriveSequenceElement<Sequence>>(
5
+ elementParser: Parser<ElementOutput, Sequence>,
6
+ terminatorElement: Element,
7
+ ): Parser<ElementOutput[], Sequence> => {
8
+ const elementTerminatedArrayParserUnsafe: Parser<ElementOutput[], Sequence> = async parserContext => {
9
+ const elements: ElementOutput[] = [];
10
+
11
+ while (true) {
12
+ const inputElement = await parserContext.peek(0);
13
+
14
+ if (inputElement === terminatorElement) {
15
+ parserContext.skip(1);
16
+
17
+ break;
18
+ }
19
+
20
+ const element = await elementParser(parserContext);
21
+
22
+ elements.push(element);
23
+ }
24
+
25
+ return elements;
26
+ };
27
+
28
+ setParserName(elementTerminatedArrayParserUnsafe, `${getParserName(elementParser, 'anonymousElement')}*?${JSON.stringify(terminatorElement)}`);
29
+
30
+ return elementTerminatedArrayParserUnsafe;
31
+ };
@@ -0,0 +1,54 @@
1
+ import * as fc from 'fast-check';
2
+ import { testProp } from '@fast-check/ava';
3
+ import { Parser, runParser } from './parser.js';
4
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
5
+ import { createElementTerminatedSequenceArrayParser } from './elementTerminatedSequenceArrayParser.js';
6
+
7
+ testProp.serial(
8
+ 'elementTerminatedSequenceArrayParser',
9
+ [
10
+ fc
11
+ .string({
12
+ minLength: 1,
13
+ })
14
+ .map(string => ({
15
+ string,
16
+ terminator: string.slice(-1)
17
+ }))
18
+ .filter(({ string, terminator }) => string.split(terminator).length === 2)
19
+ ],
20
+ async (t, { string, terminator }) => {
21
+ const elementTerminatedSequenceArrayParser = createElementTerminatedSequenceArrayParser<string>(
22
+ terminator,
23
+ );
24
+
25
+ const createTestWrapperParser = (innerParser: typeof elementTerminatedSequenceArrayParser): Parser<{
26
+ strings: string[];
27
+ nextPeek: string | undefined;
28
+ position: number;
29
+ }, string> => async parserContext => {
30
+ const strings = await innerParser(parserContext);
31
+
32
+ return {
33
+ strings,
34
+ nextPeek: await parserContext.peek(0),
35
+ position: parserContext.position,
36
+ };
37
+ };
38
+
39
+ const actual = await runParser(
40
+ createTestWrapperParser(elementTerminatedSequenceArrayParser),
41
+ string,
42
+ stringParserInputCompanion,
43
+ );
44
+
45
+ t.deepEqual(actual, {
46
+ strings: [ string.split(terminator)[0] ],
47
+ nextPeek: undefined,
48
+ position: string.length,
49
+ });
50
+ },
51
+ {
52
+ verbose: true,
53
+ },
54
+ );