@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
package/src/smaliParser.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import invariant from 'invariant';
|
|
2
2
|
import { type Simplify } from 'type-fest';
|
|
3
|
-
import { type
|
|
3
|
+
import { type RawDalvikBytecodeOperation, rawDalvikBytecodeOperationCompanion } from './dalvikBytecodeParser.js';
|
|
4
|
+
import { type DalvikBytecodeOperation, type DalvikBytecode, getOperationSizeInCodeUnits } from './dalvikBytecodeParser/addressConversion.js';
|
|
4
5
|
import {
|
|
5
6
|
type DalvikExecutableAccessFlags, dalvikExecutableAccessFlagsDefault, type DalvikExecutableAnnotation, type DalvikExecutableClassAnnotations, type DalvikExecutableClassData, type DalvikExecutableClassDefinition, type DalvikExecutableClassMethodAnnotation, type DalvikExecutableClassParameterAnnotation, type DalvikExecutableCode, type DalvikExecutableDebugInfo, type DalvikExecutableEncodedValue, type DalvikExecutableField, dalvikExecutableFieldEquals, type DalvikExecutableFieldWithAccess, type DalvikExecutableMethod, dalvikExecutableMethodEquals, type DalvikExecutableMethodWithAccess, type DalvikExecutablePrototype, isDalvikExecutableField, isDalvikExecutableMethod,
|
|
6
7
|
} from './dalvikExecutable.js';
|
|
7
8
|
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
9
|
+
import { createObjectParser } from './objectParser.js';
|
|
8
10
|
import { cloneParser, type Parser, setParserName } from './parser.js';
|
|
9
11
|
import { type ParserContext } from './parserContext.js';
|
|
10
12
|
import { promiseCompose } from './promiseCompose.js';
|
|
@@ -18,16 +20,13 @@ import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
|
|
|
18
20
|
import { createSeparatedArrayParser } from './separatedArrayParser.js';
|
|
19
21
|
import { smaliMemberNameParser, smaliTypeDescriptorParser } from './dalvikExecutableParser/stringSyntaxParser.js';
|
|
20
22
|
import { createDisjunctionParser } from './disjunctionParser.js';
|
|
21
|
-
import { formatSizes } from './dalvikBytecodeParser/formatSizes.js';
|
|
22
|
-
import { operationFormats } from './dalvikBytecodeParser/operationFormats.js';
|
|
23
23
|
import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
|
|
24
24
|
import { parserCreatorCompose } from './parserCreatorCompose.js';
|
|
25
25
|
import { type IndexIntoMethodIds } from './dalvikExecutableParser/typedNumbers.js';
|
|
26
|
-
import { createDebugLogInputParser } from './debugLogInputParser.js';
|
|
27
|
-
import { createDebugLogParser } from './debugLogParser.js';
|
|
28
26
|
import { createElementParser } from './elementParser.js';
|
|
29
27
|
import { createTerminatedArrayParser } from './terminatedArrayParser.js';
|
|
30
28
|
import { createParserAccessorParser } from './parserAccessorParser.js';
|
|
29
|
+
import { createRegExpParser } from './regexpParser.js';
|
|
31
30
|
|
|
32
31
|
function shortyFromLongy(longy: string): string {
|
|
33
32
|
if (longy.startsWith('[')) {
|
|
@@ -37,30 +36,6 @@ function shortyFromLongy(longy: string): string {
|
|
|
37
36
|
return longy.slice(0, 1);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
function getOperationFormatSize(operation: SmaliCodeOperation): number {
|
|
41
|
-
if (operation.operation === 'packed-switch-payload') {
|
|
42
|
-
return (operation.branchOffsetIndices.length * 2) + 4;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (operation.operation === 'sparse-switch-payload') {
|
|
46
|
-
return (operation.branchOffsetIndices.length * 4) + 2;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (operation.operation === 'fill-array-data-payload') {
|
|
50
|
-
const dataSize = operation.data.length; // in bytes
|
|
51
|
-
const paddingSize = dataSize % 2; // 1 if odd, 0 if even
|
|
52
|
-
const totalBytes = 8 + dataSize + paddingSize; // header (8 bytes) + data + padding
|
|
53
|
-
return totalBytes / 2; // Convert to code units (1 code unit = 2 bytes)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const operationFormat = operationFormats[operation.operation as keyof typeof operationFormats];
|
|
57
|
-
invariant(operationFormat, 'Unknown operation format for "%s" (operation: %o)', operation.operation, operation);
|
|
58
|
-
|
|
59
|
-
const operationSize = formatSizes[operationFormat];
|
|
60
|
-
invariant(operationSize, 'Unknown operation size for format %s of operation %s', operationFormat, operation.operation);
|
|
61
|
-
|
|
62
|
-
return operationSize;
|
|
63
|
-
}
|
|
64
39
|
|
|
65
40
|
// Helper function to convert raw annotation element values to tagged encoded values
|
|
66
41
|
function convertToTaggedEncodedValue(wrappedValue: SmaliAnnotationElementValue): DalvikExecutableEncodedValue {
|
|
@@ -166,7 +141,7 @@ function convertToTaggedEncodedValue(wrappedValue: SmaliAnnotationElementValue):
|
|
|
166
141
|
}
|
|
167
142
|
|
|
168
143
|
|
|
169
|
-
const smaliNewlinesParser: Parser<
|
|
144
|
+
const smaliNewlinesParser: Parser<undefined, string> = promiseCompose(
|
|
170
145
|
createNonEmptyArrayParser(createExactSequenceParser('\n')),
|
|
171
146
|
_newlines => undefined,
|
|
172
147
|
);
|
|
@@ -188,31 +163,11 @@ const smaliIndentationParser: Parser<void, string> = promiseCompose(
|
|
|
188
163
|
export const smaliCommentParser: Parser<string, string> = promiseCompose(
|
|
189
164
|
createTupleParser([
|
|
190
165
|
createExactSequenceParser('#'),
|
|
191
|
-
(
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
parserContext.invariant(character !== undefined, 'Unexpected end of input');
|
|
198
|
-
|
|
199
|
-
invariant(character !== undefined, 'Unexpected end of input');
|
|
200
|
-
|
|
201
|
-
if (character !== '\n') {
|
|
202
|
-
characters.push(character);
|
|
203
|
-
|
|
204
|
-
parserContext.skip(1);
|
|
205
|
-
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
parserContext.skip(1);
|
|
210
|
-
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return characters.join('');
|
|
215
|
-
}),
|
|
166
|
+
promiseCompose(
|
|
167
|
+
createRegExpParser(/[^\n]*/),
|
|
168
|
+
match => match[0],
|
|
169
|
+
),
|
|
170
|
+
createExactSequenceParser('\n'),
|
|
216
171
|
]),
|
|
217
172
|
([
|
|
218
173
|
_hash,
|
|
@@ -232,7 +187,7 @@ const smaliIndentedCommentParser: Parser<string, string> = promiseCompose(
|
|
|
232
187
|
);
|
|
233
188
|
|
|
234
189
|
const smaliCommentsOrNewlinesParser: Parser<string[], string> = promiseCompose(
|
|
235
|
-
createArrayParser(createUnionParser
|
|
190
|
+
createArrayParser(createUnionParser([
|
|
236
191
|
smaliNewlinesParser,
|
|
237
192
|
smaliIndentedCommentParser,
|
|
238
193
|
smaliCommentParser,
|
|
@@ -243,7 +198,7 @@ const smaliCommentsOrNewlinesParser: Parser<string[], string> = promiseCompose(
|
|
|
243
198
|
const smaliLineEndPraser: Parser<undefined | string, string> = promiseCompose(
|
|
244
199
|
createTupleParser([
|
|
245
200
|
createOptionalParser(smaliWhitespaceParser),
|
|
246
|
-
createUnionParser
|
|
201
|
+
createUnionParser([
|
|
247
202
|
smaliNewlinesParser,
|
|
248
203
|
smaliCommentParser,
|
|
249
204
|
]),
|
|
@@ -254,89 +209,31 @@ const smaliLineEndPraser: Parser<undefined | string, string> = promiseCompose(
|
|
|
254
209
|
]) => newlineOrComment,
|
|
255
210
|
);
|
|
256
211
|
|
|
257
|
-
const smaliIdentifierParser: Parser<string, string> =
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const character = await parserContext.peek(0);
|
|
262
|
-
|
|
263
|
-
parserContext.invariant(character !== undefined, 'Unexpected end of input');
|
|
264
|
-
|
|
265
|
-
invariant(character !== undefined, 'Unexpected end of input');
|
|
266
|
-
|
|
267
|
-
if (
|
|
268
|
-
character === '_'
|
|
269
|
-
|| (
|
|
270
|
-
character >= 'a' && character <= 'z'
|
|
271
|
-
)
|
|
272
|
-
|| (
|
|
273
|
-
character >= 'A' && character <= 'Z'
|
|
274
|
-
)
|
|
275
|
-
|| (
|
|
276
|
-
character >= '0' && character <= '9'
|
|
277
|
-
)
|
|
278
|
-
) {
|
|
279
|
-
parserContext.skip(1);
|
|
280
|
-
|
|
281
|
-
characters.push(character);
|
|
282
|
-
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
parserContext.invariant(characters.length > 0, 'Expected at least one character');
|
|
287
|
-
|
|
288
|
-
break;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return characters.join('');
|
|
292
|
-
};
|
|
212
|
+
const smaliIdentifierParser: Parser<string, string> = promiseCompose(
|
|
213
|
+
createRegExpParser(/[a-zA-Z0-9_]+/),
|
|
214
|
+
match => match[0],
|
|
215
|
+
);
|
|
293
216
|
|
|
294
217
|
setParserName(smaliIdentifierParser, 'smaliIdentifierParser');
|
|
295
218
|
|
|
296
|
-
const elementParser = createElementParser<string>();
|
|
297
|
-
|
|
298
219
|
const smaliHexNumberParser: Parser<number | bigint, string> = promiseCompose(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
() => elementParser,
|
|
304
|
-
character => async parserContext => {
|
|
305
|
-
parserContext.invariant(
|
|
306
|
-
(
|
|
307
|
-
(character >= '0' && character <= '9')
|
|
308
|
-
|| (character >= 'a' && character <= 'f')
|
|
309
|
-
|| (character >= 'A' && character <= 'F')
|
|
310
|
-
),
|
|
311
|
-
'Expected "0" to "9", "a" to "f", "A" to "F", got "%s"',
|
|
312
|
-
character,
|
|
313
|
-
);
|
|
220
|
+
createRegExpParser(/-?0x([0-9a-fA-F]+)(L)?/),
|
|
221
|
+
match => {
|
|
222
|
+
const hexDigits = match[1]!;
|
|
223
|
+
const optionalL = match[2];
|
|
314
224
|
|
|
315
|
-
return character;
|
|
316
|
-
},
|
|
317
|
-
)()),
|
|
318
|
-
createOptionalParser(createExactSequenceParser('L')),
|
|
319
|
-
]),
|
|
320
|
-
([
|
|
321
|
-
optionalMinus,
|
|
322
|
-
_0x,
|
|
323
|
-
valueCharacters,
|
|
324
|
-
optionalL,
|
|
325
|
-
]) => {
|
|
326
|
-
const value = valueCharacters.join('');
|
|
327
|
-
|
|
328
225
|
// If the 'L' suffix is present, use BigInt for long values
|
|
329
226
|
if (optionalL) {
|
|
330
|
-
const sign =
|
|
331
|
-
return sign * BigInt('0x' +
|
|
227
|
+
const sign = match[0].startsWith('-') ? -1n : 1n;
|
|
228
|
+
return sign * BigInt('0x' + hexDigits);
|
|
332
229
|
}
|
|
333
|
-
|
|
334
|
-
const sign =
|
|
335
|
-
return sign * Number.parseInt(
|
|
230
|
+
|
|
231
|
+
const sign = match[0].startsWith('-') ? -1 : 1;
|
|
232
|
+
return sign * Number.parseInt(hexDigits, 16);
|
|
336
233
|
},
|
|
337
234
|
);
|
|
338
235
|
|
|
339
|
-
const smaliNumberParser = createUnionParser
|
|
236
|
+
const smaliNumberParser = createUnionParser([
|
|
340
237
|
promiseCompose(
|
|
341
238
|
createTupleParser([
|
|
342
239
|
createNegativeLookaheadParser(createUnionParser([
|
|
@@ -383,7 +280,7 @@ const smaliNumberParser = createUnionParser<number, string>([
|
|
|
383
280
|
setParserName(smaliNumberParser, 'smaliNumberParser');
|
|
384
281
|
|
|
385
282
|
// Parser for field initial values that can include BigInt
|
|
386
|
-
const smaliFieldValueParser = createUnionParser
|
|
283
|
+
const smaliFieldValueParser = createUnionParser([
|
|
387
284
|
promiseCompose(
|
|
388
285
|
createTupleParser([
|
|
389
286
|
createNegativeLookaheadParser(createUnionParser([
|
|
@@ -424,7 +321,7 @@ const smaliQuotedStringParser: Parser<string, string> = promiseCompose(
|
|
|
424
321
|
const smaliCharacterLiteralParser: Parser<number, string> = promiseCompose(
|
|
425
322
|
createTupleParser([
|
|
426
323
|
createExactSequenceParser('\''),
|
|
427
|
-
createDisjunctionParser
|
|
324
|
+
createDisjunctionParser([
|
|
428
325
|
// Handle escape sequences (must come before regular characters)
|
|
429
326
|
promiseCompose(createExactSequenceParser(String.raw`\\`), () => '\\'),
|
|
430
327
|
promiseCompose(createExactSequenceParser(String.raw`\'`), () => '\''),
|
|
@@ -477,9 +374,9 @@ const smaliIdentifierContinuationParser: Parser<string, string> = async (parserC
|
|
|
477
374
|
setParserName(smaliIdentifierContinuationParser, 'smaliIdentifierContinuationParser');
|
|
478
375
|
|
|
479
376
|
// Helper to create an access flag parser with word boundary check
|
|
480
|
-
const createAccessFlagParser = (keyword:
|
|
377
|
+
const createAccessFlagParser = <const T extends string>(keyword: T): Parser<T, string> => promiseCompose(
|
|
481
378
|
createTupleParser([
|
|
482
|
-
createExactSequenceParser(keyword),
|
|
379
|
+
createExactSequenceParser(keyword) as Parser<T, string>,
|
|
483
380
|
createNegativeLookaheadParser(smaliIdentifierContinuationParser),
|
|
484
381
|
]),
|
|
485
382
|
([flag]) => flag,
|
|
@@ -487,7 +384,7 @@ const createAccessFlagParser = (keyword: string): Parser<typeof keyword, string>
|
|
|
487
384
|
|
|
488
385
|
const smaliAccessFlagsParser: Parser<DalvikExecutableAccessFlags, string> = promiseCompose(
|
|
489
386
|
createSeparatedArrayParser(
|
|
490
|
-
createUnionParser
|
|
387
|
+
createUnionParser([
|
|
491
388
|
createAccessFlagParser('public'),
|
|
492
389
|
createAccessFlagParser('protected'),
|
|
493
390
|
createAccessFlagParser('private'),
|
|
@@ -554,20 +451,11 @@ const smaliClassDeclarationParser: Parser<Pick<DalvikExecutableClassDefinition<u
|
|
|
554
451
|
|
|
555
452
|
setParserName(smaliClassDeclarationParser, 'smaliClassDeclarationParser');
|
|
556
453
|
|
|
557
|
-
const smaliSuperDeclarationParser: Parser<Pick<DalvikExecutableClassDefinition<unknown>, 'superclass'>, string> =
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
]),
|
|
563
|
-
([
|
|
564
|
-
_super,
|
|
565
|
-
superclass,
|
|
566
|
-
_newline,
|
|
567
|
-
]) => ({
|
|
568
|
-
superclass,
|
|
569
|
-
}),
|
|
570
|
-
);
|
|
454
|
+
const smaliSuperDeclarationParser: Parser<Pick<DalvikExecutableClassDefinition<unknown>, 'superclass'>, string> = createObjectParser({
|
|
455
|
+
_super: createExactSequenceParser('.super '),
|
|
456
|
+
superclass: smaliTypeDescriptorParser,
|
|
457
|
+
_newline: smaliLineEndPraser,
|
|
458
|
+
});
|
|
571
459
|
|
|
572
460
|
setParserName(smaliSuperDeclarationParser, 'smaliSuperDeclarationParser');
|
|
573
461
|
|
|
@@ -586,20 +474,11 @@ const smaliInterfaceDeclarationParser: Parser<string, string> = promiseCompose(
|
|
|
586
474
|
|
|
587
475
|
setParserName(smaliInterfaceDeclarationParser, 'smaliInterfaceDeclarationParser');
|
|
588
476
|
|
|
589
|
-
const smaliSourceDeclarationParser: Parser<Pick<DalvikExecutableClassDefinition<unknown>, 'sourceFile'>, string> =
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
]),
|
|
595
|
-
([
|
|
596
|
-
_source,
|
|
597
|
-
sourceFile,
|
|
598
|
-
_newline,
|
|
599
|
-
]) => ({
|
|
600
|
-
sourceFile,
|
|
601
|
-
}),
|
|
602
|
-
);
|
|
477
|
+
const smaliSourceDeclarationParser: Parser<Pick<DalvikExecutableClassDefinition<unknown>, 'sourceFile'>, string> = createObjectParser({
|
|
478
|
+
_source: createExactSequenceParser('.source '),
|
|
479
|
+
sourceFile: smaliQuotedStringParser,
|
|
480
|
+
_newline: smaliLineEndPraser,
|
|
481
|
+
});
|
|
603
482
|
|
|
604
483
|
// Wrapper type to distinguish different value types in smali annotation elements
|
|
605
484
|
type SmaliAnnotationElementValue =
|
|
@@ -613,28 +492,14 @@ type SmaliAnnotationElement = {
|
|
|
613
492
|
value: SmaliAnnotationElementValue;
|
|
614
493
|
};
|
|
615
494
|
|
|
616
|
-
const smaliEnumValueParser: Parser<DalvikExecutableField, string> =
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
]),
|
|
625
|
-
([
|
|
626
|
-
_enum,
|
|
627
|
-
classType,
|
|
628
|
-
_arrow,
|
|
629
|
-
fieldName,
|
|
630
|
-
_colon,
|
|
631
|
-
fieldType,
|
|
632
|
-
]) => ({
|
|
633
|
-
class: classType,
|
|
634
|
-
type: fieldType,
|
|
635
|
-
name: fieldName,
|
|
636
|
-
}),
|
|
637
|
-
);
|
|
495
|
+
const smaliEnumValueParser: Parser<DalvikExecutableField, string> = createObjectParser({
|
|
496
|
+
_enum: createExactSequenceParser('.enum '),
|
|
497
|
+
class: smaliTypeDescriptorParser,
|
|
498
|
+
_arrow: createExactSequenceParser('->'),
|
|
499
|
+
name: smaliMemberNameParser,
|
|
500
|
+
_colon: createExactSequenceParser(':'),
|
|
501
|
+
type: smaliTypeDescriptorParser,
|
|
502
|
+
});
|
|
638
503
|
|
|
639
504
|
setParserName(smaliEnumValueParser, 'smaliEnumValueParser');
|
|
640
505
|
|
|
@@ -665,24 +530,12 @@ const smaliMethodPrototypeParser: Parser<DalvikExecutablePrototype, string> = pr
|
|
|
665
530
|
|
|
666
531
|
setParserName(smaliMethodPrototypeParser, 'smaliMethodPrototypeParser');
|
|
667
532
|
|
|
668
|
-
const smaliParametersMethodParser: Parser<DalvikExecutableMethod, string> =
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
]),
|
|
675
|
-
([
|
|
676
|
-
classPath,
|
|
677
|
-
_separator,
|
|
678
|
-
methodName,
|
|
679
|
-
prototype,
|
|
680
|
-
]) => ({
|
|
681
|
-
class: classPath,
|
|
682
|
-
prototype,
|
|
683
|
-
name: methodName,
|
|
684
|
-
}),
|
|
685
|
-
);
|
|
533
|
+
const smaliParametersMethodParser: Parser<DalvikExecutableMethod, string> = createObjectParser({
|
|
534
|
+
class: smaliTypeDescriptorParser,
|
|
535
|
+
_separator: createExactSequenceParser('->'),
|
|
536
|
+
name: smaliMemberNameParser,
|
|
537
|
+
prototype: smaliMethodPrototypeParser,
|
|
538
|
+
});
|
|
686
539
|
|
|
687
540
|
setParserName(smaliParametersMethodParser, 'smaliParametersMethodParser');
|
|
688
541
|
|
|
@@ -700,46 +553,49 @@ const smaliAnnotationElementParser: Parser<SmaliAnnotationElement, string> = pro
|
|
|
700
553
|
smaliIdentifierParser,
|
|
701
554
|
createExactSequenceParser(' = '),
|
|
702
555
|
createDisjunctionParser([
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
value
|
|
706
|
-
),
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
value
|
|
710
|
-
),
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
value
|
|
714
|
-
),
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
value
|
|
718
|
-
),
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
value
|
|
722
|
-
),
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
value
|
|
726
|
-
),
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
556
|
+
createObjectParser({
|
|
557
|
+
kind: 'raw' as const,
|
|
558
|
+
value: createParserAccessorParser(() => smaliSubannotationParser),
|
|
559
|
+
}),
|
|
560
|
+
createObjectParser({
|
|
561
|
+
kind: 'enum' as const,
|
|
562
|
+
value: smaliEnumValueParser,
|
|
563
|
+
}),
|
|
564
|
+
createObjectParser({
|
|
565
|
+
kind: 'string' as const,
|
|
566
|
+
value: smaliQuotedStringParser,
|
|
567
|
+
}),
|
|
568
|
+
createObjectParser({
|
|
569
|
+
kind: 'raw' as const,
|
|
570
|
+
value: smaliParametersMethodParser,
|
|
571
|
+
}),
|
|
572
|
+
createObjectParser({
|
|
573
|
+
kind: 'type' as const,
|
|
574
|
+
value: smaliTypeDescriptorParser,
|
|
575
|
+
}),
|
|
576
|
+
createObjectParser({
|
|
577
|
+
kind: 'raw' as const,
|
|
578
|
+
value: smaliNumberParser,
|
|
579
|
+
}),
|
|
580
|
+
createObjectParser({
|
|
581
|
+
kind: 'raw' as const,
|
|
582
|
+
value: true as const,
|
|
583
|
+
_true: createExactSequenceParser('true'),
|
|
584
|
+
}),
|
|
585
|
+
createObjectParser({
|
|
586
|
+
kind: 'raw' as const,
|
|
587
|
+
value: false as const,
|
|
588
|
+
_false: createExactSequenceParser('false'),
|
|
589
|
+
}),
|
|
735
590
|
promiseCompose(
|
|
736
591
|
createExactSequenceParser('null'),
|
|
737
592
|
() => ({ kind: 'raw' as const, value: null }),
|
|
738
593
|
),
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
594
|
+
createObjectParser({
|
|
595
|
+
kind: 'raw' as const,
|
|
596
|
+
value: [] as const,
|
|
597
|
+
_emptyBraces: createExactSequenceParser('{}'),
|
|
598
|
+
}),
|
|
743
599
|
promiseCompose(
|
|
744
600
|
createTupleParser([
|
|
745
601
|
createExactSequenceParser('{\n'),
|
|
@@ -862,27 +718,14 @@ const smaliAnnotationElementParser: Parser<SmaliAnnotationElement, string> = pro
|
|
|
862
718
|
setParserName(smaliAnnotationElementParser, 'smaliAnnotationElementParser');
|
|
863
719
|
|
|
864
720
|
// Now define the subannotation parser
|
|
865
|
-
smaliSubannotationParser =
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
]),
|
|
874
|
-
([
|
|
875
|
-
_subannotation,
|
|
876
|
-
type,
|
|
877
|
-
_newline,
|
|
878
|
-
elements,
|
|
879
|
-
_indentation,
|
|
880
|
-
_endSubannotation,
|
|
881
|
-
]) => ({
|
|
882
|
-
type,
|
|
883
|
-
elements,
|
|
884
|
-
}),
|
|
885
|
-
);
|
|
721
|
+
smaliSubannotationParser = createObjectParser({
|
|
722
|
+
_subannotation: createExactSequenceParser('.subannotation '),
|
|
723
|
+
type: smaliTypeDescriptorParser,
|
|
724
|
+
_newline: smaliLineEndPraser,
|
|
725
|
+
elements: createArrayParser(smaliAnnotationElementParser),
|
|
726
|
+
_indentation: smaliIndentationParser,
|
|
727
|
+
_endSubannotation: createExactSequenceParser('.end subannotation'),
|
|
728
|
+
});
|
|
886
729
|
|
|
887
730
|
setParserName(smaliSubannotationParser, 'smaliSubannotationParser');
|
|
888
731
|
|
|
@@ -892,38 +735,21 @@ type SmaliAnnotation = {
|
|
|
892
735
|
visibility: 'build' | 'runtime' | 'system';
|
|
893
736
|
};
|
|
894
737
|
|
|
895
|
-
export const smaliAnnotationParser: Parser<SmaliAnnotation, string> =
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
createExactSequenceParser('system'),
|
|
903
|
-
]),
|
|
904
|
-
smaliSingleWhitespaceParser,
|
|
905
|
-
smaliTypeDescriptorParser,
|
|
906
|
-
smaliLineEndPraser,
|
|
907
|
-
createArrayParser(smaliAnnotationElementParser),
|
|
908
|
-
smaliIndentationParser,
|
|
909
|
-
createExactSequenceParser('.end annotation\n'),
|
|
738
|
+
export const smaliAnnotationParser: Parser<SmaliAnnotation, string> = createObjectParser({
|
|
739
|
+
_indentation0: smaliIndentationParser,
|
|
740
|
+
_annotation: createExactSequenceParser('.annotation '),
|
|
741
|
+
visibility: createUnionParser([
|
|
742
|
+
createExactSequenceParser('build' as const),
|
|
743
|
+
createExactSequenceParser('runtime' as const),
|
|
744
|
+
createExactSequenceParser('system' as const),
|
|
910
745
|
]),
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
elements,
|
|
919
|
-
_indentation1,
|
|
920
|
-
_endAnnotation,
|
|
921
|
-
]) => ({
|
|
922
|
-
type,
|
|
923
|
-
elements,
|
|
924
|
-
visibility,
|
|
925
|
-
}),
|
|
926
|
-
);
|
|
746
|
+
_space: smaliSingleWhitespaceParser,
|
|
747
|
+
type: smaliTypeDescriptorParser,
|
|
748
|
+
_newline: smaliLineEndPraser,
|
|
749
|
+
elements: createArrayParser(smaliAnnotationElementParser),
|
|
750
|
+
_indentation1: smaliIndentationParser,
|
|
751
|
+
_endAnnotation: createExactSequenceParser('.end annotation\n'),
|
|
752
|
+
});
|
|
927
753
|
|
|
928
754
|
setParserName(smaliAnnotationParser, 'smaliAnnotationParser');
|
|
929
755
|
|
|
@@ -949,7 +775,7 @@ export const smaliFieldParser: Parser<SmaliField, string> = promiseCompose(
|
|
|
949
775
|
createOptionalParser(promiseCompose(
|
|
950
776
|
createTupleParser([
|
|
951
777
|
createExactSequenceParser(' = '),
|
|
952
|
-
createUnionParser
|
|
778
|
+
createUnionParser([
|
|
953
779
|
smaliCharacterLiteralParser,
|
|
954
780
|
smaliFieldValueParser,
|
|
955
781
|
smaliQuotedStringParser,
|
|
@@ -1154,25 +980,16 @@ function isSmaliRegister(value: unknown): value is SmaliRegister {
|
|
|
1154
980
|
);
|
|
1155
981
|
}
|
|
1156
982
|
|
|
1157
|
-
const smaliParametersRegisterParser: Parser<SmaliRegister, string> =
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
smaliNumberParser,
|
|
1162
|
-
]),
|
|
1163
|
-
createTupleParser([
|
|
1164
|
-
createExactSequenceParser('p'),
|
|
1165
|
-
smaliNumberParser,
|
|
1166
|
-
]),
|
|
1167
|
-
]),
|
|
1168
|
-
([
|
|
1169
|
-
prefix,
|
|
1170
|
-
index,
|
|
1171
|
-
]) => ({
|
|
1172
|
-
prefix,
|
|
1173
|
-
index,
|
|
983
|
+
const smaliParametersRegisterParser: Parser<SmaliRegister, string> = createUnionParser([
|
|
984
|
+
createObjectParser({
|
|
985
|
+
prefix: createExactSequenceParser('v' as const),
|
|
986
|
+
index: smaliNumberParser,
|
|
1174
987
|
}),
|
|
1175
|
-
|
|
988
|
+
createObjectParser({
|
|
989
|
+
prefix: createExactSequenceParser('p' as const),
|
|
990
|
+
index: smaliNumberParser,
|
|
991
|
+
}),
|
|
992
|
+
]);
|
|
1176
993
|
|
|
1177
994
|
setParserName(smaliParametersRegisterParser, 'smaliParametersRegisterParser');
|
|
1178
995
|
|
|
@@ -1180,6 +997,7 @@ type SmaliCodeLocal = {
|
|
|
1180
997
|
register: SmaliRegister;
|
|
1181
998
|
name: string | undefined;
|
|
1182
999
|
type: string | undefined;
|
|
1000
|
+
signature: string | undefined;
|
|
1183
1001
|
};
|
|
1184
1002
|
|
|
1185
1003
|
const smaliCodeLocalParser: Parser<SmaliCodeLocal, string> = promiseCompose(
|
|
@@ -1192,6 +1010,11 @@ const smaliCodeLocalParser: Parser<SmaliCodeLocal, string> = promiseCompose(
|
|
|
1192
1010
|
smaliQuotedStringParser,
|
|
1193
1011
|
createExactSequenceParser(':'),
|
|
1194
1012
|
smaliTypeDescriptorParser,
|
|
1013
|
+
createOptionalParser(createTupleParser([
|
|
1014
|
+
createExactSequenceParser(','),
|
|
1015
|
+
smaliWhitespaceParser,
|
|
1016
|
+
smaliQuotedStringParser,
|
|
1017
|
+
])),
|
|
1195
1018
|
])),
|
|
1196
1019
|
smaliLineEndPraser,
|
|
1197
1020
|
]),
|
|
@@ -1203,6 +1026,7 @@ const smaliCodeLocalParser: Parser<SmaliCodeLocal, string> = promiseCompose(
|
|
|
1203
1026
|
register,
|
|
1204
1027
|
name: nameAndType?.[2],
|
|
1205
1028
|
type: nameAndType?.[4],
|
|
1029
|
+
signature: nameAndType?.[5]?.[2],
|
|
1206
1030
|
}),
|
|
1207
1031
|
);
|
|
1208
1032
|
|
|
@@ -1341,52 +1165,33 @@ type SmaliCatchDirective = {
|
|
|
1341
1165
|
handlerLabel: string;
|
|
1342
1166
|
};
|
|
1343
1167
|
|
|
1344
|
-
const smaliCatchDirectiveParser: Parser<SmaliCatchDirective, string> =
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
),
|
|
1363
|
-
]),
|
|
1364
|
-
createExactSequenceParser(' {'),
|
|
1365
|
-
smaliCodeLabelParser,
|
|
1366
|
-
createExactSequenceParser(' .. '),
|
|
1367
|
-
smaliCodeLabelParser,
|
|
1368
|
-
createExactSequenceParser('} '),
|
|
1369
|
-
smaliCodeLabelParser,
|
|
1370
|
-
smaliLineEndPraser,
|
|
1168
|
+
const smaliCatchDirectiveParser: Parser<SmaliCatchDirective, string> = createObjectParser({
|
|
1169
|
+
_indentation: smaliIndentationParser,
|
|
1170
|
+
_catch: createExactSequenceParser('.catch'),
|
|
1171
|
+
type: createUnionParser([
|
|
1172
|
+
promiseCompose(
|
|
1173
|
+
createExactSequenceParser('all'),
|
|
1174
|
+
() => undefined as undefined,
|
|
1175
|
+
),
|
|
1176
|
+
promiseCompose(
|
|
1177
|
+
createTupleParser([
|
|
1178
|
+
createExactSequenceParser(' '),
|
|
1179
|
+
smaliTypeDescriptorParser,
|
|
1180
|
+
]),
|
|
1181
|
+
([
|
|
1182
|
+
_space,
|
|
1183
|
+
type,
|
|
1184
|
+
]) => type,
|
|
1185
|
+
),
|
|
1371
1186
|
]),
|
|
1372
|
-
(
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
_closeBrace,
|
|
1381
|
-
handlerLabel,
|
|
1382
|
-
_newline,
|
|
1383
|
-
]) => ({
|
|
1384
|
-
type,
|
|
1385
|
-
startLabel,
|
|
1386
|
-
endLabel,
|
|
1387
|
-
handlerLabel,
|
|
1388
|
-
}),
|
|
1389
|
-
);
|
|
1187
|
+
_openBrace: createExactSequenceParser(' {'),
|
|
1188
|
+
startLabel: smaliCodeLabelParser,
|
|
1189
|
+
_dots: createExactSequenceParser(' .. '),
|
|
1190
|
+
endLabel: smaliCodeLabelParser,
|
|
1191
|
+
_closeBrace: createExactSequenceParser('} '),
|
|
1192
|
+
handlerLabel: smaliCodeLabelParser,
|
|
1193
|
+
_newline: smaliLineEndPraser,
|
|
1194
|
+
});
|
|
1390
1195
|
|
|
1391
1196
|
setParserName(smaliCatchDirectiveParser, 'smaliCatchDirectiveParser');
|
|
1392
1197
|
|
|
@@ -1395,23 +1200,12 @@ type SmaliLabeledCatchDirective = {
|
|
|
1395
1200
|
catchDirective: SmaliCatchDirective;
|
|
1396
1201
|
};
|
|
1397
1202
|
|
|
1398
|
-
const smaliLabeledCatchDirectiveParser: Parser<SmaliLabeledCatchDirective, string> =
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
]),
|
|
1405
|
-
([
|
|
1406
|
-
_lines,
|
|
1407
|
-
_local,
|
|
1408
|
-
labels,
|
|
1409
|
-
catchDirective,
|
|
1410
|
-
]) => ({
|
|
1411
|
-
labels,
|
|
1412
|
-
catchDirective,
|
|
1413
|
-
}),
|
|
1414
|
-
);
|
|
1203
|
+
const smaliLabeledCatchDirectiveParser: Parser<SmaliLabeledCatchDirective, string> = createObjectParser({
|
|
1204
|
+
_lines: createArrayParser(smaliCodeLineParser),
|
|
1205
|
+
_local: createOptionalParser(smaliCodeLocalParser),
|
|
1206
|
+
labels: createArrayParser(smaliCodeLabelLineParser),
|
|
1207
|
+
catchDirective: smaliCatchDirectiveParser,
|
|
1208
|
+
});
|
|
1415
1209
|
|
|
1416
1210
|
setParserName(smaliLabeledCatchDirectiveParser, 'smaliLabeledCatchDirectiveParser');
|
|
1417
1211
|
|
|
@@ -1490,57 +1284,20 @@ const smaliParametersStringParser: Parser<string, string> = cloneParser(smaliQuo
|
|
|
1490
1284
|
setParserName(smaliParametersStringParser, 'smaliParametersStringParser');
|
|
1491
1285
|
|
|
1492
1286
|
const smaliParametersIntegerParser: Parser<number | bigint, string> = promiseCompose(
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
const characters: string[] = [];
|
|
1498
|
-
|
|
1499
|
-
while (true) {
|
|
1500
|
-
const character = await parserContext.peek(0);
|
|
1501
|
-
|
|
1502
|
-
parserContext.invariant(character !== undefined, 'Unexpected end of input');
|
|
1503
|
-
|
|
1504
|
-
invariant(character !== undefined, 'Unexpected end of input');
|
|
1287
|
+
createRegExpParser(/-?0x([0-9a-fA-F]+)([Lts])?/),
|
|
1288
|
+
match => {
|
|
1289
|
+
const hexDigits = match[1]!;
|
|
1290
|
+
const optionalSuffix = match[2];
|
|
1505
1291
|
|
|
1506
|
-
if (
|
|
1507
|
-
(character >= '0' && character <= '9')
|
|
1508
|
-
|| (character >= 'a' && character <= 'f')
|
|
1509
|
-
|| (character >= 'A' && character <= 'F')
|
|
1510
|
-
) {
|
|
1511
|
-
characters.push(character);
|
|
1512
|
-
|
|
1513
|
-
parserContext.skip(1);
|
|
1514
|
-
|
|
1515
|
-
continue;
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
break;
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
return characters.join('');
|
|
1522
|
-
},
|
|
1523
|
-
createOptionalParser(createUnionParser([
|
|
1524
|
-
createExactSequenceParser('L'),
|
|
1525
|
-
createExactSequenceParser('t'),
|
|
1526
|
-
createExactSequenceParser('s'),
|
|
1527
|
-
])),
|
|
1528
|
-
]),
|
|
1529
|
-
([
|
|
1530
|
-
optionalMinus,
|
|
1531
|
-
_0x,
|
|
1532
|
-
value,
|
|
1533
|
-
optionalSuffix,
|
|
1534
|
-
]) => {
|
|
1535
1292
|
if (optionalSuffix === 'L') {
|
|
1536
|
-
const sign =
|
|
1293
|
+
const sign = match[0].startsWith('-') ? -1n : 1n;
|
|
1537
1294
|
|
|
1538
|
-
return sign * BigInt('0x' +
|
|
1295
|
+
return sign * BigInt('0x' + hexDigits);
|
|
1539
1296
|
}
|
|
1540
1297
|
|
|
1541
|
-
const sign =
|
|
1298
|
+
const sign = match[0].startsWith('-') ? -1 : 1;
|
|
1542
1299
|
|
|
1543
|
-
return sign * Number.parseInt(
|
|
1300
|
+
return sign * Number.parseInt(hexDigits, 16);
|
|
1544
1301
|
},
|
|
1545
1302
|
);
|
|
1546
1303
|
|
|
@@ -1563,26 +1320,13 @@ const smaliParametersTypeParser: Parser<string, string> = cloneParser(smaliTypeD
|
|
|
1563
1320
|
|
|
1564
1321
|
setParserName(smaliParametersTypeParser, 'smaliParametersTypeParser');
|
|
1565
1322
|
|
|
1566
|
-
const smaliParametersFieldParser: Parser<DalvikExecutableField, string> =
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
]),
|
|
1574
|
-
([
|
|
1575
|
-
classPath,
|
|
1576
|
-
_separator,
|
|
1577
|
-
fieldName,
|
|
1578
|
-
_colon,
|
|
1579
|
-
type,
|
|
1580
|
-
]) => ({
|
|
1581
|
-
class: classPath,
|
|
1582
|
-
name: fieldName,
|
|
1583
|
-
type,
|
|
1584
|
-
}),
|
|
1585
|
-
);
|
|
1323
|
+
const smaliParametersFieldParser: Parser<DalvikExecutableField, string> = createObjectParser({
|
|
1324
|
+
class: smaliTypeDescriptorParser,
|
|
1325
|
+
_separator: createExactSequenceParser('->'),
|
|
1326
|
+
name: smaliMemberNameParser,
|
|
1327
|
+
_colon: createExactSequenceParser(':'),
|
|
1328
|
+
type: smaliTypeDescriptorParser,
|
|
1329
|
+
});
|
|
1586
1330
|
|
|
1587
1331
|
setParserName(smaliParametersFieldParser, 'smaliParametersFieldParser');
|
|
1588
1332
|
|
|
@@ -1590,12 +1334,15 @@ type SmaliCodeOperationParameter =
|
|
|
1590
1334
|
| SmaliRegister
|
|
1591
1335
|
| SmaliRegister[]
|
|
1592
1336
|
| string
|
|
1337
|
+
| number
|
|
1338
|
+
| bigint
|
|
1593
1339
|
| DalvikExecutableMethod
|
|
1340
|
+
| DalvikExecutableField
|
|
1594
1341
|
;
|
|
1595
1342
|
|
|
1596
1343
|
const smaliCodeOperationParametersParser: Parser<SmaliCodeOperationParameter[], string> = createArrayParser(promiseCompose(
|
|
1597
1344
|
createTupleParser([
|
|
1598
|
-
createUnionParser
|
|
1345
|
+
createUnionParser([
|
|
1599
1346
|
smaliParametersRegisterParser,
|
|
1600
1347
|
smaliParametersRegistersParser,
|
|
1601
1348
|
smaliParametersStringParser,
|
|
@@ -1663,29 +1410,18 @@ type SmaliOneLineCodeOperation = {
|
|
|
1663
1410
|
parameters: SmaliCodeOperationParameter[];
|
|
1664
1411
|
};
|
|
1665
1412
|
|
|
1666
|
-
const smaliOneLineCodeOperationParser: Parser<SmaliOneLineCodeOperation, string> =
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
]),
|
|
1679
|
-
([
|
|
1680
|
-
_indent,
|
|
1681
|
-
operation,
|
|
1682
|
-
parameters,
|
|
1683
|
-
_newline,
|
|
1684
|
-
]) => ({
|
|
1685
|
-
operation,
|
|
1686
|
-
parameters,
|
|
1687
|
-
}),
|
|
1688
|
-
);
|
|
1413
|
+
const smaliOneLineCodeOperationParser: Parser<SmaliOneLineCodeOperation, string> = createObjectParser({
|
|
1414
|
+
_indent: smaliSingleIndentationParser,
|
|
1415
|
+
operation: smaliCodeOperationNameParser,
|
|
1416
|
+
parameters: promiseCompose(
|
|
1417
|
+
createOptionalParser(createTupleParser([
|
|
1418
|
+
smaliSingleWhitespaceParser,
|
|
1419
|
+
smaliCodeOperationParametersParser,
|
|
1420
|
+
])),
|
|
1421
|
+
undefinedOrParameters => undefinedOrParameters === undefined ? [] : undefinedOrParameters[1],
|
|
1422
|
+
),
|
|
1423
|
+
_newline: smaliLineEndPraser,
|
|
1424
|
+
});
|
|
1689
1425
|
|
|
1690
1426
|
setParserName(smaliOneLineCodeOperationParser, 'smaliOneLineCodeOperationParser');
|
|
1691
1427
|
|
|
@@ -1841,17 +1577,21 @@ const smaliLooseCodeOperationParser: Parser<SmaliLooseCodeOperation, string> = c
|
|
|
1841
1577
|
|
|
1842
1578
|
setParserName(smaliLooseCodeOperationParser, 'smaliLooseCodeOperationParser');
|
|
1843
1579
|
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1580
|
+
// SmaliCodeOperation transforms DalvikBytecodeOperation:
|
|
1581
|
+
// - targetInstructionIndex -> branchOffsetIndex (intermediate form during parsing, relative)
|
|
1582
|
+
// - targetInstructionIndices -> branchOffsetIndices (intermediate form during parsing, relative)
|
|
1583
|
+
// - methodIndex -> method (resolved)
|
|
1584
|
+
type SmaliCodeOperationFromDalvikOperation<T extends DalvikBytecodeOperation> =
|
|
1585
|
+
T extends { targetInstructionIndices: number[] }
|
|
1586
|
+
? Simplify<Omit<T, 'targetInstructionIndices'> & { branchOffsetIndices: number[] }>
|
|
1587
|
+
: T extends { targetInstructionIndex: number }
|
|
1588
|
+
? Simplify<Omit<T, 'targetInstructionIndex'> & { branchOffsetIndex: number }>
|
|
1849
1589
|
: T extends { methodIndex: IndexIntoMethodIds }
|
|
1850
1590
|
? Simplify<Omit<T, 'methodIndex'> & { method: DalvikExecutableMethod }>
|
|
1851
1591
|
: T
|
|
1852
1592
|
;
|
|
1853
1593
|
|
|
1854
|
-
type SmaliCodeOperation =
|
|
1594
|
+
type SmaliCodeOperation = SmaliCodeOperationFromDalvikOperation<DalvikBytecodeOperation>;
|
|
1855
1595
|
|
|
1856
1596
|
export const smaliCodeOperationParser: Parser<SmaliCodeOperation, string> = promiseCompose(
|
|
1857
1597
|
smaliLooseCodeOperationParser,
|
|
@@ -2240,41 +1980,15 @@ const smaliExecutableCodeParser: Parser<SmaliExecutableCode<DalvikBytecode>, str
|
|
|
2240
1980
|
}
|
|
2241
1981
|
}
|
|
2242
1982
|
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
let operationOffset = 0;
|
|
2246
|
-
|
|
2247
|
-
for (const [ operationIndex, operation ] of instructions.entries()) {
|
|
2248
|
-
const operationSize = getOperationFormatSize(operation);
|
|
2249
|
-
|
|
2250
|
-
branchOffsetByBranchOffsetIndex.set(
|
|
2251
|
-
operationIndex,
|
|
2252
|
-
operationOffset,
|
|
2253
|
-
);
|
|
2254
|
-
|
|
2255
|
-
operationOffset += operationSize;
|
|
2256
|
-
}
|
|
2257
|
-
|
|
1983
|
+
// Convert branchOffsetIndex (relative) to targetInstructionIndex (absolute)
|
|
2258
1984
|
for (const [ operationIndex, operation ] of instructions.entries()) {
|
|
2259
1985
|
if (
|
|
2260
1986
|
'branchOffsetIndex' in operation
|
|
2261
1987
|
&& typeof operation.branchOffsetIndex === 'number'
|
|
2262
1988
|
) {
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
'Expected branch offset for operation index %s, but got undefined',
|
|
2267
|
-
operation.branchOffsetIndex,
|
|
2268
|
-
);
|
|
2269
|
-
|
|
2270
|
-
const branchOffset = branchOffsetByBranchOffsetIndex.get(operationIndex);
|
|
2271
|
-
invariant(
|
|
2272
|
-
branchOffset !== undefined,
|
|
2273
|
-
'Expected branch offset for operation index %s, but got undefined',
|
|
2274
|
-
operationIndex,
|
|
2275
|
-
);
|
|
2276
|
-
|
|
2277
|
-
(operation as any).branchOffset = operationOffset - branchOffset;
|
|
1989
|
+
// branchOffsetIndex is the relative instruction index from the label
|
|
1990
|
+
// targetInstructionIndex is the absolute instruction index
|
|
1991
|
+
(operation as any).targetInstructionIndex = operationIndex + operation.branchOffsetIndex;
|
|
2278
1992
|
}
|
|
2279
1993
|
|
|
2280
1994
|
if (
|
|
@@ -2297,22 +2011,11 @@ const smaliExecutableCodeParser: Parser<SmaliExecutableCode<DalvikBytecode>, str
|
|
|
2297
2011
|
const [ sourceOperation ] = sourceOperations;
|
|
2298
2012
|
const sourceOperationIndex = instructions.indexOf(sourceOperation);
|
|
2299
2013
|
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
sourceOperationIndex + branchOffsetIndex,
|
|
2306
|
-
);
|
|
2307
|
-
|
|
2308
|
-
const branchOffset = branchOffsetByBranchOffsetIndex.get(sourceOperationIndex);
|
|
2309
|
-
invariant(
|
|
2310
|
-
branchOffset !== undefined,
|
|
2311
|
-
'Expected branch offset for operation index %s, but got undefined',
|
|
2312
|
-
sourceOperationIndex,
|
|
2313
|
-
);
|
|
2314
|
-
|
|
2315
|
-
return operationOffset - branchOffset;
|
|
2014
|
+
// For payload instructions, branchOffsetIndices contains instruction-relative indices
|
|
2015
|
+
// from the source switch instruction. Convert to absolute instruction indices.
|
|
2016
|
+
(operation as any).targetInstructionIndices = operation.branchOffsetIndices.map((branchOffsetIndex: number) => {
|
|
2017
|
+
// branchOffsetIndex is relative to the source operation
|
|
2018
|
+
return sourceOperationIndex + branchOffsetIndex;
|
|
2316
2019
|
});
|
|
2317
2020
|
}
|
|
2318
2021
|
}
|
|
@@ -2356,11 +2059,12 @@ const smaliExecutableCodeParser: Parser<SmaliExecutableCode<DalvikBytecode>, str
|
|
|
2356
2059
|
}
|
|
2357
2060
|
|
|
2358
2061
|
// Build tries array from catch directives
|
|
2062
|
+
// Now using instruction indices directly instead of code unit offsets
|
|
2359
2063
|
const triesByRange = new Map<string, {
|
|
2360
|
-
|
|
2064
|
+
startInstructionIndex: number;
|
|
2361
2065
|
instructionCount: number;
|
|
2362
|
-
handlers: Array<{ type: string;
|
|
2363
|
-
|
|
2066
|
+
handlers: Array<{ type: string; handlerInstructionIndex: number }>;
|
|
2067
|
+
catchAllInstructionIndex: number | undefined;
|
|
2364
2068
|
}>();
|
|
2365
2069
|
|
|
2366
2070
|
for (const catchDirective of catchDirectives) {
|
|
@@ -2373,56 +2077,64 @@ const smaliExecutableCodeParser: Parser<SmaliExecutableCode<DalvikBytecode>, str
|
|
|
2373
2077
|
invariant(endIndex !== undefined, 'Expected to find end label %s', catchDirective.endLabel);
|
|
2374
2078
|
invariant(handlerIndex !== undefined, 'Expected to find handler label %s', catchDirective.handlerLabel);
|
|
2375
2079
|
|
|
2376
|
-
|
|
2377
|
-
const
|
|
2378
|
-
const
|
|
2379
|
-
|
|
2380
|
-
invariant(startAddress !== undefined, 'Expected start address for index %s', startIndex);
|
|
2381
|
-
invariant(endAddress !== undefined, 'Expected end address for index %s', endIndex);
|
|
2382
|
-
invariant(handlerAddress !== undefined, 'Expected handler address for index %s', handlerIndex);
|
|
2080
|
+
// Use instruction indices directly
|
|
2081
|
+
const startInstructionIndex = startIndex;
|
|
2082
|
+
const instructionCount = endIndex - startIndex;
|
|
2083
|
+
const handlerInstructionIndex = handlerIndex;
|
|
2383
2084
|
|
|
2384
|
-
const
|
|
2385
|
-
const rangeKey = `${startAddress}-${instructionCount}`;
|
|
2085
|
+
const rangeKey = `${startInstructionIndex}-${instructionCount}`;
|
|
2386
2086
|
|
|
2387
2087
|
let tryEntry = triesByRange.get(rangeKey);
|
|
2388
2088
|
if (!tryEntry) {
|
|
2389
2089
|
tryEntry = {
|
|
2390
|
-
|
|
2090
|
+
startInstructionIndex,
|
|
2391
2091
|
instructionCount,
|
|
2392
2092
|
handlers: [],
|
|
2393
|
-
|
|
2093
|
+
catchAllInstructionIndex: undefined as number | undefined,
|
|
2394
2094
|
};
|
|
2395
2095
|
triesByRange.set(rangeKey, tryEntry);
|
|
2396
2096
|
}
|
|
2397
2097
|
|
|
2398
2098
|
if (catchDirective.type === undefined) {
|
|
2399
2099
|
// .catchall
|
|
2400
|
-
tryEntry.
|
|
2100
|
+
tryEntry.catchAllInstructionIndex = handlerInstructionIndex;
|
|
2401
2101
|
} else {
|
|
2402
2102
|
// .catch Type
|
|
2403
2103
|
tryEntry.handlers.push({
|
|
2404
2104
|
type: catchDirective.type,
|
|
2405
|
-
|
|
2105
|
+
handlerInstructionIndex,
|
|
2406
2106
|
});
|
|
2407
2107
|
}
|
|
2408
2108
|
}
|
|
2409
2109
|
|
|
2410
2110
|
const tries = Array.from(triesByRange.values()).map(tryEntry => ({
|
|
2411
|
-
|
|
2111
|
+
startInstructionIndex: tryEntry.startInstructionIndex,
|
|
2412
2112
|
instructionCount: tryEntry.instructionCount,
|
|
2413
2113
|
handler: {
|
|
2414
2114
|
handlers: tryEntry.handlers,
|
|
2415
|
-
|
|
2115
|
+
catchAllInstructionIndex: tryEntry.catchAllInstructionIndex,
|
|
2416
2116
|
},
|
|
2417
2117
|
}));
|
|
2418
2118
|
|
|
2119
|
+
// Build debug info from debug directives
|
|
2120
|
+
// Debug info still uses code unit offsets (addressDiff), so we need to build the mapping
|
|
2121
|
+
// IMPORTANT: Must be done BEFORE deleting branchOffsetIndices, as getOperationSizeInCodeUnits uses it
|
|
2122
|
+
const codeUnitOffsetByInstructionIndex = new Map<number, number>();
|
|
2123
|
+
let codeUnitOffset = 0;
|
|
2124
|
+
for (let i = 0; i < instructions.length; i++) {
|
|
2125
|
+
codeUnitOffsetByInstructionIndex.set(i, codeUnitOffset);
|
|
2126
|
+
codeUnitOffset += getOperationSizeInCodeUnits(instructions[i]);
|
|
2127
|
+
}
|
|
2128
|
+
codeUnitOffsetByInstructionIndex.set(instructions.length, codeUnitOffset);
|
|
2129
|
+
// Alias for backward compatibility with debug info code
|
|
2130
|
+
const branchOffsetByBranchOffsetIndex = codeUnitOffsetByInstructionIndex;
|
|
2131
|
+
|
|
2419
2132
|
for (const operation of instructions) {
|
|
2420
2133
|
delete (operation as any).labels;
|
|
2421
2134
|
delete (operation as any).branchOffsetIndex;
|
|
2422
2135
|
delete (operation as any).branchOffsetIndices;
|
|
2423
2136
|
}
|
|
2424
2137
|
|
|
2425
|
-
// Build debug info from debug directives
|
|
2426
2138
|
type DebugByteCodeValue = DalvikExecutableDebugInfo['bytecode'][number];
|
|
2427
2139
|
let debugInfo: DalvikExecutableDebugInfo | undefined;
|
|
2428
2140
|
const debugBytecode: DebugByteCodeValue[] = [];
|
|
@@ -2741,7 +2453,7 @@ export const smaliMethodParser: Parser<SmaliMethod<DalvikBytecode>, string> = pr
|
|
|
2741
2453
|
code.insSize = insSize;
|
|
2742
2454
|
|
|
2743
2455
|
for (const operation of code.instructions) {
|
|
2744
|
-
const smaliRegisters =
|
|
2456
|
+
const smaliRegisters = rawDalvikBytecodeOperationCompanion.getRegisters(operation as RawDalvikBytecodeOperation) as unknown[] as SmaliRegister[]; // TODO
|
|
2745
2457
|
|
|
2746
2458
|
if (smaliRegisters.length === 0) {
|
|
2747
2459
|
continue;
|
|
@@ -2769,7 +2481,7 @@ export const smaliMethodParser: Parser<SmaliMethod<DalvikBytecode>, string> = pr
|
|
|
2769
2481
|
continue;
|
|
2770
2482
|
}
|
|
2771
2483
|
|
|
2772
|
-
const registers =
|
|
2484
|
+
const registers = rawDalvikBytecodeOperationCompanion.getRegisters(operation as RawDalvikBytecodeOperation);
|
|
2773
2485
|
|
|
2774
2486
|
outsSize = Math.max(outsSize, registers.length); // TODO?: two words for wide types?
|
|
2775
2487
|
}
|
|
@@ -2829,7 +2541,7 @@ type SmaliMethods = Pick<DalvikExecutableClassData<DalvikBytecode>, 'directMetho
|
|
|
2829
2541
|
};
|
|
2830
2542
|
|
|
2831
2543
|
const smaliMethodsParser: Parser<SmaliMethods, string> = promiseCompose(
|
|
2832
|
-
createArrayParser
|
|
2544
|
+
createArrayParser(createDisjunctionParser([
|
|
2833
2545
|
smaliMethodParser,
|
|
2834
2546
|
smaliCommentsOrNewlinesParser,
|
|
2835
2547
|
])),
|