@futpib/parser 1.0.2 → 1.0.3
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/.github/copilot-instructions.md +149 -0
- package/.github/workflows/copilot-setup-steps.yml +18 -0
- package/.github/workflows/main.yml +29 -8
- package/.yarn/releases/yarn-4.9.4.cjs +942 -0
- package/.yarnrc.yml +1 -1
- package/build/allSettledStream.js +1 -1
- package/build/allSettledStream.test.js +2 -2
- package/build/androidPackageParser.d.ts +1 -1
- package/build/androidPackageParser.js +5 -3
- package/build/androidPackageParser.test.js +7 -7
- package/build/androidPackageUnparser.d.ts +2 -2
- package/build/androidPackageUnparser.js +18 -14
- package/build/androidPackageUnparser.test.js +7 -7
- package/build/arbitrarilySlicedAsyncInterator.js +2 -1
- package/build/arbitraryDalvikBytecode.d.ts +4 -0
- package/build/arbitraryDalvikBytecode.js +640 -0
- package/build/arbitraryDalvikExecutable.d.ts +3 -0
- package/build/arbitraryDalvikExecutable.js +282 -0
- package/build/arbitraryDosDateTime.js +1 -0
- package/build/arbitraryZipStream.js +1 -1
- package/build/arrayParser.js +2 -2
- package/build/arrayUnparser.d.ts +1 -1
- package/build/backsmali.d.ts +3 -1
- package/build/backsmali.js +31 -3
- package/build/customInvariant.d.ts +2 -1
- package/build/customInvariant.js +4 -6
- package/build/dalvikBytecodeParser/formatParsers.d.ts +76 -2
- package/build/dalvikBytecodeParser/formatParsers.js +146 -11
- package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
- package/build/dalvikBytecodeParser/formatSizes.js +34 -0
- package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
- package/build/dalvikBytecodeParser/operationFormats.js +225 -0
- package/build/dalvikBytecodeParser.d.ts +1105 -5
- package/build/dalvikBytecodeParser.js +658 -205
- package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
- package/build/dalvikBytecodeUnparser.d.ts +3 -0
- package/build/dalvikBytecodeUnparser.js +642 -0
- package/build/dalvikBytecodeUnparser.test.d.ts +1 -0
- package/build/dalvikBytecodeUnparser.test.js +25 -0
- package/build/dalvikExecutable.d.ts +65 -8
- package/build/dalvikExecutable.js +36 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +1 -1
- package/build/dalvikExecutableParser/stringSyntaxParser.js +17 -17
- package/build/dalvikExecutableParser/typeParsers.d.ts +2 -1
- package/build/dalvikExecutableParser/typeParsers.js +16 -11
- package/build/dalvikExecutableParser/typedNumbers.d.ts +85 -69
- package/build/dalvikExecutableParser/typedNumbers.js +0 -1
- package/build/dalvikExecutableParser.d.ts +2 -2
- package/build/dalvikExecutableParser.js +655 -337
- package/build/dalvikExecutableParser.test.js +24 -22
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +223 -246
- package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
- package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
- package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
- package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
- package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
- package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
- package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
- package/build/dalvikExecutableUnparser/utils.js +108 -0
- package/build/dalvikExecutableUnparser.d.ts +4 -0
- package/build/dalvikExecutableUnparser.js +406 -0
- package/build/dalvikExecutableUnparser.test.d.ts +1 -0
- package/build/dalvikExecutableUnparser.test.js +31 -0
- package/build/debugLogInputParser.js +1 -1
- package/build/disjunctionParser.d.ts +2 -2
- package/build/disjunctionParser.js +2 -2
- package/build/elementTerminatedArrayParser.d.ts +2 -2
- package/build/elementTerminatedArrayParser.js +1 -1
- package/build/elementTerminatedArrayParser.test.js +5 -5
- package/build/elementTerminatedSequenceArrayParser.d.ts +2 -2
- package/build/elementTerminatedSequenceArrayParser.js +1 -1
- package/build/elementTerminatedSequenceArrayParser.test.js +2 -2
- package/build/elementTerminatedSequenceParser.d.ts +2 -2
- package/build/elementTerminatedSequenceParser.js +1 -1
- package/build/elementTerminatedSequenceParser.test.js +2 -2
- package/build/endOfInputParser.d.ts +1 -1
- package/build/exactElementSwitchParser.d.ts +3 -0
- package/build/exactElementSwitchParser.js +22 -0
- package/build/fetchCid.js +2 -6
- package/build/fetchCid.test.d.ts +1 -0
- package/build/fetchCid.test.js +16 -0
- package/build/fixedLengthSequenceParser.test.js +2 -2
- package/build/hasExecutable.js +2 -2
- package/build/highResolutionTimer.js +1 -1
- package/build/inputReader.d.ts +1 -1
- package/build/inputReader.test.js +33 -45
- package/build/javaKeyStoreParser.test.js +6 -6
- package/build/jsonParser.js +8 -8
- package/build/lazyMessageError.d.ts +48 -0
- package/build/lazyMessageError.js +53 -0
- package/build/lazyMessageError.test.d.ts +1 -0
- package/build/lazyMessageError.test.js +15 -0
- package/build/leb128Parser.d.ts +1 -1
- package/build/leb128Parser.js +10 -10
- package/build/leb128Parser.test.js +7 -7
- package/build/negativeLookaheadParser.js +2 -2
- package/build/negativeLookaheadParser.test.js +4 -4
- package/build/noStackCaptureOverheadError.d.ts +4 -0
- package/build/noStackCaptureOverheadError.js +9 -0
- package/build/noStackCaptureOverheadError.test.d.ts +1 -0
- package/build/noStackCaptureOverheadError.test.js +15 -0
- package/build/nonEmptyArrayParser.js +2 -2
- package/build/nonEmptyArrayParser.test.js +2 -1
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +2 -1
- package/build/parser.js +23 -8
- package/build/parser.test.js +78 -29
- package/build/parserConsumedSequenceParser.d.ts +1 -1
- package/build/parserConsumedSequenceParser.js +2 -2
- package/build/parserContext.d.ts +8 -6
- package/build/parserContext.js +60 -33
- package/build/parserContext.test.js +7 -3
- package/build/parserError.d.ts +603 -44
- package/build/parserError.js +98 -53
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.js +2 -2
- package/build/promiseCompose.js +1 -2
- package/build/separatedArrayParser.js +2 -2
- package/build/separatedNonEmptyArrayParser.d.ts +2 -0
- package/build/separatedNonEmptyArrayParser.js +40 -0
- package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
- package/build/separatedNonEmptyArrayParser.test.js +66 -0
- package/build/sequenceBuffer.js +1 -1
- package/build/sequenceTerminatedSequenceParser.d.ts +2 -2
- package/build/sequenceTerminatedSequenceParser.js +3 -3
- package/build/sequenceTerminatedSequenceParser.test.js +1 -1
- package/build/sequenceUnparser.d.ts +1 -1
- package/build/skipToParser.d.ts +1 -1
- package/build/skipToParser.js +2 -2
- package/build/sliceBoundedParser.test.js +4 -9
- package/build/smali.d.ts +1 -1
- package/build/smali.js +6 -2
- package/build/smaliParser.d.ts +62 -6
- package/build/smaliParser.js +1721 -296
- package/build/smaliParser.test.js +338 -43
- package/build/stringFromAsyncIterable.d.ts +1 -0
- package/build/stringFromAsyncIterable.js +7 -0
- package/build/terminatedArrayParser.js +4 -4
- package/build/terminatedArrayParser.test.js +7 -7
- package/build/toAsyncIterator.js +4 -4
- package/build/unionParser.d.ts +1 -1
- package/build/unionParser.js +2 -2
- package/build/unionParser.test.js +3 -3
- package/build/unparser.d.ts +3 -3
- package/build/unparser.js +6 -4
- package/build/unparser.test.js +7 -19
- package/build/unparserContext.d.ts +2 -2
- package/build/unparserContext.js +2 -3
- package/build/unparserError.d.ts +2 -1
- package/build/unparserError.js +2 -1
- package/build/unparserImplementationInvariant.d.ts +1 -1
- package/build/unparserOutputCompanion.d.ts +1 -1
- package/build/unparserOutputCompanion.js +1 -1
- package/build/zipParser.js +1 -1
- package/build/zipUnparser.d.ts +3 -3
- package/build/zipUnparser.js +9 -19
- package/build/zipUnparser.test.js +1 -1
- package/package.json +19 -26
- package/src/allSettledStream.test.ts +2 -2
- package/src/allSettledStream.ts +3 -3
- package/src/androidPackageParser.test.ts +17 -19
- package/src/androidPackageParser.ts +129 -171
- package/src/androidPackageUnparser.test.ts +19 -21
- package/src/androidPackageUnparser.ts +23 -17
- package/src/arbitrarilySlicedAsyncInterable.ts +1 -1
- package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
- package/src/arbitraryDalvikBytecode.ts +992 -0
- package/src/arbitraryDalvikExecutable.ts +434 -0
- package/src/arbitraryDosDateTime.ts +1 -0
- package/src/arbitraryZipStream.ts +1 -1
- package/src/arrayParser.ts +2 -2
- package/src/arrayUnparser.ts +2 -2
- package/src/backsmali.ts +48 -4
- package/src/bsonParser.test.ts +12 -14
- package/src/customInvariant.ts +8 -12
- package/src/dalvikBytecodeParser/formatParsers.ts +376 -17
- package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
- package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
- package/src/dalvikBytecodeParser.ts +1042 -243
- package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
- package/src/dalvikBytecodeUnparser.test.ts +44 -0
- package/src/dalvikBytecodeUnparser.ts +758 -0
- package/src/dalvikExecutable.ts +110 -48
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +33 -33
- package/src/dalvikExecutableParser/typeParsers.ts +23 -14
- package/src/dalvikExecutableParser/typedNumbers.ts +19 -19
- package/src/dalvikExecutableParser.test.ts +60 -60
- package/src/dalvikExecutableParser.test.ts.md +6 -6
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +911 -434
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +256 -239
- package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
- package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
- package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
- package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
- package/src/dalvikExecutableUnparser/utils.ts +149 -0
- package/src/dalvikExecutableUnparser.test.ts +57 -0
- package/src/dalvikExecutableUnparser.ts +581 -0
- package/src/debugLogInputParser.ts +1 -1
- package/src/disjunctionParser.ts +5 -5
- package/src/elementTerminatedArrayParser.test.ts +8 -8
- package/src/elementTerminatedArrayParser.ts +2 -2
- package/src/elementTerminatedSequenceArrayParser.test.ts +4 -6
- package/src/elementTerminatedSequenceArrayParser.ts +2 -2
- package/src/elementTerminatedSequenceParser.test.ts +4 -6
- package/src/elementTerminatedSequenceParser.ts +2 -2
- package/src/endOfInputParser.ts +1 -1
- package/src/exactElementSwitchParser.ts +41 -0
- package/src/fetchCid.test.ts +20 -0
- package/src/fetchCid.ts +3 -7
- package/src/fixedLengthSequenceParser.test.ts +10 -12
- package/src/hasExecutable.ts +2 -2
- package/src/highResolutionTimer.ts +1 -1
- package/src/inputReader.test.ts +39 -52
- package/src/inputReader.ts +2 -4
- package/src/inputReaderState.ts +1 -1
- package/src/inspect.ts +1 -1
- package/src/javaKeyStoreParser.test.ts +12 -14
- package/src/javaKeyStoreParser.ts +2 -6
- package/src/jsonParser.test.ts +2 -4
- package/src/jsonParser.ts +34 -38
- package/src/lazyMessageError.test.ts +21 -0
- package/src/lazyMessageError.ts +88 -0
- package/src/leb128Parser.test.ts +25 -23
- package/src/leb128Parser.ts +19 -19
- package/src/negativeLookaheadParser.test.ts +7 -11
- package/src/negativeLookaheadParser.ts +2 -2
- package/src/noStackCaptureOverheadError.test.ts +17 -0
- package/src/noStackCaptureOverheadError.ts +12 -0
- package/src/nonEmptyArrayParser.test.ts +3 -2
- package/src/nonEmptyArrayParser.ts +2 -2
- package/src/optionalParser.ts +2 -2
- package/src/parser.test.ts +96 -43
- package/src/parser.test.ts.md +13 -6
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +35 -12
- package/src/parserAccessorParser.ts +1 -1
- package/src/parserConsumedSequenceParser.ts +3 -3
- package/src/parserContext.test.ts +7 -3
- package/src/parserContext.ts +82 -48
- package/src/parserError.ts +143 -63
- package/src/parserImplementationInvariant.ts +3 -3
- package/src/parserInputCompanion.ts +2 -2
- package/src/promiseCompose.ts +2 -2
- package/src/separatedArrayParser.ts +3 -3
- package/src/separatedNonEmptyArrayParser.test.ts +117 -0
- package/src/separatedNonEmptyArrayParser.ts +61 -0
- package/src/sequenceBuffer.test.ts +9 -9
- package/src/sequenceBuffer.ts +4 -4
- package/src/sequenceTerminatedSequenceParser.test.ts +3 -5
- package/src/sequenceTerminatedSequenceParser.ts +4 -4
- package/src/sequenceUnparser.ts +2 -2
- package/src/skipToParser.ts +2 -2
- package/src/sliceBoundedParser.test.ts +4 -12
- package/src/sliceBoundedParser.ts +2 -2
- package/src/smali.ts +8 -3
- package/src/smaliParser.test.ts +377 -66
- package/src/smaliParser.test.ts.md +1635 -48
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +2751 -569
- package/src/stringFromAsyncIterable.ts +9 -0
- package/src/terminatedArrayParser.test.ts +11 -11
- package/src/terminatedArrayParser.ts +5 -7
- package/src/toAsyncIterator.ts +8 -8
- package/src/uint8Array.ts +2 -3
- package/src/unionParser.test.ts +22 -23
- package/src/unionParser.ts +6 -8
- package/src/unparser.test.ts +18 -34
- package/src/unparser.ts +13 -9
- package/src/unparserContext.ts +9 -13
- package/src/unparserError.ts +2 -1
- package/src/unparserImplementationInvariant.ts +1 -1
- package/src/unparserOutputCompanion.ts +1 -1
- package/src/zip.ts +2 -6
- package/src/zipParser.ts +10 -18
- package/src/zipUnparser.test.ts +1 -1
- package/src/zipUnparser.ts +52 -64
- package/tsconfig.json +7 -1
- package/xo.config.ts +15 -0
- package/.yarn/releases/yarn-4.5.3.cjs +0 -934
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { NoStackCaptureOverheadError } from "./noStackCaptureOverheadError.js";
|
|
2
|
+
|
|
3
|
+
type ValueOrAccessor<T> = T | (() => T);
|
|
4
|
+
|
|
5
|
+
export type LazyMessage =
|
|
6
|
+
| ValueOrAccessor<string | string[]>
|
|
7
|
+
| [ ValueOrAccessor<string | string[]>, ...Array<ValueOrAccessor<unknown>> ]
|
|
8
|
+
;
|
|
9
|
+
|
|
10
|
+
function formatLazyMessageFormat(
|
|
11
|
+
format: ValueOrAccessor<string | string[]>,
|
|
12
|
+
): string {
|
|
13
|
+
if (typeof format === 'function') {
|
|
14
|
+
format = format();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (Array.isArray(format)) {
|
|
18
|
+
return format.join('\n');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return format;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function formatLazyMessageSubstitutions(
|
|
25
|
+
format: string,
|
|
26
|
+
formatArguments: Array<ValueOrAccessor<unknown>>,
|
|
27
|
+
): string {
|
|
28
|
+
return format.replaceAll('%s', () => {
|
|
29
|
+
const argumentOrAccessor = formatArguments.shift();
|
|
30
|
+
return typeof argumentOrAccessor === 'function' ? argumentOrAccessor() : argumentOrAccessor;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function formatLazyMessage(lazyMessage: LazyMessage): string {
|
|
35
|
+
if (Array.isArray(lazyMessage)) {
|
|
36
|
+
const [ format, ...formatArguments ] = lazyMessage;
|
|
37
|
+
const formattedFormat = formatLazyMessageFormat(format);
|
|
38
|
+
return formatLazyMessageSubstitutions(formattedFormat, formatArguments);
|
|
39
|
+
} else {
|
|
40
|
+
return formatLazyMessageFormat(lazyMessage);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface LazyMessageError extends Error {
|
|
45
|
+
computeMessage(): void;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function createLazyMessageErrorClass(
|
|
49
|
+
BaseError: typeof NoStackCaptureOverheadError | typeof Error,
|
|
50
|
+
) {
|
|
51
|
+
return class LazyMessageError extends (BaseError as typeof Error) implements LazyMessageError {
|
|
52
|
+
name = 'LazyMessageError';
|
|
53
|
+
|
|
54
|
+
_lazyMessage: undefined | LazyMessage;
|
|
55
|
+
|
|
56
|
+
constructor(
|
|
57
|
+
lazyMessage: LazyMessage,
|
|
58
|
+
) {
|
|
59
|
+
super('LAZY_MESSAGE');
|
|
60
|
+
this._lazyMessage = lazyMessage;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
computeMessage(): void {
|
|
64
|
+
if (this._lazyMessage === undefined) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this.message = formatLazyMessage(this._lazyMessage);
|
|
69
|
+
this.stack = this.stack?.replace('LAZY_MESSAGE', this.message);
|
|
70
|
+
delete this._lazyMessage;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const NormalLazyMessageError = createLazyMessageErrorClass(Error);
|
|
76
|
+
export const NoStackCaptureOverheadLazyMessageError = createLazyMessageErrorClass(NoStackCaptureOverheadError);
|
|
77
|
+
|
|
78
|
+
export function isLazyMessageError(
|
|
79
|
+
value: unknown,
|
|
80
|
+
): value is LazyMessageError {
|
|
81
|
+
return (
|
|
82
|
+
typeof value === 'object'
|
|
83
|
+
&& value !== null
|
|
84
|
+
&& value instanceof Error
|
|
85
|
+
&& '_lazyMessage' in value
|
|
86
|
+
&& typeof (value as Record<string, unknown>).computeMessage === 'function'
|
|
87
|
+
);
|
|
88
|
+
}
|
package/src/leb128Parser.test.ts
CHANGED
|
@@ -4,17 +4,19 @@ import test from 'ava';
|
|
|
4
4
|
import leb128 from 'leb128';
|
|
5
5
|
import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
6
6
|
import { runParser } from './parser.js';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
uleb128Parser, sleb128Parser, uleb128NumberParser, sleb128NumberParser,
|
|
9
|
+
} from './leb128Parser.js';
|
|
8
10
|
|
|
9
11
|
test('sleb128, uleb128, uleb128p1', async t => {
|
|
10
12
|
for (const [
|
|
11
13
|
input, expectedSleb128, expectedUleb128,
|
|
12
14
|
] of [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
[ Buffer.from('00', 'hex'), 0n, 0n ],
|
|
16
|
+
[ Buffer.from('01', 'hex'), 1n, 1n ],
|
|
17
|
+
[ Buffer.from('7f', 'hex'), -1n, 127n ],
|
|
18
|
+
[ Buffer.from('807f', 'hex'), -128n, 16_256n ],
|
|
19
|
+
] as const) {
|
|
18
20
|
const actualSleb128 = await runParser(sleb128Parser, input, uint8ArrayParserInputCompanion);
|
|
19
21
|
const actualUleb128 = await runParser(uleb128Parser, input, uint8ArrayParserInputCompanion);
|
|
20
22
|
|
|
@@ -25,12 +27,12 @@ test('sleb128, uleb128, uleb128p1', async t => {
|
|
|
25
27
|
for (const [
|
|
26
28
|
input, expectedUleb128,
|
|
27
29
|
] of [
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
[ new Uint8Array([ 2 ]), 2n ],
|
|
31
|
+
[ new Uint8Array([ 127 ]), 127n ],
|
|
32
|
+
[ new Uint8Array([ 0 + 0x80, 1 ]), 128n ],
|
|
33
|
+
[ new Uint8Array([ 1 + 0x80, 1 ]), 129n ],
|
|
34
|
+
[ new Uint8Array([ 57 + 0x80, 100 ]), 12_857n ],
|
|
35
|
+
] as const) {
|
|
34
36
|
const actualUleb128 = await runParser(uleb128Parser, input, uint8ArrayParserInputCompanion);
|
|
35
37
|
|
|
36
38
|
t.is(actualUleb128, expectedUleb128, 'uleb128');
|
|
@@ -39,15 +41,15 @@ test('sleb128, uleb128, uleb128p1', async t => {
|
|
|
39
41
|
for (const [
|
|
40
42
|
input, expectedSleb128,
|
|
41
43
|
] of [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
[ new Uint8Array([ 2 ]), 2n ],
|
|
45
|
+
[ new Uint8Array([ 0x7E ]), -2n ],
|
|
46
|
+
[ new Uint8Array([ 127 + 0x80, 0 ]), 127n ],
|
|
47
|
+
[ new Uint8Array([ 1 + 0x80, 0x7F ]), -127n ],
|
|
48
|
+
[ new Uint8Array([ 0 + 0x80, 1 ]), 128n ],
|
|
49
|
+
[ new Uint8Array([ 0 + 0x80, 0x7F ]), -128n ],
|
|
50
|
+
[ new Uint8Array([ 1 + 0x80, 1 ]), 129n ],
|
|
51
|
+
[ new Uint8Array([ 0x7F + 0x80, 0x7E ]), -129n ],
|
|
52
|
+
] as const) {
|
|
51
53
|
const actualSleb128 = await runParser(sleb128Parser, input, uint8ArrayParserInputCompanion);
|
|
52
54
|
|
|
53
55
|
t.is(actualSleb128, expectedSleb128, 'sleb128');
|
|
@@ -98,7 +100,7 @@ testProp.skip(
|
|
|
98
100
|
const uleb128 = leb128.unsigned.encode(natural);
|
|
99
101
|
|
|
100
102
|
if (natural > (2 ** 32) - 1) {
|
|
101
|
-
await t.throwsAsync(() => runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion));
|
|
103
|
+
await t.throwsAsync(async () => runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion));
|
|
102
104
|
|
|
103
105
|
return;
|
|
104
106
|
}
|
|
@@ -122,7 +124,7 @@ testProp.skip(
|
|
|
122
124
|
const sleb128 = leb128.signed.encode(integer);
|
|
123
125
|
|
|
124
126
|
if (integer > (2 ** 32) - 1 || integer < -(2 ** 32)) {
|
|
125
|
-
await t.throwsAsync(() => runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion));
|
|
127
|
+
await t.throwsAsync(async () => runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion));
|
|
126
128
|
|
|
127
129
|
return;
|
|
128
130
|
}
|
package/src/leb128Parser.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Parser } from
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
2
|
|
|
3
|
-
export const uleb128Parser: Parser<bigint, Uint8Array> = async
|
|
3
|
+
export const uleb128Parser: Parser<bigint, Uint8Array> = async parserContext => {
|
|
4
4
|
let leastSignificantValueBitIndex = 0n;
|
|
5
5
|
let value = 0n;
|
|
6
6
|
|
|
7
7
|
while (true) {
|
|
8
8
|
const byte = await parserContext.read(0);
|
|
9
|
-
const byteValue = BigInt(byte &
|
|
10
|
-
const byteNotLast = BigInt(byte &
|
|
9
|
+
const byteValue = BigInt(byte & 0b0111_1111);
|
|
10
|
+
const byteNotLast = BigInt(byte & 0b1000_0000);
|
|
11
11
|
|
|
12
12
|
value |= byteValue << leastSignificantValueBitIndex;
|
|
13
13
|
|
|
@@ -20,16 +20,16 @@ export const uleb128Parser: Parser<bigint, Uint8Array> = async (parserContext) =
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
return value;
|
|
23
|
-
}
|
|
23
|
+
};
|
|
24
24
|
|
|
25
|
-
export const sleb128Parser: Parser<bigint, Uint8Array> = async
|
|
25
|
+
export const sleb128Parser: Parser<bigint, Uint8Array> = async parserContext => {
|
|
26
26
|
let value = 0n;
|
|
27
27
|
let leastSignificantValueBitIndex = 0n;
|
|
28
28
|
|
|
29
29
|
while (true) {
|
|
30
30
|
const byte = await parserContext.read(0);
|
|
31
|
-
const byteValue = BigInt(byte &
|
|
32
|
-
const byteNotLast = BigInt(byte &
|
|
31
|
+
const byteValue = BigInt(byte & 0b0111_1111);
|
|
32
|
+
const byteNotLast = BigInt(byte & 0b1000_0000);
|
|
33
33
|
|
|
34
34
|
value |= byteValue << leastSignificantValueBitIndex;
|
|
35
35
|
leastSignificantValueBitIndex += 7n;
|
|
@@ -38,7 +38,7 @@ export const sleb128Parser: Parser<bigint, Uint8Array> = async (parserContext) =
|
|
|
38
38
|
continue;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const mostSignificantInputBit = byte &
|
|
41
|
+
const mostSignificantInputBit = byte & 0b0100_0000;
|
|
42
42
|
|
|
43
43
|
if (mostSignificantInputBit) {
|
|
44
44
|
value |= (~0n << leastSignificantValueBitIndex);
|
|
@@ -50,7 +50,7 @@ export const sleb128Parser: Parser<bigint, Uint8Array> = async (parserContext) =
|
|
|
50
50
|
return value;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
export const uleb128NumberParser: Parser<number, Uint8Array> = async
|
|
53
|
+
export const uleb128NumberParser: Parser<number, Uint8Array> = async parserContext => {
|
|
54
54
|
const value = await uleb128Parser(parserContext);
|
|
55
55
|
|
|
56
56
|
parserContext.invariant(
|
|
@@ -62,7 +62,7 @@ export const uleb128NumberParser: Parser<number, Uint8Array> = async (parserCont
|
|
|
62
62
|
return Number(value);
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
export const sleb128NumberParser: Parser<number, Uint8Array> = async
|
|
65
|
+
export const sleb128NumberParser: Parser<number, Uint8Array> = async parserContext => {
|
|
66
66
|
const value = await sleb128Parser(parserContext);
|
|
67
67
|
|
|
68
68
|
parserContext.invariant(
|
|
@@ -74,14 +74,14 @@ export const sleb128NumberParser: Parser<number, Uint8Array> = async (parserCont
|
|
|
74
74
|
return Number(value);
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
export const uleb128UnsafeNumberParser: Parser<number, Uint8Array> = async
|
|
77
|
+
export const uleb128UnsafeNumberParser: Parser<number, Uint8Array> = async parserContext => {
|
|
78
78
|
let leastSignificantValueBitIndex = 0;
|
|
79
79
|
let value = 0;
|
|
80
80
|
|
|
81
81
|
while (true) {
|
|
82
82
|
const byte = await parserContext.read(0);
|
|
83
|
-
const byteValue = byte &
|
|
84
|
-
const byteNotLast = byte &
|
|
83
|
+
const byteValue = byte & 0b0111_1111;
|
|
84
|
+
const byteNotLast = byte & 0b1000_0000;
|
|
85
85
|
|
|
86
86
|
value |= byteValue << leastSignificantValueBitIndex;
|
|
87
87
|
|
|
@@ -94,16 +94,16 @@ export const uleb128UnsafeNumberParser: Parser<number, Uint8Array> = async (pars
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
return value;
|
|
97
|
-
}
|
|
97
|
+
};
|
|
98
98
|
|
|
99
|
-
export const sleb128UnsafeNumberParser: Parser<number, Uint8Array> = async
|
|
99
|
+
export const sleb128UnsafeNumberParser: Parser<number, Uint8Array> = async parserContext => {
|
|
100
100
|
let value = 0;
|
|
101
101
|
let leastSignificantValueBitIndex = 0;
|
|
102
102
|
|
|
103
103
|
while (true) {
|
|
104
104
|
const byte = await parserContext.read(0);
|
|
105
|
-
const byteValue = byte &
|
|
106
|
-
const byteNotLast = byte &
|
|
105
|
+
const byteValue = byte & 0b0111_1111;
|
|
106
|
+
const byteNotLast = byte & 0b1000_0000;
|
|
107
107
|
|
|
108
108
|
value |= byteValue << leastSignificantValueBitIndex;
|
|
109
109
|
leastSignificantValueBitIndex += 7;
|
|
@@ -112,7 +112,7 @@ export const sleb128UnsafeNumberParser: Parser<number, Uint8Array> = async (pars
|
|
|
112
112
|
continue;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
const mostSignificantInputBit = byte &
|
|
115
|
+
const mostSignificantInputBit = byte & 0b0100_0000;
|
|
116
116
|
|
|
117
117
|
if (leastSignificantValueBitIndex < 32 && mostSignificantInputBit) {
|
|
118
118
|
value |= (~0 << leastSignificantValueBitIndex);
|
|
@@ -5,7 +5,6 @@ import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
|
5
5
|
import { runParser } from './parser.js';
|
|
6
6
|
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
7
7
|
import { createTupleParser } from './tupleParser.js';
|
|
8
|
-
import { ParserParsingFailedError } from './parserError.js';
|
|
9
8
|
|
|
10
9
|
testProp(
|
|
11
10
|
'negativeLookaheadParser',
|
|
@@ -17,33 +16,30 @@ testProp(
|
|
|
17
16
|
fc.string({
|
|
18
17
|
minLength: 1,
|
|
19
18
|
}),
|
|
20
|
-
).filter(([ a, b ]) => !a.startsWith(b))
|
|
19
|
+
).filter(([ a, b ]) => !a.startsWith(b)),
|
|
21
20
|
],
|
|
22
21
|
async (t, [ stringA, stringB ]) => {
|
|
23
22
|
const result = await runParser(
|
|
24
23
|
createTupleParser([
|
|
25
|
-
createNegativeLookaheadParser(
|
|
26
|
-
createExactSequenceParser(stringB),
|
|
27
|
-
),
|
|
24
|
+
createNegativeLookaheadParser(createExactSequenceParser(stringB)),
|
|
28
25
|
createExactSequenceParser(stringA + stringB),
|
|
29
26
|
]),
|
|
30
27
|
stringA + stringB,
|
|
31
28
|
stringParserInputCompanion,
|
|
32
29
|
);
|
|
33
30
|
|
|
34
|
-
t.deepEqual(result, [undefined, stringA + stringB]);
|
|
31
|
+
t.deepEqual(result, [ undefined, stringA + stringB ]);
|
|
35
32
|
|
|
36
|
-
await t.throwsAsync(() => runParser(
|
|
33
|
+
await t.throwsAsync(async () => runParser(
|
|
37
34
|
createTupleParser([
|
|
38
|
-
createNegativeLookaheadParser(
|
|
39
|
-
createExactSequenceParser(stringA),
|
|
40
|
-
),
|
|
35
|
+
createNegativeLookaheadParser(createExactSequenceParser(stringA)),
|
|
41
36
|
createExactSequenceParser(stringA + stringB),
|
|
42
37
|
]),
|
|
43
38
|
stringA + stringB,
|
|
44
39
|
stringParserInputCompanion,
|
|
45
40
|
), {
|
|
46
|
-
|
|
41
|
+
any: true,
|
|
42
|
+
name: 'ParserParsingInvariantError',
|
|
47
43
|
message: /lookahead/,
|
|
48
44
|
});
|
|
49
45
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getParserName, setParserName, type Parser } from './parser.js';
|
|
2
|
-
import { ParserParsingFailedError } from './parserError.js';
|
|
2
|
+
import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
|
|
3
3
|
|
|
4
4
|
export const createNegativeLookaheadParser = <Sequence>(
|
|
5
5
|
childParser: Parser<unknown, Sequence>,
|
|
@@ -14,7 +14,7 @@ export const createNegativeLookaheadParser = <Sequence>(
|
|
|
14
14
|
|
|
15
15
|
childParserSuccess = true;
|
|
16
16
|
} catch (error) {
|
|
17
|
-
if (!(error
|
|
17
|
+
if (!isParserParsingFailedError(error)) {
|
|
18
18
|
throw error;
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import util from 'util';
|
|
3
|
+
import { NoStackCaptureOverheadError } from './noStackCaptureOverheadError.js';
|
|
4
|
+
|
|
5
|
+
test('NoStackCaptureOverheadError works', t => {
|
|
6
|
+
const error = new NoStackCaptureOverheadError('Test message');
|
|
7
|
+
|
|
8
|
+
t.is(error.name, 'NoStackCaptureOverheadError');
|
|
9
|
+
t.is(error.message, 'Test message');
|
|
10
|
+
t.true(error instanceof Error, 'error is instance of Error');
|
|
11
|
+
t.true(error instanceof NoStackCaptureOverheadError, 'error is instance of NoStackCaptureOverheadError');
|
|
12
|
+
t.false(new Error() instanceof NoStackCaptureOverheadError, 'regular Error is not instance of NoStackCaptureOverheadError');
|
|
13
|
+
if (typeof (Error as any).isError === 'function') {
|
|
14
|
+
t.false((Error as any).isError(error), 'Error.isError does not identify error as Error');
|
|
15
|
+
}
|
|
16
|
+
t.false(util.types.isNativeError(error), 'util.types.isNativeError does not identify error as native Error');
|
|
17
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
class NoStackCaptureOverheadErrorClass extends Error {}
|
|
3
|
+
|
|
4
|
+
function NoStackCaptureOverheadErrorConstructor(this: Error, message: string) {
|
|
5
|
+
this.name = 'NoStackCaptureOverheadError';
|
|
6
|
+
this.message = message;
|
|
7
|
+
this.stack = 'This stack is intentionally left blank to avoid capture overhead.';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
NoStackCaptureOverheadErrorConstructor.prototype = Object.create(Error.prototype);
|
|
11
|
+
|
|
12
|
+
export const NoStackCaptureOverheadError = NoStackCaptureOverheadErrorConstructor as unknown as typeof NoStackCaptureOverheadErrorClass
|
|
@@ -7,7 +7,8 @@ import { createExactElementParser } from './exactElementParser.js';
|
|
|
7
7
|
test('empty array does not match', async t => {
|
|
8
8
|
const parser: Parser<string[], string> = createNonEmptyArrayParser(createExactElementParser('0'));
|
|
9
9
|
|
|
10
|
-
await t.throwsAsync(() => runParser(parser, '', stringParserInputCompanion), {
|
|
10
|
+
await t.throwsAsync(async () => runParser(parser, '', stringParserInputCompanion), {
|
|
11
|
+
any: true,
|
|
11
12
|
message: /Expected .* to match at least once/,
|
|
12
13
|
});
|
|
13
14
|
});
|
|
@@ -16,5 +17,5 @@ test('non-empty array matches', async t => {
|
|
|
16
17
|
const parser: Parser<string[], string> = createNonEmptyArrayParser(createExactElementParser('0'));
|
|
17
18
|
const result = await runParser(parser, '0', stringParserInputCompanion);
|
|
18
19
|
|
|
19
|
-
t.deepEqual(result, ['0']);
|
|
20
|
+
t.deepEqual(result, [ '0' ]);
|
|
20
21
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
|
-
import { ParserParsingFailedError } from './parserError.js';
|
|
2
|
+
import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
|
|
3
3
|
|
|
4
4
|
export const createNonEmptyArrayParser = <ElementOutput, Sequence>(
|
|
5
5
|
elementParser: Parser<ElementOutput, Sequence>,
|
|
@@ -19,7 +19,7 @@ export const createNonEmptyArrayParser = <ElementOutput, Sequence>(
|
|
|
19
19
|
elements.push(element);
|
|
20
20
|
elementParserContext.unlookahead();
|
|
21
21
|
} catch (error) {
|
|
22
|
-
if (error
|
|
22
|
+
if (isParserParsingFailedError(error)) {
|
|
23
23
|
break;
|
|
24
24
|
}
|
|
25
25
|
|
package/src/optionalParser.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
|
-
import { ParserParsingFailedError } from './parserError.js';
|
|
2
|
+
import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
|
|
3
3
|
|
|
4
4
|
export const createOptionalParser = <Output, Sequence>(
|
|
5
5
|
childParser: Parser<Output, Sequence>,
|
|
@@ -12,7 +12,7 @@ export const createOptionalParser = <Output, Sequence>(
|
|
|
12
12
|
childParserContext.unlookahead();
|
|
13
13
|
return value;
|
|
14
14
|
} catch (error) {
|
|
15
|
-
if (error
|
|
15
|
+
if (isParserParsingFailedError(error)) {
|
|
16
16
|
return undefined;
|
|
17
17
|
}
|
|
18
18
|
|