@futpib/parser 1.0.4 → 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 +6 -1
- package/build/bashParser.js +131 -90
- package/build/bashParser.test.js +162 -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 +3 -2
- package/build/index.js +2 -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.js +33 -3
- package/build/regexpParser.test.js +31 -0
- package/build/regularExpressionParser.js +35 -15
- 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 +24 -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 +8 -1
- package/src/bashParser.test.ts +258 -0
- package/src/bashParser.ts +180 -143
- 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 +7 -1
- 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 +78 -0
- package/src/regexpParser.ts +35 -3
- package/src/regularExpressionParser.ts +36 -37
- 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/build/parserError.js
CHANGED
|
@@ -15,7 +15,11 @@ export function isParserParsingFailedError(value) {
|
|
|
15
15
|
&& 'depth' in value
|
|
16
16
|
&& typeof value.depth === 'number'
|
|
17
17
|
&& 'position' in value
|
|
18
|
-
&& typeof value.position === 'number'
|
|
18
|
+
&& typeof value.position === 'number'
|
|
19
|
+
&& 'furthestReadPosition' in value
|
|
20
|
+
&& typeof value.furthestReadPosition === 'number'
|
|
21
|
+
&& 'furthestPeekedPosition' in value
|
|
22
|
+
&& typeof value.furthestPeekedPosition === 'number');
|
|
19
23
|
}
|
|
20
24
|
export function isParserParsingJoinError(value) {
|
|
21
25
|
return (typeof value === 'object'
|
|
@@ -40,11 +44,15 @@ function createParserErrorModule(BaseLazyMessageError) {
|
|
|
40
44
|
class ParserParsingFailedError extends ParserError {
|
|
41
45
|
depth;
|
|
42
46
|
position;
|
|
47
|
+
furthestReadPosition;
|
|
48
|
+
furthestPeekedPosition;
|
|
43
49
|
name = 'ParserParsingFailedError';
|
|
44
|
-
constructor(message, depth, position) {
|
|
50
|
+
constructor(message, depth, position, furthestReadPosition, furthestPeekedPosition) {
|
|
45
51
|
super(message);
|
|
46
52
|
this.depth = depth;
|
|
47
53
|
this.position = position;
|
|
54
|
+
this.furthestReadPosition = furthestReadPosition;
|
|
55
|
+
this.furthestPeekedPosition = furthestPeekedPosition;
|
|
48
56
|
}
|
|
49
57
|
}
|
|
50
58
|
class ParserParsingJoinError extends ParserParsingFailedError {
|
|
@@ -57,24 +65,24 @@ function createParserErrorModule(BaseLazyMessageError) {
|
|
|
57
65
|
class ParserParsingJoinAllError extends ParserParsingJoinError {
|
|
58
66
|
childErrors;
|
|
59
67
|
name = 'ParserParsingJoinAllError';
|
|
60
|
-
constructor(message, depth, position, childErrors) {
|
|
61
|
-
super(message, depth, position);
|
|
68
|
+
constructor(message, depth, position, furthestReadPosition, furthestPeekedPosition, childErrors) {
|
|
69
|
+
super(message, depth, position, furthestReadPosition, furthestPeekedPosition);
|
|
62
70
|
this.childErrors = childErrors;
|
|
63
71
|
}
|
|
64
72
|
}
|
|
65
73
|
class ParserParsingJoinDeepestError extends ParserParsingJoinError {
|
|
66
74
|
childErrors;
|
|
67
75
|
name = 'ParserParsingJoinDeepestError';
|
|
68
|
-
constructor(message, depth, position, childErrors) {
|
|
69
|
-
super(message, depth, position);
|
|
76
|
+
constructor(message, depth, position, furthestReadPosition, furthestPeekedPosition, childErrors) {
|
|
77
|
+
super(message, depth, position, furthestReadPosition, furthestPeekedPosition);
|
|
70
78
|
this.childErrors = childErrors;
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
class ParserParsingJoinFurthestError extends ParserParsingJoinError {
|
|
74
82
|
childErrors;
|
|
75
83
|
name = 'ParserParsingJoinFurthestError';
|
|
76
|
-
constructor(message, depth, position, childErrors) {
|
|
77
|
-
super(message, depth, position);
|
|
84
|
+
constructor(message, depth, position, furthestReadPosition, furthestPeekedPosition, childErrors) {
|
|
85
|
+
super(message, depth, position, furthestReadPosition, furthestPeekedPosition);
|
|
78
86
|
this.childErrors = childErrors;
|
|
79
87
|
}
|
|
80
88
|
}
|
package/build/regexpParser.js
CHANGED
|
@@ -5,14 +5,44 @@ export const createRegExpParser = (regexp) => {
|
|
|
5
5
|
let window = 1;
|
|
6
6
|
let lastMatch;
|
|
7
7
|
let reachedEndOfInput = false;
|
|
8
|
+
let inputLength;
|
|
8
9
|
while (true) {
|
|
9
10
|
const sequence = await parserContext.peekSequence(start, start + window);
|
|
10
11
|
if (sequence === undefined) {
|
|
11
|
-
reachedEndOfInput
|
|
12
|
+
if (!reachedEndOfInput) {
|
|
13
|
+
reachedEndOfInput = true;
|
|
14
|
+
// Binary search to find actual input length
|
|
15
|
+
// We know: length >= start (we've peeked successfully before)
|
|
16
|
+
// We know: length < start + window (current peek failed)
|
|
17
|
+
let lo = start;
|
|
18
|
+
let hi = start + window;
|
|
19
|
+
while (hi - lo > 1) {
|
|
20
|
+
const mid = (lo + hi) >> 1;
|
|
21
|
+
const probe = await parserContext.peekSequence(0, mid);
|
|
22
|
+
if (probe !== undefined) {
|
|
23
|
+
lo = mid;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
hi = mid;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
inputLength = lo;
|
|
30
|
+
// Try matching against the full input
|
|
31
|
+
if (inputLength > 0) {
|
|
32
|
+
const fullInput = await parserContext.peekSequence(0, inputLength);
|
|
33
|
+
if (fullInput !== undefined) {
|
|
34
|
+
const match = regexp.exec(fullInput);
|
|
35
|
+
if (match !== null && match.index === 0) {
|
|
36
|
+
parserContext.skip(match[0].length);
|
|
37
|
+
return match;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
12
42
|
window = Math.floor(window / 2);
|
|
13
43
|
if (window === 0) {
|
|
14
44
|
// Get the full sequence we've accumulated to verify matches
|
|
15
|
-
const fullSequence = await parserContext.peekSequence(0, start);
|
|
45
|
+
const fullSequence = await parserContext.peekSequence(0, inputLength ?? start);
|
|
16
46
|
// Verify any previous match is still valid with full context
|
|
17
47
|
// For lookahead/lookbehind assertions, additional input might invalidate a match
|
|
18
48
|
if (fullSequence !== undefined) {
|
|
@@ -36,7 +66,7 @@ export const createRegExpParser = (regexp) => {
|
|
|
36
66
|
}
|
|
37
67
|
continue;
|
|
38
68
|
}
|
|
39
|
-
const fullSequence = await parserContext.peekSequence(0, start + window);
|
|
69
|
+
const fullSequence = await parserContext.peekSequence(0, inputLength ?? start + window);
|
|
40
70
|
if (fullSequence === undefined) {
|
|
41
71
|
continue;
|
|
42
72
|
}
|
|
@@ -81,3 +81,34 @@ test('regexpParser with negative lookahead should match single char', async (t)
|
|
|
81
81
|
t.is(position, 1); // Consumed 1 character
|
|
82
82
|
t.truthy(remainingInput); // There's remaining input (the space)
|
|
83
83
|
});
|
|
84
|
+
test('regexpParser should match exact 6-character input', async (t) => {
|
|
85
|
+
const regexpParser = createRegExpParser(/abcdef/);
|
|
86
|
+
const result = await runParser(regexpParser, 'abcdef', stringParserInputCompanion);
|
|
87
|
+
t.is(result[0], 'abcdef');
|
|
88
|
+
});
|
|
89
|
+
test('regexpParser should match quoted string of length 6', async (t) => {
|
|
90
|
+
const regexpParser = createRegExpParser(/"[^"]*"/);
|
|
91
|
+
const result = await runParser(regexpParser, '"abcd"', // 6 characters total
|
|
92
|
+
stringParserInputCompanion);
|
|
93
|
+
t.is(result[0], '"abcd"');
|
|
94
|
+
});
|
|
95
|
+
// Property-based tests for fixed-length patterns
|
|
96
|
+
testProp('regexpParser should match exact n-character input for any length', [fc.integer({ min: 1, max: 20 })], async (t, length) => {
|
|
97
|
+
const input = 'a'.repeat(length);
|
|
98
|
+
const regex = new RegExp(`a{${length}}`);
|
|
99
|
+
const regexpParser = createRegExpParser(regex);
|
|
100
|
+
const result = await runParser(regexpParser, input, stringParserInputCompanion);
|
|
101
|
+
t.is(result[0], input);
|
|
102
|
+
});
|
|
103
|
+
testProp('regexpParser should match quoted strings of any length', [fc.integer({ min: 0, max: 20 })], async (t, contentLength) => {
|
|
104
|
+
const content = 'x'.repeat(contentLength);
|
|
105
|
+
const input = `"${content}"`;
|
|
106
|
+
const regexpParser = createRegExpParser(/"[^"]*"/);
|
|
107
|
+
const result = await runParser(regexpParser, input, stringParserInputCompanion);
|
|
108
|
+
t.is(result[0], input);
|
|
109
|
+
});
|
|
110
|
+
testProp('regexpParser greedy patterns should match any length input', [fc.stringMatching(/^[a-z]+$/).filter(s => s.length > 0 && s.length <= 20)], async (t, input) => {
|
|
111
|
+
const regexpParser = createRegExpParser(/[a-z]+/);
|
|
112
|
+
const result = await runParser(regexpParser, input, stringParserInputCompanion);
|
|
113
|
+
t.is(result[0], input);
|
|
114
|
+
});
|
|
@@ -11,6 +11,7 @@ import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js'
|
|
|
11
11
|
import { createTerminatedArrayParser } from './terminatedArrayParser.js';
|
|
12
12
|
import { createDisjunctionParser } from './disjunctionParser.js';
|
|
13
13
|
import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
|
|
14
|
+
import { createObjectParser } from './objectParser.js';
|
|
14
15
|
// CharacterSet helpers
|
|
15
16
|
const emptyCharacterSet = { type: 'empty' };
|
|
16
17
|
function codePointRangeIsEmpty(range) {
|
|
@@ -401,9 +402,18 @@ const characterClassParser = promiseCompose(createTupleParser([
|
|
|
401
402
|
}
|
|
402
403
|
return literal(charset);
|
|
403
404
|
});
|
|
404
|
-
const starQuantifierParser =
|
|
405
|
-
|
|
406
|
-
|
|
405
|
+
const starQuantifierParser = createObjectParser({
|
|
406
|
+
type: 'star',
|
|
407
|
+
_marker: createExactSequenceParser('*'),
|
|
408
|
+
});
|
|
409
|
+
const plusQuantifierParser = createObjectParser({
|
|
410
|
+
type: 'plus',
|
|
411
|
+
_marker: createExactSequenceParser('+'),
|
|
412
|
+
});
|
|
413
|
+
const optionalQuantifierParser = createObjectParser({
|
|
414
|
+
type: 'optional',
|
|
415
|
+
_marker: createExactSequenceParser('?'),
|
|
416
|
+
});
|
|
407
417
|
// Parse a number for quantifiers
|
|
408
418
|
const numberParser = parserCreatorCompose(() => createArrayParser(parserCreatorCompose(() => elementParser, char => async (parserContext) => {
|
|
409
419
|
parserContext.invariant(char >= '0' && char <= '9', 'Expected digit, got "%s"', char);
|
|
@@ -465,24 +475,34 @@ const nonCaptureGroupParser = promiseCompose(createTupleParser([
|
|
|
465
475
|
createExactSequenceParser(')'),
|
|
466
476
|
]), ([, inner]) => inner);
|
|
467
477
|
// Positive lookahead (?=...)
|
|
468
|
-
const positiveLookaheadMarkerParser =
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
createExactSequenceParser('
|
|
472
|
-
|
|
478
|
+
const positiveLookaheadMarkerParser = createObjectParser({
|
|
479
|
+
type: 'lookahead-marker',
|
|
480
|
+
isPositive: true,
|
|
481
|
+
_open: createExactSequenceParser('(?='),
|
|
482
|
+
inner: createParserAccessorParser(() => alternationParser),
|
|
483
|
+
_close: createExactSequenceParser(')'),
|
|
484
|
+
});
|
|
473
485
|
// Negative lookahead (?!...)
|
|
474
|
-
const negativeLookaheadMarkerParser =
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
createExactSequenceParser('
|
|
478
|
-
|
|
486
|
+
const negativeLookaheadMarkerParser = createObjectParser({
|
|
487
|
+
type: 'lookahead-marker',
|
|
488
|
+
isPositive: false,
|
|
489
|
+
_open: createExactSequenceParser('(?!'),
|
|
490
|
+
inner: createParserAccessorParser(() => alternationParser),
|
|
491
|
+
_close: createExactSequenceParser(')'),
|
|
492
|
+
});
|
|
479
493
|
const groupParser = createUnionParser([
|
|
480
494
|
namedCaptureGroupParser,
|
|
481
495
|
nonCaptureGroupParser,
|
|
482
496
|
captureGroupParser,
|
|
483
497
|
]);
|
|
484
|
-
const startAnchorMarkerParser =
|
|
485
|
-
|
|
498
|
+
const startAnchorMarkerParser = createObjectParser({
|
|
499
|
+
type: 'start-anchor-marker',
|
|
500
|
+
_marker: createExactSequenceParser('^'),
|
|
501
|
+
});
|
|
502
|
+
const endAnchorMarkerParser = createObjectParser({
|
|
503
|
+
type: 'end-anchor-marker',
|
|
504
|
+
_marker: createExactSequenceParser('$'),
|
|
505
|
+
});
|
|
486
506
|
// Atom: the basic unit that can be quantified (excluding anchors)
|
|
487
507
|
const atomParser = createUnionParser([
|
|
488
508
|
groupParser,
|
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
import { getParserName, setParserName } from './parser.js';
|
|
2
54
|
import { isParserParsingFailedError } from './parserError.js';
|
|
3
55
|
import { promiseCompose } from './promiseCompose.js';
|
|
@@ -11,26 +63,33 @@ export const createSeparatedArrayParser = (elementParser, separatorParser) => {
|
|
|
11
63
|
let parser = elementParser;
|
|
12
64
|
const elements = [];
|
|
13
65
|
while (true) {
|
|
14
|
-
const
|
|
15
|
-
const initialPosition = elementParserContext.position;
|
|
66
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
16
67
|
try {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
68
|
+
const elementParserContext = __addDisposableResource(env_1, parserContext.lookahead(), false);
|
|
69
|
+
const initialPosition = elementParserContext.position;
|
|
70
|
+
try {
|
|
71
|
+
const element = await parser(elementParserContext);
|
|
72
|
+
if (elementParserContext.position === initialPosition) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
elements.push(element);
|
|
76
|
+
elementParserContext.unlookahead();
|
|
20
77
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
break;
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (isParserParsingFailedError(error)) {
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
27
83
|
}
|
|
28
|
-
|
|
84
|
+
parser = separatorThenElementParser;
|
|
85
|
+
}
|
|
86
|
+
catch (e_1) {
|
|
87
|
+
env_1.error = e_1;
|
|
88
|
+
env_1.hasError = true;
|
|
29
89
|
}
|
|
30
90
|
finally {
|
|
31
|
-
|
|
91
|
+
__disposeResources(env_1);
|
|
32
92
|
}
|
|
33
|
-
parser = separatorThenElementParser;
|
|
34
93
|
}
|
|
35
94
|
return elements;
|
|
36
95
|
};
|
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
import { getParserName, setParserName } from './parser.js';
|
|
2
54
|
import { isParserParsingFailedError } from './parserError.js';
|
|
3
55
|
import { promiseCompose } from './promiseCompose.js';
|
|
@@ -11,26 +63,33 @@ export const createSeparatedNonEmptyArrayParser = (elementParser, separatorParse
|
|
|
11
63
|
let parser = elementParser;
|
|
12
64
|
const elements = [];
|
|
13
65
|
while (true) {
|
|
14
|
-
const
|
|
15
|
-
const initialPosition = elementParserContext.position;
|
|
66
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
16
67
|
try {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
68
|
+
const elementParserContext = __addDisposableResource(env_1, parserContext.lookahead(), false);
|
|
69
|
+
const initialPosition = elementParserContext.position;
|
|
70
|
+
try {
|
|
71
|
+
const element = await parser(elementParserContext);
|
|
72
|
+
if (elementParserContext.position === initialPosition) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
elements.push(element);
|
|
76
|
+
elementParserContext.unlookahead();
|
|
20
77
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
break;
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (isParserParsingFailedError(error)) {
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
27
83
|
}
|
|
28
|
-
|
|
84
|
+
parser = separatorThenElementParser;
|
|
85
|
+
}
|
|
86
|
+
catch (e_1) {
|
|
87
|
+
env_1.error = e_1;
|
|
88
|
+
env_1.hasError = true;
|
|
29
89
|
}
|
|
30
90
|
finally {
|
|
31
|
-
|
|
91
|
+
__disposeResources(env_1);
|
|
32
92
|
}
|
|
33
|
-
parser = separatorThenElementParser;
|
|
34
93
|
}
|
|
35
94
|
parserContext.invariant(elements.length > 0, 'Expected elementParser (%s) to match at least once', getParserName(elementParser, 'anonymousSeparatedNonEmptyArrayChild'));
|
|
36
95
|
return elements;
|
|
@@ -1,19 +1,76 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
import { getParserName, setParserName } from './parser.js';
|
|
2
54
|
export const createSliceBoundedParser = (childParser, sliceEnd, mustConsumeAll = true) => {
|
|
3
55
|
const sliceBoundedParser = async (parserContext) => {
|
|
4
|
-
const
|
|
5
|
-
const childParserContext = parserContext.lookahead({
|
|
6
|
-
sliceEnd: absoluteSliceEnd,
|
|
7
|
-
});
|
|
56
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
8
57
|
try {
|
|
58
|
+
const absoluteSliceEnd = parserContext.position + sliceEnd;
|
|
59
|
+
const childParserContext = __addDisposableResource(env_1, parserContext.lookahead({
|
|
60
|
+
sliceEnd: absoluteSliceEnd,
|
|
61
|
+
}), false);
|
|
9
62
|
const value = await childParser(childParserContext);
|
|
10
63
|
childParserContext.invariant((!mustConsumeAll
|
|
11
64
|
|| childParserContext.position === absoluteSliceEnd), 'child parser must consume all input in the slice (%s in total, up to position %s), instead consumed %s up to position %s', sliceEnd, absoluteSliceEnd, childParserContext.position - parserContext.position, childParserContext.position);
|
|
12
65
|
childParserContext.unlookahead();
|
|
13
66
|
return value;
|
|
14
67
|
}
|
|
68
|
+
catch (e_1) {
|
|
69
|
+
env_1.error = e_1;
|
|
70
|
+
env_1.hasError = true;
|
|
71
|
+
}
|
|
15
72
|
finally {
|
|
16
|
-
|
|
73
|
+
__disposeResources(env_1);
|
|
17
74
|
}
|
|
18
75
|
};
|
|
19
76
|
setParserName(sliceBoundedParser, [
|
package/build/smaliParser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Simplify } from 'type-fest';
|
|
2
|
-
import { type
|
|
2
|
+
import { type DalvikBytecodeOperation, type DalvikBytecode } from './dalvikBytecodeParser/addressConversion.js';
|
|
3
3
|
import { type DalvikExecutableClassDefinition, type DalvikExecutableField, type DalvikExecutableFieldWithAccess, type DalvikExecutableMethod, type DalvikExecutableMethodWithAccess } from './dalvikExecutable.js';
|
|
4
4
|
import { type Parser } from './parser.js';
|
|
5
5
|
import { type IndexIntoMethodIds } from './dalvikExecutableParser/typedNumbers.js';
|
|
@@ -43,20 +43,20 @@ type SmaliCodeParameter = {
|
|
|
43
43
|
annotation: SmaliAnnotation | undefined;
|
|
44
44
|
};
|
|
45
45
|
export declare const smaliCodeParameterParser: Parser<SmaliCodeParameter, string>;
|
|
46
|
-
type
|
|
47
|
-
|
|
48
|
-
} ? Simplify<Omit<T, '
|
|
46
|
+
type SmaliCodeOperationFromDalvikOperation<T extends DalvikBytecodeOperation> = T extends {
|
|
47
|
+
targetInstructionIndices: number[];
|
|
48
|
+
} ? Simplify<Omit<T, 'targetInstructionIndices'> & {
|
|
49
49
|
branchOffsetIndices: number[];
|
|
50
50
|
}> : T extends {
|
|
51
|
-
|
|
52
|
-
} ? Simplify<Omit<T, '
|
|
51
|
+
targetInstructionIndex: number;
|
|
52
|
+
} ? Simplify<Omit<T, 'targetInstructionIndex'> & {
|
|
53
53
|
branchOffsetIndex: number;
|
|
54
54
|
}> : T extends {
|
|
55
55
|
methodIndex: IndexIntoMethodIds;
|
|
56
56
|
} ? Simplify<Omit<T, 'methodIndex'> & {
|
|
57
57
|
method: DalvikExecutableMethod;
|
|
58
58
|
}> : T;
|
|
59
|
-
type SmaliCodeOperation =
|
|
59
|
+
type SmaliCodeOperation = SmaliCodeOperationFromDalvikOperation<DalvikBytecodeOperation>;
|
|
60
60
|
export declare const smaliCodeOperationParser: Parser<SmaliCodeOperation, string>;
|
|
61
61
|
type SmaliMethod<DalvikBytecode> = {
|
|
62
62
|
dalvikExecutableMethodWithAccess: DalvikExecutableMethodWithAccess<DalvikBytecode>;
|