@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.
- package/.claude/settings.local.json +24 -0
- package/.github/workflows/main.yml +1 -0
- package/build/androidPackageParser.js +30 -32
- package/build/arbitraryDalvikBytecode.d.ts +3 -3
- package/build/arbitraryDalvikBytecode.js +33 -27
- package/build/arbitraryDalvikExecutable.js +55 -17
- package/build/arbitraryJava.d.ts +31 -0
- package/build/arbitraryJava.js +532 -0
- package/build/arbitraryJavaScript.d.ts +3 -0
- package/build/arbitraryJavaScript.js +263 -0
- package/build/arbitraryJavascript.d.ts +3 -0
- package/build/arbitraryJavascript.js +263 -0
- package/build/arbitraryZig.d.ts +3 -0
- package/build/arbitraryZig.js +240 -0
- package/build/arbitraryZipStream.d.ts +1 -1
- package/build/arrayParser.js +72 -13
- package/build/backsmali.d.ts +4 -3
- package/build/backsmali.js +26 -6
- package/build/bash.d.ts +89 -0
- package/build/bash.js +1 -0
- package/build/bashParser.d.ts +6 -0
- package/build/bashParser.js +335 -0
- package/build/bashParser.test.d.ts +1 -0
- package/build/bashParser.test.js +343 -0
- package/build/bashParserEdgeCases.test.d.ts +1 -0
- package/build/bashParserEdgeCases.test.js +117 -0
- package/build/dalvikBytecodeParser/addressConversion.d.ts +110 -0
- package/build/dalvikBytecodeParser/addressConversion.js +334 -0
- package/build/dalvikBytecodeParser/formatParsers.d.ts +7 -6
- package/build/dalvikBytecodeParser/formatParsers.js +13 -14
- package/build/dalvikBytecodeParser.d.ts +60 -31
- package/build/dalvikBytecodeParser.js +92 -35
- package/build/dalvikBytecodeParser.test-d.d.ts +1 -0
- package/build/dalvikBytecodeParser.test-d.js +268 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +9 -8
- package/build/dalvikBytecodeUnparser/formatUnparsers.js +13 -12
- package/build/dalvikBytecodeUnparser.d.ts +2 -2
- package/build/dalvikBytecodeUnparser.js +23 -23
- package/build/dalvikBytecodeUnparser.test.js +7 -7
- package/build/dalvikExecutable.d.ts +3 -3
- package/build/dalvikExecutable.test-d.d.ts +1 -0
- package/build/dalvikExecutable.test-d.js +59 -0
- package/build/dalvikExecutableParser/typedNumbers.d.ts +18 -0
- package/build/dalvikExecutableParser/typedNumbers.js +3 -0
- package/build/dalvikExecutableParser.d.ts +2 -1
- package/build/dalvikExecutableParser.js +96 -77
- package/build/dalvikExecutableParser.test.js +24 -3
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +3 -0
- package/build/dalvikExecutableUnparser/poolScanners.d.ts +2 -2
- package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +3 -3
- package/build/dalvikExecutableUnparser/sectionUnparsers.js +26 -11
- package/build/dalvikExecutableUnparser.d.ts +2 -2
- package/build/dalvikExecutableUnparser.test.js +2 -1
- package/build/disjunctionParser.d.ts +5 -3
- package/build/disjunctionParser.js +79 -17
- package/build/disjunctionParser.test-d.d.ts +1 -0
- package/build/disjunctionParser.test-d.js +72 -0
- package/build/elementSwitchParser.d.ts +4 -0
- package/build/{exactElementSwitchParser.js → elementSwitchParser.js} +3 -4
- package/build/elementSwitchParser.test-d.d.ts +1 -0
- package/build/elementSwitchParser.test-d.js +44 -0
- package/build/exactSequenceParser.d.ts +4 -2
- package/build/exactSequenceParser.test-d.d.ts +1 -0
- package/build/exactSequenceParser.test-d.js +36 -0
- package/build/fetchCid.js +2 -66
- package/build/index.d.ts +25 -2
- package/build/index.js +23 -1
- package/build/index.test.js +16 -1
- package/build/inputReader.d.ts +10 -0
- package/build/inputReader.js +36 -0
- package/build/java.d.ts +502 -0
- package/build/java.js +2 -0
- package/build/javaKeyStoreParser.js +14 -17
- package/build/javaParser.d.ts +51 -0
- package/build/javaParser.js +1538 -0
- package/build/javaParser.test.d.ts +1 -0
- package/build/javaParser.test.js +1287 -0
- package/build/javaScript.d.ts +35 -0
- package/build/javaScript.js +1 -0
- package/build/javaScriptParser.d.ts +9 -0
- package/build/javaScriptParser.js +34 -0
- package/build/javaScriptUnparser.d.ts +3 -0
- package/build/javaScriptUnparser.js +4 -0
- package/build/javaScriptUnparser.test.d.ts +1 -0
- package/build/javaScriptUnparser.test.js +24 -0
- package/build/javaUnparser.d.ts +2 -0
- package/build/javaUnparser.js +519 -0
- package/build/javaUnparser.test.d.ts +1 -0
- package/build/javaUnparser.test.js +24 -0
- package/build/javascript.d.ts +35 -0
- package/build/javascript.js +1 -0
- package/build/javascriptParser.d.ts +9 -0
- package/build/javascriptParser.js +34 -0
- package/build/javascriptUnparser.d.ts +3 -0
- package/build/javascriptUnparser.js +4 -0
- package/build/javascriptUnparser.test.d.ts +1 -0
- package/build/javascriptUnparser.test.js +24 -0
- package/build/jsonParser.js +2 -12
- package/build/lazyMessageError.d.ts +3 -0
- package/build/lookaheadParser.js +60 -3
- package/build/negativeLookaheadParser.js +70 -11
- package/build/nonEmptyArrayParser.js +72 -13
- package/build/objectParser.d.ts +12 -0
- package/build/objectParser.js +31 -0
- package/build/objectParser.test-d.d.ts +1 -0
- package/build/objectParser.test-d.js +112 -0
- package/build/objectParser.test.d.ts +1 -0
- package/build/objectParser.test.js +55 -0
- package/build/optionalParser.js +69 -10
- package/build/parser.d.ts +4 -0
- package/build/parser.js +3 -1
- package/build/parser.test.js +114 -1
- package/build/parserConsumedSequenceParser.js +66 -7
- package/build/parserContext.d.ts +6 -0
- package/build/parserContext.js +20 -11
- package/build/parserError.d.ts +119 -27
- package/build/parserError.js +16 -8
- package/build/regexpParser.d.ts +2 -0
- package/build/regexpParser.js +101 -0
- package/build/regexpParser.test.d.ts +1 -0
- package/build/regexpParser.test.js +114 -0
- package/build/regularExpression.d.ts +63 -0
- package/build/regularExpression.js +1 -0
- package/build/regularExpressionParser.d.ts +3 -0
- package/build/regularExpressionParser.js +600 -0
- package/build/regularExpressionParser.test.d.ts +1 -0
- package/build/regularExpressionParser.test.js +89 -0
- package/build/separatedArrayParser.js +73 -14
- package/build/separatedNonEmptyArrayParser.js +73 -14
- package/build/sliceBoundedParser.js +62 -5
- package/build/smaliParser.d.ts +7 -7
- package/build/smaliParser.js +185 -268
- package/build/smaliParser.test.js +58 -0
- package/build/stringEscapes.d.ts +5 -0
- package/build/stringEscapes.js +244 -0
- package/build/symbolicExpression.d.ts +29 -0
- package/build/symbolicExpression.js +1 -0
- package/build/symbolicExpressionParser.d.ts +4 -0
- package/build/symbolicExpressionParser.js +123 -0
- package/build/symbolicExpressionParser.test.d.ts +1 -0
- package/build/symbolicExpressionParser.test.js +289 -0
- package/build/terminatedArrayParser.js +113 -38
- package/build/terminatedArrayParser.test.js +4 -2
- package/build/tupleParser.d.ts +7 -15
- package/build/tupleParser.js +1 -0
- package/build/unionParser.d.ts +5 -3
- package/build/unionParser.js +7 -2
- package/build/unionParser.test-d.d.ts +1 -0
- package/build/unionParser.test-d.js +72 -0
- package/build/unionParser.test.js +10 -11
- package/build/zig.d.ts +280 -0
- package/build/zig.js +2 -0
- package/build/zigParser.d.ts +3 -0
- package/build/zigParser.js +1119 -0
- package/build/zigParser.test.d.ts +1 -0
- package/build/zigParser.test.js +1590 -0
- package/build/zigUnparser.d.ts +2 -0
- package/build/zigUnparser.js +460 -0
- package/build/zigUnparser.test.d.ts +1 -0
- package/build/zigUnparser.test.js +24 -0
- package/build/zipParser.js +19 -32
- package/build/zipUnparser.js +19 -7
- package/build/zipUnparser.test.js +1 -1
- package/node_modules-@types/s-expression/index.d.ts +5 -0
- package/package.json +25 -6
- package/src/androidPackageParser.ts +33 -60
- package/src/arbitraryDalvikBytecode.ts +39 -31
- package/src/arbitraryDalvikExecutable.ts +65 -20
- package/src/arbitraryJava.ts +804 -0
- package/src/arbitraryJavaScript.ts +410 -0
- package/src/arbitraryZig.ts +380 -0
- package/src/arrayParser.ts +1 -3
- package/src/backsmali.ts +35 -4
- package/src/bash.ts +127 -0
- package/src/bashParser.test.ts +590 -0
- package/src/bashParser.ts +498 -0
- package/src/dalvikBytecodeParser/addressConversion.ts +496 -0
- package/src/dalvikBytecodeParser/formatParsers.ts +19 -29
- package/src/dalvikBytecodeParser.test-d.ts +310 -0
- package/src/dalvikBytecodeParser.ts +194 -69
- package/src/dalvikBytecodeUnparser/formatUnparsers.ts +27 -26
- package/src/dalvikBytecodeUnparser.test.ts +7 -7
- package/src/dalvikBytecodeUnparser.ts +31 -30
- package/src/dalvikExecutable.test-d.ts +132 -0
- package/src/dalvikExecutable.ts +3 -3
- package/src/dalvikExecutableParser/typedNumbers.ts +11 -0
- package/src/dalvikExecutableParser.test.ts +37 -3
- package/src/dalvikExecutableParser.test.ts.md +163 -2
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +121 -139
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +4 -0
- package/src/dalvikExecutableUnparser/poolScanners.ts +6 -6
- package/src/dalvikExecutableUnparser/sectionUnparsers.ts +38 -14
- package/src/dalvikExecutableUnparser.test.ts +3 -2
- package/src/dalvikExecutableUnparser.ts +4 -4
- package/src/disjunctionParser.test-d.ts +105 -0
- package/src/disjunctionParser.ts +18 -15
- package/src/elementSwitchParser.test-d.ts +74 -0
- package/src/elementSwitchParser.ts +51 -0
- package/src/exactSequenceParser.test-d.ts +43 -0
- package/src/exactSequenceParser.ts +13 -8
- package/src/fetchCid.ts +2 -76
- package/src/index.test.ts +22 -1
- package/src/index.ts +119 -2
- package/src/inputReader.ts +53 -0
- package/src/java.ts +708 -0
- package/src/javaKeyStoreParser.ts +18 -32
- package/src/javaParser.test.ts +1592 -0
- package/src/javaParser.ts +2640 -0
- package/src/javaScript.ts +36 -0
- package/src/javaScriptParser.ts +57 -0
- package/src/javaScriptUnparser.test.ts +37 -0
- package/src/javaScriptUnparser.ts +7 -0
- package/src/javaUnparser.test.ts +37 -0
- package/src/javaUnparser.ts +640 -0
- package/src/jsonParser.ts +6 -27
- package/src/lookaheadParser.ts +2 -6
- package/src/negativeLookaheadParser.ts +1 -3
- package/src/nonEmptyArrayParser.ts +1 -3
- package/src/objectParser.test-d.ts +152 -0
- package/src/objectParser.test.ts +71 -0
- package/src/objectParser.ts +69 -0
- package/src/optionalParser.ts +1 -3
- package/src/parser.test.ts +151 -4
- package/src/parser.ts +11 -1
- package/src/parserConsumedSequenceParser.ts +2 -4
- package/src/parserContext.ts +26 -11
- package/src/parserError.ts +17 -3
- package/src/regexpParser.test.ts +264 -0
- package/src/regexpParser.ts +126 -0
- package/src/regularExpression.ts +24 -0
- package/src/regularExpressionParser.test.ts +102 -0
- package/src/regularExpressionParser.ts +920 -0
- package/src/separatedArrayParser.ts +1 -3
- package/src/separatedNonEmptyArrayParser.ts +1 -3
- package/src/sliceBoundedParser.test.ts +2 -2
- package/src/sliceBoundedParser.ts +15 -19
- package/src/smaliParser.test.ts +64 -0
- package/src/smaliParser.test.ts.md +12 -12
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +246 -534
- package/src/stringEscapes.ts +253 -0
- package/src/symbolicExpression.ts +17 -0
- package/src/symbolicExpressionParser.test.ts +466 -0
- package/src/symbolicExpressionParser.ts +190 -0
- package/src/terminatedArrayParser.test.ts +9 -6
- package/src/terminatedArrayParser.ts +25 -29
- package/src/tupleParser.ts +21 -18
- package/src/unionParser.test-d.ts +105 -0
- package/src/unionParser.test.ts +18 -17
- package/src/unionParser.ts +28 -16
- package/src/zig.ts +411 -0
- package/src/zigParser.test.ts +1693 -0
- package/src/zigParser.ts +1745 -0
- package/src/zigUnparser.test.ts +37 -0
- package/src/zigUnparser.ts +615 -0
- package/src/zipParser.ts +20 -56
- package/src/zipUnparser.test.ts +1 -1
- package/src/zipUnparser.ts +22 -7
- package/tsconfig.json +2 -2
- package/build/exactElementSwitchParser.d.ts +0 -3
- package/src/exactElementSwitchParser.ts +0 -41
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// Helper to check that a literal type is assignable to the operation name union
|
|
2
|
+
const _checkOperation = (_) => { };
|
|
3
|
+
// nop
|
|
4
|
+
_checkOperation('nop');
|
|
5
|
+
// move operations
|
|
6
|
+
_checkOperation('move');
|
|
7
|
+
_checkOperation('move/from16');
|
|
8
|
+
_checkOperation('move/16');
|
|
9
|
+
_checkOperation('move-wide');
|
|
10
|
+
_checkOperation('move-wide/from16');
|
|
11
|
+
_checkOperation('move-wide/16');
|
|
12
|
+
_checkOperation('move-object');
|
|
13
|
+
_checkOperation('move-object/from16');
|
|
14
|
+
_checkOperation('move-object/16');
|
|
15
|
+
// move-result operations
|
|
16
|
+
_checkOperation('move-result');
|
|
17
|
+
_checkOperation('move-result-wide');
|
|
18
|
+
_checkOperation('move-result-object');
|
|
19
|
+
_checkOperation('move-exception');
|
|
20
|
+
// return operations
|
|
21
|
+
_checkOperation('return-void');
|
|
22
|
+
_checkOperation('return');
|
|
23
|
+
_checkOperation('return-wide');
|
|
24
|
+
_checkOperation('return-object');
|
|
25
|
+
// const operations
|
|
26
|
+
_checkOperation('const/4');
|
|
27
|
+
_checkOperation('const/16');
|
|
28
|
+
_checkOperation('const');
|
|
29
|
+
_checkOperation('const/high16');
|
|
30
|
+
_checkOperation('const-wide/16');
|
|
31
|
+
_checkOperation('const-wide/32');
|
|
32
|
+
_checkOperation('const-wide');
|
|
33
|
+
_checkOperation('const-wide/high16');
|
|
34
|
+
_checkOperation('const-string');
|
|
35
|
+
_checkOperation('const-string/jumbo');
|
|
36
|
+
_checkOperation('const-class');
|
|
37
|
+
_checkOperation('const-method-handle');
|
|
38
|
+
_checkOperation('const-method-type');
|
|
39
|
+
// monitor operations
|
|
40
|
+
_checkOperation('monitor-enter');
|
|
41
|
+
_checkOperation('monitor-exit');
|
|
42
|
+
// type operations
|
|
43
|
+
_checkOperation('check-cast');
|
|
44
|
+
_checkOperation('instance-of');
|
|
45
|
+
// array operations
|
|
46
|
+
_checkOperation('array-length');
|
|
47
|
+
_checkOperation('new-instance');
|
|
48
|
+
_checkOperation('new-array');
|
|
49
|
+
_checkOperation('filled-new-array');
|
|
50
|
+
_checkOperation('filled-new-array/range');
|
|
51
|
+
_checkOperation('fill-array-data');
|
|
52
|
+
_checkOperation('fill-array-data-payload');
|
|
53
|
+
// throw
|
|
54
|
+
_checkOperation('throw');
|
|
55
|
+
// goto operations
|
|
56
|
+
_checkOperation('goto');
|
|
57
|
+
_checkOperation('goto/16');
|
|
58
|
+
_checkOperation('goto/32');
|
|
59
|
+
// switch operations
|
|
60
|
+
_checkOperation('packed-switch');
|
|
61
|
+
_checkOperation('packed-switch-payload');
|
|
62
|
+
_checkOperation('sparse-switch');
|
|
63
|
+
_checkOperation('sparse-switch-payload');
|
|
64
|
+
// compare operations
|
|
65
|
+
_checkOperation('cmpl-float');
|
|
66
|
+
_checkOperation('cmpg-float');
|
|
67
|
+
_checkOperation('cmpl-double');
|
|
68
|
+
_checkOperation('cmpg-double');
|
|
69
|
+
_checkOperation('cmp-long');
|
|
70
|
+
// if-test operations
|
|
71
|
+
_checkOperation('if-eq');
|
|
72
|
+
_checkOperation('if-ne');
|
|
73
|
+
_checkOperation('if-lt');
|
|
74
|
+
_checkOperation('if-ge');
|
|
75
|
+
_checkOperation('if-gt');
|
|
76
|
+
_checkOperation('if-le');
|
|
77
|
+
// if-testz operations
|
|
78
|
+
_checkOperation('if-eqz');
|
|
79
|
+
_checkOperation('if-nez');
|
|
80
|
+
_checkOperation('if-ltz');
|
|
81
|
+
_checkOperation('if-gez');
|
|
82
|
+
_checkOperation('if-gtz');
|
|
83
|
+
_checkOperation('if-lez');
|
|
84
|
+
// aget operations
|
|
85
|
+
_checkOperation('aget');
|
|
86
|
+
_checkOperation('aget-wide');
|
|
87
|
+
_checkOperation('aget-object');
|
|
88
|
+
_checkOperation('aget-boolean');
|
|
89
|
+
_checkOperation('aget-byte');
|
|
90
|
+
_checkOperation('aget-char');
|
|
91
|
+
_checkOperation('aget-short');
|
|
92
|
+
// aput operations
|
|
93
|
+
_checkOperation('aput');
|
|
94
|
+
_checkOperation('aput-wide');
|
|
95
|
+
_checkOperation('aput-object');
|
|
96
|
+
_checkOperation('aput-boolean');
|
|
97
|
+
_checkOperation('aput-byte');
|
|
98
|
+
_checkOperation('aput-char');
|
|
99
|
+
_checkOperation('aput-short');
|
|
100
|
+
// iget operations
|
|
101
|
+
_checkOperation('iget');
|
|
102
|
+
_checkOperation('iget-wide');
|
|
103
|
+
_checkOperation('iget-object');
|
|
104
|
+
_checkOperation('iget-boolean');
|
|
105
|
+
_checkOperation('iget-byte');
|
|
106
|
+
_checkOperation('iget-char');
|
|
107
|
+
_checkOperation('iget-short');
|
|
108
|
+
// iput operations
|
|
109
|
+
_checkOperation('iput');
|
|
110
|
+
_checkOperation('iput-wide');
|
|
111
|
+
_checkOperation('iput-object');
|
|
112
|
+
_checkOperation('iput-boolean');
|
|
113
|
+
_checkOperation('iput-byte');
|
|
114
|
+
_checkOperation('iput-char');
|
|
115
|
+
_checkOperation('iput-short');
|
|
116
|
+
// sget operations
|
|
117
|
+
_checkOperation('sget');
|
|
118
|
+
_checkOperation('sget-wide');
|
|
119
|
+
_checkOperation('sget-object');
|
|
120
|
+
_checkOperation('sget-boolean');
|
|
121
|
+
_checkOperation('sget-byte');
|
|
122
|
+
_checkOperation('sget-char');
|
|
123
|
+
_checkOperation('sget-short');
|
|
124
|
+
// sput operations
|
|
125
|
+
_checkOperation('sput');
|
|
126
|
+
_checkOperation('sput-wide');
|
|
127
|
+
_checkOperation('sput-object');
|
|
128
|
+
_checkOperation('sput-boolean');
|
|
129
|
+
_checkOperation('sput-byte');
|
|
130
|
+
_checkOperation('sput-char');
|
|
131
|
+
_checkOperation('sput-short');
|
|
132
|
+
// invoke operations
|
|
133
|
+
_checkOperation('invoke-virtual');
|
|
134
|
+
_checkOperation('invoke-super');
|
|
135
|
+
_checkOperation('invoke-direct');
|
|
136
|
+
_checkOperation('invoke-static');
|
|
137
|
+
_checkOperation('invoke-interface');
|
|
138
|
+
// invoke/range operations
|
|
139
|
+
_checkOperation('invoke-virtual/range');
|
|
140
|
+
_checkOperation('invoke-super/range');
|
|
141
|
+
_checkOperation('invoke-direct/range');
|
|
142
|
+
_checkOperation('invoke-static/range');
|
|
143
|
+
_checkOperation('invoke-interface/range');
|
|
144
|
+
// invoke-polymorphic operations
|
|
145
|
+
_checkOperation('invoke-polymorphic');
|
|
146
|
+
_checkOperation('invoke-polymorphic/range');
|
|
147
|
+
// invoke-custom operations
|
|
148
|
+
_checkOperation('invoke-custom');
|
|
149
|
+
_checkOperation('invoke-custom/range');
|
|
150
|
+
// unary operations
|
|
151
|
+
_checkOperation('neg-int');
|
|
152
|
+
_checkOperation('not-int');
|
|
153
|
+
_checkOperation('neg-long');
|
|
154
|
+
_checkOperation('not-long');
|
|
155
|
+
_checkOperation('neg-float');
|
|
156
|
+
_checkOperation('neg-double');
|
|
157
|
+
_checkOperation('int-to-long');
|
|
158
|
+
_checkOperation('int-to-float');
|
|
159
|
+
_checkOperation('int-to-double');
|
|
160
|
+
_checkOperation('long-to-int');
|
|
161
|
+
_checkOperation('long-to-float');
|
|
162
|
+
_checkOperation('long-to-double');
|
|
163
|
+
_checkOperation('float-to-int');
|
|
164
|
+
_checkOperation('float-to-long');
|
|
165
|
+
_checkOperation('float-to-double');
|
|
166
|
+
_checkOperation('double-to-int');
|
|
167
|
+
_checkOperation('double-to-long');
|
|
168
|
+
_checkOperation('double-to-float');
|
|
169
|
+
_checkOperation('int-to-byte');
|
|
170
|
+
_checkOperation('int-to-char');
|
|
171
|
+
_checkOperation('int-to-short');
|
|
172
|
+
// binary int operations
|
|
173
|
+
_checkOperation('add-int');
|
|
174
|
+
_checkOperation('sub-int');
|
|
175
|
+
_checkOperation('mul-int');
|
|
176
|
+
_checkOperation('div-int');
|
|
177
|
+
_checkOperation('rem-int');
|
|
178
|
+
_checkOperation('and-int');
|
|
179
|
+
_checkOperation('or-int');
|
|
180
|
+
_checkOperation('xor-int');
|
|
181
|
+
_checkOperation('shl-int');
|
|
182
|
+
_checkOperation('shr-int');
|
|
183
|
+
_checkOperation('ushr-int');
|
|
184
|
+
// binary long operations
|
|
185
|
+
_checkOperation('add-long');
|
|
186
|
+
_checkOperation('sub-long');
|
|
187
|
+
_checkOperation('mul-long');
|
|
188
|
+
_checkOperation('div-long');
|
|
189
|
+
_checkOperation('rem-long');
|
|
190
|
+
_checkOperation('and-long');
|
|
191
|
+
_checkOperation('or-long');
|
|
192
|
+
_checkOperation('xor-long');
|
|
193
|
+
_checkOperation('shl-long');
|
|
194
|
+
_checkOperation('shr-long');
|
|
195
|
+
_checkOperation('ushr-long');
|
|
196
|
+
// binary float operations
|
|
197
|
+
_checkOperation('add-float');
|
|
198
|
+
_checkOperation('sub-float');
|
|
199
|
+
_checkOperation('mul-float');
|
|
200
|
+
_checkOperation('div-float');
|
|
201
|
+
_checkOperation('rem-float');
|
|
202
|
+
// binary double operations
|
|
203
|
+
_checkOperation('add-double');
|
|
204
|
+
_checkOperation('sub-double');
|
|
205
|
+
_checkOperation('mul-double');
|
|
206
|
+
_checkOperation('div-double');
|
|
207
|
+
_checkOperation('rem-double');
|
|
208
|
+
// binary int/2addr operations
|
|
209
|
+
_checkOperation('add-int/2addr');
|
|
210
|
+
_checkOperation('sub-int/2addr');
|
|
211
|
+
_checkOperation('mul-int/2addr');
|
|
212
|
+
_checkOperation('div-int/2addr');
|
|
213
|
+
_checkOperation('rem-int/2addr');
|
|
214
|
+
_checkOperation('and-int/2addr');
|
|
215
|
+
_checkOperation('or-int/2addr');
|
|
216
|
+
_checkOperation('xor-int/2addr');
|
|
217
|
+
_checkOperation('shl-int/2addr');
|
|
218
|
+
_checkOperation('shr-int/2addr');
|
|
219
|
+
_checkOperation('ushr-int/2addr');
|
|
220
|
+
// binary long/2addr operations
|
|
221
|
+
_checkOperation('add-long/2addr');
|
|
222
|
+
_checkOperation('sub-long/2addr');
|
|
223
|
+
_checkOperation('mul-long/2addr');
|
|
224
|
+
_checkOperation('div-long/2addr');
|
|
225
|
+
_checkOperation('rem-long/2addr');
|
|
226
|
+
_checkOperation('and-long/2addr');
|
|
227
|
+
_checkOperation('or-long/2addr');
|
|
228
|
+
_checkOperation('xor-long/2addr');
|
|
229
|
+
_checkOperation('shl-long/2addr');
|
|
230
|
+
_checkOperation('shr-long/2addr');
|
|
231
|
+
_checkOperation('ushr-long/2addr');
|
|
232
|
+
// binary float/2addr operations
|
|
233
|
+
_checkOperation('add-float/2addr');
|
|
234
|
+
_checkOperation('sub-float/2addr');
|
|
235
|
+
_checkOperation('mul-float/2addr');
|
|
236
|
+
_checkOperation('div-float/2addr');
|
|
237
|
+
_checkOperation('rem-float/2addr');
|
|
238
|
+
// binary double/2addr operations
|
|
239
|
+
_checkOperation('add-double/2addr');
|
|
240
|
+
_checkOperation('sub-double/2addr');
|
|
241
|
+
_checkOperation('mul-double/2addr');
|
|
242
|
+
_checkOperation('div-double/2addr');
|
|
243
|
+
_checkOperation('rem-double/2addr');
|
|
244
|
+
// binary int/lit16 operations
|
|
245
|
+
_checkOperation('add-int/lit16');
|
|
246
|
+
_checkOperation('rsub-int');
|
|
247
|
+
_checkOperation('mul-int/lit16');
|
|
248
|
+
_checkOperation('div-int/lit16');
|
|
249
|
+
_checkOperation('rem-int/lit16');
|
|
250
|
+
_checkOperation('and-int/lit16');
|
|
251
|
+
_checkOperation('or-int/lit16');
|
|
252
|
+
_checkOperation('xor-int/lit16');
|
|
253
|
+
// binary int/lit8 operations
|
|
254
|
+
_checkOperation('add-int/lit8');
|
|
255
|
+
_checkOperation('rsub-int/lit8');
|
|
256
|
+
_checkOperation('mul-int/lit8');
|
|
257
|
+
_checkOperation('div-int/lit8');
|
|
258
|
+
_checkOperation('rem-int/lit8');
|
|
259
|
+
_checkOperation('and-int/lit8');
|
|
260
|
+
_checkOperation('or-int/lit8');
|
|
261
|
+
_checkOperation('xor-int/lit8');
|
|
262
|
+
_checkOperation('shl-int/lit8');
|
|
263
|
+
_checkOperation('shr-int/lit8');
|
|
264
|
+
_checkOperation('ushr-int/lit8');
|
|
265
|
+
// Verify the type check actually works - this should be a type error
|
|
266
|
+
// @ts-expect-error
|
|
267
|
+
_checkOperation('fake-operation');
|
|
268
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Unparser } from '../unparser.js';
|
|
2
|
+
import { type CodeUnit } from '../dalvikExecutableParser/typedNumbers.js';
|
|
2
3
|
export declare const ubyteUnparser: Unparser<number, Uint8Array>;
|
|
3
4
|
export declare const byteUnparser: Unparser<number, Uint8Array>;
|
|
4
5
|
export declare const shortUnparser: Unparser<number, Uint8Array>;
|
|
@@ -9,7 +10,7 @@ export declare const longUnparser: Unparser<bigint, Uint8Array>;
|
|
|
9
10
|
export declare const ulongUnparser: Unparser<bigint, Uint8Array>;
|
|
10
11
|
export declare const nibblesUnparser: Unparser<[number, number], Uint8Array>;
|
|
11
12
|
type DalvikBytecodeFormat10t = {
|
|
12
|
-
|
|
13
|
+
branchOffsetCodeUnit: CodeUnit;
|
|
13
14
|
};
|
|
14
15
|
export declare const dalvikBytecodeFormat10tUnparser: Unparser<DalvikBytecodeFormat10t, Uint8Array>;
|
|
15
16
|
type DalvikBytecodeFormat10x = void;
|
|
@@ -29,7 +30,7 @@ type DalvikBytecodeFormat12x = {
|
|
|
29
30
|
export declare const dalvikBytecodeFormat12xUnparser: Unparser<DalvikBytecodeFormat12x, Uint8Array>;
|
|
30
31
|
export declare const dalvikBytecodeFormat12xReversedUnparser: Unparser<DalvikBytecodeFormat12x, Uint8Array>;
|
|
31
32
|
type DalvikBytecodeFormat20t = {
|
|
32
|
-
|
|
33
|
+
branchOffsetCodeUnit: CodeUnit;
|
|
33
34
|
};
|
|
34
35
|
export declare const dalvikBytecodeFormat20tUnparser: Unparser<DalvikBytecodeFormat20t, Uint8Array>;
|
|
35
36
|
type DalvikBytecodeFormat21c = {
|
|
@@ -43,7 +44,7 @@ type DalvikBytecodeFormat21h = {
|
|
|
43
44
|
};
|
|
44
45
|
export declare const dalvikBytecodeFormat21hUnparser: Unparser<DalvikBytecodeFormat21h, Uint8Array>;
|
|
45
46
|
type DalvikBytecodeFormat21t = {
|
|
46
|
-
|
|
47
|
+
branchOffsetCodeUnit: CodeUnit;
|
|
47
48
|
registers: number[];
|
|
48
49
|
};
|
|
49
50
|
export declare const dalvikBytecodeFormat21tUnparser: Unparser<DalvikBytecodeFormat21t, Uint8Array>;
|
|
@@ -68,7 +69,7 @@ type DalvikBytecodeFormat22s = {
|
|
|
68
69
|
};
|
|
69
70
|
export declare const dalvikBytecodeFormat22sUnparser: Unparser<DalvikBytecodeFormat22s, Uint8Array>;
|
|
70
71
|
type DalvikBytecodeFormat22t = {
|
|
71
|
-
|
|
72
|
+
branchOffsetCodeUnit: CodeUnit;
|
|
72
73
|
registers: number[];
|
|
73
74
|
};
|
|
74
75
|
export declare const dalvikBytecodeFormat22tUnparser: Unparser<DalvikBytecodeFormat22t, Uint8Array>;
|
|
@@ -82,7 +83,7 @@ type DalvikBytecodeFormat23x = {
|
|
|
82
83
|
};
|
|
83
84
|
export declare const dalvikBytecodeFormat23xUnparser: Unparser<DalvikBytecodeFormat23x, Uint8Array>;
|
|
84
85
|
type DalvikBytecodeFormat30t = {
|
|
85
|
-
|
|
86
|
+
branchOffsetCodeUnit: CodeUnit;
|
|
86
87
|
};
|
|
87
88
|
export declare const dalvikBytecodeFormat30tUnparser: Unparser<DalvikBytecodeFormat30t, Uint8Array>;
|
|
88
89
|
type DalvikBytecodeFormat31i = {
|
|
@@ -96,7 +97,7 @@ type DalvikBytecodeFormat31c = {
|
|
|
96
97
|
};
|
|
97
98
|
export declare const dalvikBytecodeFormat31cUnparser: Unparser<DalvikBytecodeFormat31c, Uint8Array>;
|
|
98
99
|
type DalvikBytecodeFormat31t = {
|
|
99
|
-
|
|
100
|
+
branchOffsetCodeUnit: CodeUnit;
|
|
100
101
|
registers: number[];
|
|
101
102
|
};
|
|
102
103
|
export declare const dalvikBytecodeFormat31tUnparser: Unparser<DalvikBytecodeFormat31t, Uint8Array>;
|
|
@@ -134,13 +135,13 @@ export declare const dalvikBytecodeFormat4rccUnparser: Unparser<DalvikBytecodeFo
|
|
|
134
135
|
type DalvikBytecodeOperationPackedSwitchPayload = {
|
|
135
136
|
operation: 'packed-switch-payload';
|
|
136
137
|
value: number;
|
|
137
|
-
|
|
138
|
+
branchOffsetsCodeUnit: CodeUnit[];
|
|
138
139
|
};
|
|
139
140
|
export declare const dalvikBytecodeOperationPackedSwitchPayloadUnparser: Unparser<DalvikBytecodeOperationPackedSwitchPayload, Uint8Array>;
|
|
140
141
|
type DalvikBytecodeOperationSparseSwitchPayload = {
|
|
141
142
|
operation: 'sparse-switch-payload';
|
|
142
143
|
keys: number[];
|
|
143
|
-
|
|
144
|
+
branchOffsetsCodeUnit: CodeUnit[];
|
|
144
145
|
};
|
|
145
146
|
export declare const dalvikBytecodeOperationSparseSwitchPayloadUnparser: Unparser<DalvikBytecodeOperationSparseSwitchPayload, Uint8Array>;
|
|
146
147
|
type DalvikBytecodeOperationFillArrayDataPayload = {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isoCodeUnit } from '../dalvikExecutableParser/typedNumbers.js';
|
|
1
2
|
// Basic type unparsers
|
|
2
3
|
export const ubyteUnparser = async function* (input) {
|
|
3
4
|
const buffer = Buffer.alloc(1);
|
|
@@ -45,7 +46,7 @@ export const nibblesUnparser = async function* ([high, low], unparserContext) {
|
|
|
45
46
|
yield* ubyteUnparser(byte, unparserContext);
|
|
46
47
|
};
|
|
47
48
|
export const dalvikBytecodeFormat10tUnparser = async function* (input, unparserContext) {
|
|
48
|
-
yield* byteUnparser(input.
|
|
49
|
+
yield* byteUnparser(isoCodeUnit.unwrap(input.branchOffsetCodeUnit), unparserContext);
|
|
49
50
|
};
|
|
50
51
|
export const dalvikBytecodeFormat10xUnparser = async function* (_input, unparserContext) {
|
|
51
52
|
yield* ubyteUnparser(0, unparserContext); // Zero byte
|
|
@@ -65,7 +66,7 @@ export const dalvikBytecodeFormat12xReversedUnparser = async function* (input, u
|
|
|
65
66
|
};
|
|
66
67
|
export const dalvikBytecodeFormat20tUnparser = async function* (input, unparserContext) {
|
|
67
68
|
yield* ubyteUnparser(0, unparserContext);
|
|
68
|
-
yield* shortUnparser(input.
|
|
69
|
+
yield* shortUnparser(isoCodeUnit.unwrap(input.branchOffsetCodeUnit), unparserContext);
|
|
69
70
|
};
|
|
70
71
|
export const dalvikBytecodeFormat21cUnparser = async function* (input, unparserContext) {
|
|
71
72
|
yield* ubyteUnparser(input.registers[0], unparserContext);
|
|
@@ -77,7 +78,7 @@ export const dalvikBytecodeFormat21hUnparser = async function* (input, unparserC
|
|
|
77
78
|
};
|
|
78
79
|
export const dalvikBytecodeFormat21tUnparser = async function* (input, unparserContext) {
|
|
79
80
|
yield* ubyteUnparser(input.registers[0], unparserContext);
|
|
80
|
-
yield* shortUnparser(input.
|
|
81
|
+
yield* shortUnparser(isoCodeUnit.unwrap(input.branchOffsetCodeUnit), unparserContext);
|
|
81
82
|
};
|
|
82
83
|
export const dalvikBytecodeFormat21sUnparser = async function* (input, unparserContext) {
|
|
83
84
|
yield* ubyteUnparser(input.registers[0], unparserContext);
|
|
@@ -98,13 +99,13 @@ export const dalvikBytecodeFormat22sUnparser = async function* (input, unparserC
|
|
|
98
99
|
};
|
|
99
100
|
export const dalvikBytecodeFormat22tUnparser = async function* (input, unparserContext) {
|
|
100
101
|
yield* nibblesUnparser([input.registers[1], input.registers[0]], unparserContext);
|
|
101
|
-
yield* shortUnparser(input.
|
|
102
|
+
yield* shortUnparser(isoCodeUnit.unwrap(input.branchOffsetCodeUnit), unparserContext);
|
|
102
103
|
};
|
|
103
104
|
// Format 22t for commutative operations (if-eq, if-ne): registers are already in sorted/canonical order
|
|
104
105
|
// so we don't reverse them
|
|
105
106
|
export const dalvikBytecodeFormat22tCommutativeUnparser = async function* (input, unparserContext) {
|
|
106
107
|
yield* nibblesUnparser([input.registers[0], input.registers[1]], unparserContext);
|
|
107
|
-
yield* shortUnparser(input.
|
|
108
|
+
yield* shortUnparser(isoCodeUnit.unwrap(input.branchOffsetCodeUnit), unparserContext);
|
|
108
109
|
};
|
|
109
110
|
export const dalvikBytecodeFormat22xUnparser = async function* (input, unparserContext) {
|
|
110
111
|
yield* ubyteUnparser(input.registers[0], unparserContext);
|
|
@@ -116,7 +117,7 @@ export const dalvikBytecodeFormat23xUnparser = async function* (input, unparserC
|
|
|
116
117
|
yield* ubyteUnparser(input.registers[2], unparserContext);
|
|
117
118
|
};
|
|
118
119
|
export const dalvikBytecodeFormat30tUnparser = async function* (input, unparserContext) {
|
|
119
|
-
yield* intUnparser(input.
|
|
120
|
+
yield* intUnparser(isoCodeUnit.unwrap(input.branchOffsetCodeUnit), unparserContext);
|
|
120
121
|
};
|
|
121
122
|
export const dalvikBytecodeFormat31iUnparser = async function* (input, unparserContext) {
|
|
122
123
|
yield* ubyteUnparser(input.registers[0], unparserContext);
|
|
@@ -128,7 +129,7 @@ export const dalvikBytecodeFormat31cUnparser = async function* (input, unparserC
|
|
|
128
129
|
};
|
|
129
130
|
export const dalvikBytecodeFormat31tUnparser = async function* (input, unparserContext) {
|
|
130
131
|
yield* ubyteUnparser(input.registers[0], unparserContext);
|
|
131
|
-
yield* intUnparser(input.
|
|
132
|
+
yield* intUnparser(isoCodeUnit.unwrap(input.branchOffsetCodeUnit), unparserContext);
|
|
132
133
|
};
|
|
133
134
|
export const dalvikBytecodeFormat32xUnparser = async function* (input, unparserContext) {
|
|
134
135
|
yield* ushortUnparser(input.registers[0], unparserContext);
|
|
@@ -182,12 +183,12 @@ export const dalvikBytecodeOperationPackedSwitchPayloadUnparser = async function
|
|
|
182
183
|
// Ident (0x0100) - little-endian
|
|
183
184
|
yield* ushortUnparser(0x01_00, unparserContext);
|
|
184
185
|
// Size
|
|
185
|
-
yield* ushortUnparser(input.
|
|
186
|
+
yield* ushortUnparser(input.branchOffsetsCodeUnit.length, unparserContext);
|
|
186
187
|
// First key value
|
|
187
188
|
yield* intUnparser(input.value, unparserContext);
|
|
188
189
|
// Branch offsets
|
|
189
|
-
for (const offset of input.
|
|
190
|
-
yield* intUnparser(offset, unparserContext);
|
|
190
|
+
for (const offset of input.branchOffsetsCodeUnit) {
|
|
191
|
+
yield* intUnparser(isoCodeUnit.unwrap(offset), unparserContext);
|
|
191
192
|
}
|
|
192
193
|
};
|
|
193
194
|
export const dalvikBytecodeOperationSparseSwitchPayloadUnparser = async function* (input, unparserContext) {
|
|
@@ -200,8 +201,8 @@ export const dalvikBytecodeOperationSparseSwitchPayloadUnparser = async function
|
|
|
200
201
|
yield* intUnparser(key, unparserContext);
|
|
201
202
|
}
|
|
202
203
|
// Branch offsets
|
|
203
|
-
for (const offset of input.
|
|
204
|
-
yield* intUnparser(offset, unparserContext);
|
|
204
|
+
for (const offset of input.branchOffsetsCodeUnit) {
|
|
205
|
+
yield* intUnparser(isoCodeUnit.unwrap(offset), unparserContext);
|
|
205
206
|
}
|
|
206
207
|
};
|
|
207
208
|
export const dalvikBytecodeOperationFillArrayDataPayloadUnparser = async function* (input, unparserContext) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type Unparser } from './unparser.js';
|
|
2
|
-
import { type
|
|
3
|
-
export declare const
|
|
2
|
+
import { type RawDalvikBytecode } from './dalvikBytecodeParser.js';
|
|
3
|
+
export declare const rawDalvikBytecodeUnparser: Unparser<RawDalvikBytecode, Uint8Array>;
|
|
@@ -245,9 +245,9 @@ const operationToOpcodeMap = new Map([
|
|
|
245
245
|
// Note: Payload instructions don't have single-byte opcodes
|
|
246
246
|
// They use multi-byte identifiers: 0x0100, 0x0200, 0x0300
|
|
247
247
|
]);
|
|
248
|
-
export const
|
|
248
|
+
export const rawDalvikBytecodeUnparser = async function* (input, unparserContext) {
|
|
249
249
|
for (const operation of input) {
|
|
250
|
-
yield*
|
|
250
|
+
yield* rawDalvikBytecodeOperationUnparser(operation, unparserContext);
|
|
251
251
|
}
|
|
252
252
|
};
|
|
253
253
|
// Type guards for payload operations
|
|
@@ -260,7 +260,7 @@ function isSparseSwitchPayload(op) {
|
|
|
260
260
|
function isFillArrayDataPayload(op) {
|
|
261
261
|
return typeof op === 'object' && op !== null && 'operation' in op && op.operation === 'fill-array-data-payload';
|
|
262
262
|
}
|
|
263
|
-
const
|
|
263
|
+
const rawDalvikBytecodeOperationUnparser = async function* (operation, unparserContext) {
|
|
264
264
|
if (!operation || typeof operation !== 'object' || !('operation' in operation)) {
|
|
265
265
|
throw new Error('Invalid operation');
|
|
266
266
|
}
|
|
@@ -300,8 +300,8 @@ function hasRegisters(op) {
|
|
|
300
300
|
function hasValue(op) {
|
|
301
301
|
return 'value' in op;
|
|
302
302
|
}
|
|
303
|
-
function
|
|
304
|
-
return '
|
|
303
|
+
function hasBranchOffsetCodeUnit(op) {
|
|
304
|
+
return 'branchOffsetCodeUnit' in op;
|
|
305
305
|
}
|
|
306
306
|
async function* unparseOperationData(operation, unparserContext) {
|
|
307
307
|
if (!('operation' in operation)) {
|
|
@@ -499,54 +499,54 @@ async function* unparseOperationData(operation, unparserContext) {
|
|
|
499
499
|
}
|
|
500
500
|
// Format 10t (goto)
|
|
501
501
|
if (operationName === 'goto') {
|
|
502
|
-
if (!
|
|
503
|
-
throw new Error(`Operation ${operationName} missing
|
|
502
|
+
if (!hasBranchOffsetCodeUnit(operation)) {
|
|
503
|
+
throw new Error(`Operation ${operationName} missing branchOffsetCodeUnit field`);
|
|
504
504
|
}
|
|
505
|
-
yield* dalvikBytecodeFormat10tUnparser({
|
|
505
|
+
yield* dalvikBytecodeFormat10tUnparser({ branchOffsetCodeUnit: operation.branchOffsetCodeUnit }, unparserContext);
|
|
506
506
|
return;
|
|
507
507
|
}
|
|
508
508
|
// Format 20t (goto/16)
|
|
509
509
|
if (operationName === 'goto/16') {
|
|
510
|
-
if (!
|
|
511
|
-
throw new Error(`Operation ${operationName} missing
|
|
510
|
+
if (!hasBranchOffsetCodeUnit(operation)) {
|
|
511
|
+
throw new Error(`Operation ${operationName} missing branchOffsetCodeUnit field`);
|
|
512
512
|
}
|
|
513
|
-
yield* dalvikBytecodeFormat20tUnparser({
|
|
513
|
+
yield* dalvikBytecodeFormat20tUnparser({ branchOffsetCodeUnit: operation.branchOffsetCodeUnit }, unparserContext);
|
|
514
514
|
return;
|
|
515
515
|
}
|
|
516
516
|
// Format 30t (goto/32)
|
|
517
517
|
if (operationName === 'goto/32') {
|
|
518
|
-
if (!
|
|
519
|
-
throw new Error(`Operation ${operationName} missing
|
|
518
|
+
if (!hasBranchOffsetCodeUnit(operation)) {
|
|
519
|
+
throw new Error(`Operation ${operationName} missing branchOffsetCodeUnit field`);
|
|
520
520
|
}
|
|
521
|
-
yield* dalvikBytecodeFormat30tUnparser({
|
|
521
|
+
yield* dalvikBytecodeFormat30tUnparser({ branchOffsetCodeUnit: operation.branchOffsetCodeUnit }, unparserContext);
|
|
522
522
|
return;
|
|
523
523
|
}
|
|
524
524
|
// Format 22t (if-* operations)
|
|
525
525
|
if (operationName.startsWith('if-') && !operationName.endsWith('z')) {
|
|
526
|
-
if (!
|
|
527
|
-
throw new Error(`Operation ${operationName} missing
|
|
526
|
+
if (!hasBranchOffsetCodeUnit(operation) || !hasRegisters(operation)) {
|
|
527
|
+
throw new Error(`Operation ${operationName} missing branchOffsetCodeUnit or registers field`);
|
|
528
528
|
}
|
|
529
529
|
// Commutative operations (if-eq, if-ne) have sorted registers, so don't reverse
|
|
530
530
|
const isCommutative = operationName === 'if-eq' || operationName === 'if-ne';
|
|
531
531
|
const unparser = isCommutative ? dalvikBytecodeFormat22tCommutativeUnparser : dalvikBytecodeFormat22tUnparser;
|
|
532
|
-
yield* unparser({
|
|
532
|
+
yield* unparser({ branchOffsetCodeUnit: operation.branchOffsetCodeUnit, registers: operation.registers }, unparserContext);
|
|
533
533
|
return;
|
|
534
534
|
}
|
|
535
535
|
// Format 21t (if-*z operations)
|
|
536
536
|
if (operationName.startsWith('if-') && operationName.endsWith('z')) {
|
|
537
|
-
if (!
|
|
538
|
-
throw new Error(`Operation ${operationName} missing
|
|
537
|
+
if (!hasBranchOffsetCodeUnit(operation) || !hasRegisters(operation)) {
|
|
538
|
+
throw new Error(`Operation ${operationName} missing branchOffsetCodeUnit or registers field`);
|
|
539
539
|
}
|
|
540
|
-
yield* dalvikBytecodeFormat21tUnparser({
|
|
540
|
+
yield* dalvikBytecodeFormat21tUnparser({ branchOffsetCodeUnit: operation.branchOffsetCodeUnit, registers: operation.registers }, unparserContext);
|
|
541
541
|
return;
|
|
542
542
|
}
|
|
543
543
|
// Format 31t (packed-switch, sparse-switch, fill-array-data)
|
|
544
544
|
if (operationName === 'packed-switch' || operationName === 'sparse-switch' ||
|
|
545
545
|
operationName === 'fill-array-data') {
|
|
546
|
-
if (!
|
|
547
|
-
throw new Error(`Operation ${operationName} missing
|
|
546
|
+
if (!hasBranchOffsetCodeUnit(operation) || !hasRegisters(operation)) {
|
|
547
|
+
throw new Error(`Operation ${operationName} missing branchOffsetCodeUnit or registers field`);
|
|
548
548
|
}
|
|
549
|
-
yield* dalvikBytecodeFormat31tUnparser({
|
|
549
|
+
yield* dalvikBytecodeFormat31tUnparser({ branchOffsetCodeUnit: operation.branchOffsetCodeUnit, registers: operation.registers }, unparserContext);
|
|
550
550
|
return;
|
|
551
551
|
}
|
|
552
552
|
// Format 22b (binary operations with literal8)
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { testProp } from '@fast-check/ava';
|
|
2
2
|
import { runUnparser } from './unparser.js';
|
|
3
|
-
import {
|
|
3
|
+
import { rawDalvikBytecodeUnparser } from './dalvikBytecodeUnparser.js';
|
|
4
4
|
import { uint8ArrayUnparserOutputCompanion } from './unparserOutputCompanion.js';
|
|
5
5
|
import { runParser } from './parser.js';
|
|
6
|
-
import {
|
|
6
|
+
import { createRawDalvikBytecodeParser } from './dalvikBytecodeParser.js';
|
|
7
7
|
import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
8
|
-
import {
|
|
8
|
+
import { arbitraryRawDalvikBytecode } from './arbitraryDalvikBytecode.js';
|
|
9
9
|
import { uint8ArrayAsyncIterableToUint8Array } from './uint8Array.js';
|
|
10
10
|
const seed = process.env.SEED ? Number(process.env.SEED) : undefined;
|
|
11
|
-
testProp('dalvik bytecode roundtrip', [
|
|
11
|
+
testProp('dalvik bytecode roundtrip', [arbitraryRawDalvikBytecode], async (t, bytecode) => {
|
|
12
12
|
// Unparse the bytecode to bytes
|
|
13
|
-
const unparsedStreamIterable = runUnparser(
|
|
13
|
+
const unparsedStreamIterable = runUnparser(rawDalvikBytecodeUnparser, bytecode, uint8ArrayUnparserOutputCompanion);
|
|
14
14
|
// Collect all chunks into a single Uint8Array
|
|
15
15
|
const unparsedStream = await uint8ArrayAsyncIterableToUint8Array(unparsedStreamIterable);
|
|
16
16
|
// Create parser with the correct size
|
|
17
|
-
const
|
|
17
|
+
const rawDalvikBytecodeParser = createRawDalvikBytecodeParser(unparsedStream.length);
|
|
18
18
|
// Re-parse the unparsed bytes
|
|
19
|
-
const actual = await runParser(
|
|
19
|
+
const actual = await runParser(rawDalvikBytecodeParser, unparsedStream, uint8ArrayParserInputCompanion);
|
|
20
20
|
// Assert deep equality
|
|
21
21
|
t.deepEqual(actual, bytecode);
|
|
22
22
|
}, {
|
|
@@ -76,17 +76,17 @@ export type DalvikExecutableEncodedValue = {
|
|
|
76
76
|
value: boolean;
|
|
77
77
|
};
|
|
78
78
|
type DalvikExecutableTry = {
|
|
79
|
-
|
|
79
|
+
startInstructionIndex: number;
|
|
80
80
|
instructionCount: number;
|
|
81
81
|
handler: DalvikExecutableEncodedCatchHandler;
|
|
82
82
|
};
|
|
83
83
|
type DalvikExecutableEncodedTypeAddressPair = {
|
|
84
84
|
type: string;
|
|
85
|
-
|
|
85
|
+
handlerInstructionIndex: number;
|
|
86
86
|
};
|
|
87
87
|
type DalvikExecutableEncodedCatchHandler = {
|
|
88
88
|
handlers: DalvikExecutableEncodedTypeAddressPair[];
|
|
89
|
-
|
|
89
|
+
catchAllInstructionIndex: undefined | number;
|
|
90
90
|
};
|
|
91
91
|
export type DalvikExecutableCode<Instructions> = {
|
|
92
92
|
registersSize: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { expectType } from 'tsd';
|
|
2
|
+
const classDef = dex.classDefinitions[0];
|
|
3
|
+
const classData = classDef.classData;
|
|
4
|
+
const method = classData.directMethods[0];
|
|
5
|
+
const code = method.code;
|
|
6
|
+
// Try block field types
|
|
7
|
+
const tryBlock = code.tries[0];
|
|
8
|
+
expectType(tryBlock.startInstructionIndex);
|
|
9
|
+
expectType(tryBlock.instructionCount);
|
|
10
|
+
// Handler field types
|
|
11
|
+
const handler = tryBlock.handler;
|
|
12
|
+
expectType(handler.catchAllInstructionIndex);
|
|
13
|
+
// Type-address pair field types
|
|
14
|
+
const typeAddressPair = handler.handlers[0];
|
|
15
|
+
expectType(typeAddressPair.handlerInstructionIndex);
|
|
16
|
+
expectType(gotoOp.targetInstructionIndex);
|
|
17
|
+
expectType(goto16Op.targetInstructionIndex);
|
|
18
|
+
expectType(goto32Op.targetInstructionIndex);
|
|
19
|
+
expectType(packedSwitchOp.targetInstructionIndex);
|
|
20
|
+
expectType(sparseSwitchOp.targetInstructionIndex);
|
|
21
|
+
expectType(packedSwitchPayloadOp.targetInstructionIndices);
|
|
22
|
+
expectType(sparseSwitchPayloadOp.targetInstructionIndices);
|
|
23
|
+
expectType(fillArrayDataOp.targetInstructionIndex);
|
|
24
|
+
expectType(ifEqOp.targetInstructionIndex);
|
|
25
|
+
expectType(ifEqzOp.targetInstructionIndex);
|
|
26
|
+
expectType(invokeVirtualOp.method);
|
|
27
|
+
expectType(igetOp.field);
|
|
28
|
+
expectType(checkCastOp.type);
|
|
29
|
+
expectType(constStringOp.string);
|
|
30
|
+
// Test that raw index fields do NOT exist on resolved types
|
|
31
|
+
// @ts-expect-error - methodIndex should not exist, use method instead
|
|
32
|
+
invokeVirtualOp.methodIndex;
|
|
33
|
+
// @ts-expect-error - fieldIndex should not exist, use field instead
|
|
34
|
+
igetOp.fieldIndex;
|
|
35
|
+
// @ts-expect-error - typeIndex should not exist, use type instead
|
|
36
|
+
checkCastOp.typeIndex;
|
|
37
|
+
// @ts-expect-error - stringIndex should not exist, use string instead
|
|
38
|
+
constStringOp.stringIndex;
|
|
39
|
+
// Test that values can be constructed with resolved fields
|
|
40
|
+
const _invokeVirtual = {
|
|
41
|
+
operation: 'invoke-virtual',
|
|
42
|
+
registers: [0],
|
|
43
|
+
method: { class: 'Lfoo/Bar;', prototype: { shorty: 'V', returnType: 'V', parameters: [] }, name: 'baz' },
|
|
44
|
+
};
|
|
45
|
+
const _iget = {
|
|
46
|
+
operation: 'iget',
|
|
47
|
+
registers: [0, 1],
|
|
48
|
+
field: { class: 'Lfoo/Bar;', type: 'I', name: 'x' },
|
|
49
|
+
};
|
|
50
|
+
const _checkCast = {
|
|
51
|
+
operation: 'check-cast',
|
|
52
|
+
registers: [0],
|
|
53
|
+
type: 'Lfoo/Bar;',
|
|
54
|
+
};
|
|
55
|
+
const _constString = {
|
|
56
|
+
operation: 'const-string',
|
|
57
|
+
registers: [0],
|
|
58
|
+
string: 'hello',
|
|
59
|
+
};
|