@futpib/parser 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/allSettledStream.js +32 -14
- package/build/allSettledStream.test.js +32 -0
- package/build/androidPackage.d.ts +39 -0
- package/build/androidPackageParser.d.ts +17 -0
- package/build/androidPackageParser.js +183 -0
- package/build/{apkParser.test.js → androidPackageParser.test.js} +6 -6
- package/build/androidPackageUnparser.d.ts +4 -0
- package/build/{apkUnparser.js → androidPackageUnparser.js} +23 -23
- package/build/androidPackageUnparser.test.js +26 -0
- package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
- package/build/arbitrarilySlicedAsyncInterable.js +3 -3
- package/build/arrayParser.test.js +3 -3
- package/build/backsmali.d.ts +1 -0
- package/build/backsmali.js +22 -0
- package/build/bsonParser.js +6 -2
- package/build/customInvariant.d.ts +1 -1
- package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
- package/build/dalvikBytecodeParser/formatParsers.js +169 -0
- package/build/dalvikBytecodeParser.d.ts +107 -0
- package/build/dalvikBytecodeParser.js +836 -0
- package/build/dalvikExecutable.d.ts +158 -0
- package/build/dalvikExecutable.js +20 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
- package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
- package/build/dalvikExecutableParser/typeParsers.js +34 -0
- package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
- package/build/dalvikExecutableParser/typedNumbers.js +19 -0
- package/build/dalvikExecutableParser.d.ts +5 -0
- package/build/dalvikExecutableParser.js +1439 -0
- package/build/dalvikExecutableParser.test.js +70 -0
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
- package/build/debugLogInputParser.d.ts +4 -0
- package/build/debugLogInputParser.js +16 -0
- package/build/debugLogParser.js +14 -3
- package/build/disjunctionParser.d.ts +2 -1
- package/build/disjunctionParser.js +4 -2
- package/build/elementTerminatedArrayParser.d.ts +3 -0
- package/build/elementTerminatedArrayParser.js +18 -0
- package/build/elementTerminatedArrayParser.test.js +52 -0
- package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
- package/build/elementTerminatedSequenceArrayParser.js +32 -0
- package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
- package/build/elementTerminatedSequenceParser.d.ts +3 -0
- package/build/elementTerminatedSequenceParser.js +27 -0
- package/build/elementTerminatedSequenceParser.test.js +34 -0
- package/build/exactElementParser.js +10 -5
- package/build/exactSequenceParser.d.ts +2 -1
- package/build/exactSequenceParser.js +12 -2
- package/build/fetchCid.d.ts +1 -0
- package/build/fetchCid.js +107 -0
- package/build/fixedLengthSequenceParser.d.ts +1 -0
- package/build/fixedLengthSequenceParser.js +18 -1
- package/build/fixedLengthSequenceParser.test.js +41 -0
- package/build/hasExecutable.d.ts +1 -0
- package/build/hasExecutable.js +8 -0
- package/build/highResolutionTimer.d.ts +16 -0
- package/build/highResolutionTimer.js +42 -0
- package/build/inputReader.d.ts +11 -0
- package/build/inputReader.js +37 -0
- package/build/inputReader.test.js +165 -0
- package/build/inputReaderState.d.ts +10 -0
- package/build/inputReaderState.js +16 -0
- package/build/inspect.d.ts +1 -0
- package/build/inspect.js +7 -0
- package/build/javaKeyStoreParser.test.js +2 -2
- package/build/jsonParser.d.ts +2 -0
- package/build/jsonParser.js +11 -14
- package/build/leb128Parser.d.ts +7 -0
- package/build/leb128Parser.js +82 -0
- package/build/leb128Parser.test.js +107 -0
- package/build/lookaheadParser.d.ts +2 -0
- package/build/lookaheadParser.js +14 -0
- package/build/negativeLookaheadParser.js +21 -15
- package/build/negativeLookaheadParser.test.js +30 -0
- package/build/nonEmptyArrayParser.d.ts +2 -0
- package/build/nonEmptyArrayParser.js +32 -0
- package/build/nonEmptyArrayParser.test.js +16 -0
- package/build/parser.d.ts +10 -1
- package/build/parser.js +66 -31
- package/build/parser.test.js +79 -12
- package/build/parserAccessorParser.js +9 -1
- package/build/parserConsumedSequenceParser.js +20 -15
- package/build/parserContext.d.ts +14 -0
- package/build/parserContext.js +56 -27
- package/build/parserContext.test.js +27 -0
- package/build/parserCreatorCompose.d.ts +1 -0
- package/build/parserCreatorCompose.js +8 -2
- package/build/parserError.d.ts +6 -0
- package/build/parserError.js +6 -6
- package/build/parserInputCompanion.d.ts +15 -0
- package/build/parserInputCompanion.js +38 -0
- package/build/promiseCompose.d.ts +1 -1
- package/build/promiseCompose.js +12 -1
- package/build/promiseSettled.d.ts +1 -0
- package/build/promiseSettled.js +4 -0
- package/build/separatedArrayParser.d.ts +2 -0
- package/build/separatedArrayParser.js +39 -0
- package/build/separatedArrayParser.test.d.ts +1 -0
- package/build/separatedArrayParser.test.js +21 -0
- package/build/sequenceBuffer.d.ts +10 -0
- package/build/sequenceBuffer.js +54 -2
- package/build/sequenceBuffer.test.js +57 -0
- package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
- package/build/sequenceTerminatedSequenceParser.js +32 -0
- package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
- package/build/sequenceTerminatedSequenceParser.test.js +37 -0
- package/build/skipParser.d.ts +1 -1
- package/build/skipParser.js +4 -2
- package/build/skipToParser.d.ts +2 -0
- package/build/skipToParser.js +11 -0
- package/build/sliceBoundedParser.d.ts +1 -1
- package/build/sliceBoundedParser.js +7 -2
- package/build/sliceBoundedParser.test.js +35 -1
- package/build/smali.d.ts +1 -0
- package/build/smali.js +17 -0
- package/build/smaliParser.d.ts +12 -0
- package/build/smaliParser.js +656 -0
- package/build/smaliParser.test.d.ts +1 -0
- package/build/smaliParser.test.js +115 -0
- package/build/terminatedArrayParser.d.ts +3 -1
- package/build/terminatedArrayParser.js +79 -2
- package/build/terminatedArrayParser.test.d.ts +1 -0
- package/build/terminatedArrayParser.test.js +131 -0
- package/build/toAsyncIterable.d.ts +1 -0
- package/build/toAsyncIterable.js +7 -0
- package/build/toAsyncIterator.d.ts +1 -0
- package/build/toAsyncIterator.js +33 -0
- package/build/tupleParser.d.ts +4 -0
- package/build/tupleParser.js +1 -5
- package/build/unionParser.d.ts +2 -1
- package/build/unionParser.js +27 -12
- package/build/unionParser.test.d.ts +1 -0
- package/build/unionParser.test.js +60 -0
- package/build/zipParser.d.ts +7 -2
- package/build/zipParser.js +36 -12
- package/build/zipUnparser.d.ts +4 -1
- package/build/zipUnparser.js +55 -26
- package/build/zipUnparser.test.js +14 -14
- package/package.json +23 -7
- package/src/allSettledStream.test.ts +40 -0
- package/src/allSettledStream.ts +47 -15
- package/src/androidPackage.ts +48 -0
- package/src/{apkParser.test.ts → androidPackageParser.test.ts} +6 -7
- package/src/{apkParser.test.ts.md → androidPackageParser.test.ts.md} +4 -4
- package/src/androidPackageParser.test.ts.snap +0 -0
- package/src/androidPackageParser.ts +440 -0
- package/src/androidPackageUnparser.test.ts +36 -0
- package/src/androidPackageUnparser.ts +120 -0
- package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
- package/src/arrayParser.test.ts +3 -3
- package/src/backsmali.ts +30 -0
- package/src/bsonParser.ts +13 -2
- package/src/customInvariant.ts +1 -1
- package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
- package/src/dalvikBytecodeParser.ts +2074 -0
- package/src/dalvikExecutable.ts +220 -0
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
- package/src/dalvikExecutableParser/typeParsers.ts +65 -0
- package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
- package/src/dalvikExecutableParser.test.ts +89 -0
- package/src/dalvikExecutableParser.test.ts.md +634 -0
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +2768 -0
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
- package/src/debugLogInputParser.ts +28 -0
- package/src/debugLogParser.ts +19 -3
- package/src/disjunctionParser.ts +10 -5
- package/src/elementTerminatedArrayParser.test.ts +99 -0
- package/src/elementTerminatedArrayParser.ts +31 -0
- package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
- package/src/elementTerminatedSequenceArrayParser.ts +52 -0
- package/src/elementTerminatedSequenceParser.test.ts +54 -0
- package/src/elementTerminatedSequenceParser.ts +43 -0
- package/src/exactElementParser.ts +17 -11
- package/src/exactSequenceParser.ts +23 -2
- package/src/fetchCid.ts +125 -0
- package/src/fixedLengthSequenceParser.test.ts +77 -0
- package/src/fixedLengthSequenceParser.ts +28 -1
- package/src/hasExecutable.ts +11 -0
- package/src/highResolutionTimer.ts +49 -0
- package/src/inputReader.test.ts +209 -0
- package/src/inputReader.ts +75 -0
- package/src/inputReaderState.ts +33 -0
- package/src/inspect.ts +9 -0
- package/src/javaKeyStoreParser.test.ts +2 -3
- package/src/jsonParser.ts +13 -25
- package/src/leb128Parser.test.ts +171 -0
- package/src/leb128Parser.ts +125 -0
- package/src/lookaheadParser.ts +19 -0
- package/src/negativeLookaheadParser.test.ts +53 -0
- package/src/negativeLookaheadParser.ts +26 -14
- package/src/nonEmptyArrayParser.test.ts +20 -0
- package/src/nonEmptyArrayParser.ts +44 -0
- package/src/optionalParser.ts +1 -0
- package/src/parser.test.ts +131 -12
- package/src/parser.test.ts.md +21 -21
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +149 -45
- package/src/parserAccessorParser.ts +12 -2
- package/src/parserConsumedSequenceParser.ts +25 -16
- package/src/parserContext.test.ts +31 -0
- package/src/parserContext.ts +109 -37
- package/src/parserCreatorCompose.ts +20 -2
- package/src/parserError.ts +9 -6
- package/src/parserInputCompanion.ts +55 -0
- package/src/promiseCompose.ts +17 -3
- package/src/promiseSettled.ts +6 -0
- package/src/separatedArrayParser.test.ts +34 -0
- package/src/separatedArrayParser.ts +55 -0
- package/src/sequenceBuffer.test.ts +70 -0
- package/src/sequenceBuffer.ts +88 -2
- package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
- package/src/sequenceTerminatedSequenceParser.ts +62 -0
- package/src/skipParser.ts +7 -5
- package/src/skipToParser.ts +16 -0
- package/src/sliceBoundedParser.test.ts +43 -1
- package/src/sliceBoundedParser.ts +19 -1
- package/src/smali.ts +24 -0
- package/src/smaliParser.test.ts +132 -0
- package/src/smaliParser.test.ts.md +2320 -0
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +1166 -0
- package/src/terminatedArrayParser.test.ts +258 -0
- package/src/terminatedArrayParser.ts +108 -3
- package/src/toAsyncIterable.ts +7 -0
- package/src/toAsyncIterator.ts +48 -0
- package/src/tupleParser.ts +8 -5
- package/src/unionParser.test.ts +79 -0
- package/src/unionParser.ts +44 -16
- package/src/zipParser.ts +77 -18
- package/src/zipUnparser.test.ts +18 -18
- package/src/zipUnparser.ts +88 -27
- package/build/apk.d.ts +0 -39
- package/build/apkParser.d.ts +0 -16
- package/build/apkParser.js +0 -164
- package/build/apkUnparser.d.ts +0 -4
- package/build/apkUnparser.test.js +0 -26
- package/build/arbitraryDosDate.d.ts +0 -2
- package/build/arbitraryDosDate.js +0 -8
- package/build/arbitraryZipEntry.d.ts +0 -3
- package/build/arbitraryZipEntry.js +0 -26
- package/build/createDisjunctionParser.d.ts +0 -2
- package/build/createDisjunctionParser.js +0 -47
- package/build/createExactParser.d.ts +0 -2
- package/build/createExactParser.js +0 -12
- package/build/createSequentialUnionParser.d.ts +0 -2
- package/build/createSequentialUnionParser.js +0 -69
- package/build/fixedLengthChunkParser.d.ts +0 -2
- package/build/fixedLengthChunkParser.js +0 -12
- package/build/fixedLengthParser.d.ts +0 -2
- package/build/fixedLengthParser.js +0 -12
- package/build/inputChunkBuffer.d.ts +0 -15
- package/build/inputChunkBuffer.js +0 -40
- package/build/inputChunkBuffer.test.js +0 -34
- package/build/inputCompanion.d.ts +0 -18
- package/build/inputCompanion.js +0 -28
- package/build/invariantDefined.d.ts +0 -1
- package/build/invariantDefined.js +0 -5
- package/build/invariantIdentity.d.ts +0 -3
- package/build/invariantIdentity.js +0 -5
- package/build/javaKeystoreParser.d.ts +0 -2
- package/build/javaKeystoreParser.js +0 -7
- package/build/jsonParser2.d.ts +0 -3
- package/build/jsonParser2.js +0 -52
- package/build/jsonParser2.test.js +0 -22
- package/build/negativeLookahead.d.ts +0 -2
- package/build/negativeLookahead.js +0 -18
- package/build/parserCompose.d.ts +0 -3
- package/build/parserCompose.js +0 -7
- package/build/parserImplementationInvariantInvariant.d.ts +0 -3
- package/build/parserImplementationInvariantInvariant.js +0 -15
- package/build/parserInvariant.d.ts +0 -4
- package/build/parserInvariant.js +0 -11
- package/build/promiseFish.d.ts +0 -1
- package/build/promiseFish.js +0 -3
- package/build/sequenceParser.d.ts +0 -3
- package/build/sequenceParser.js +0 -10
- package/build/terminatedSequenceParser.d.ts +0 -2
- package/build/terminatedSequenceParser.js +0 -24
- package/build/unparserInputCompanion.d.ts +0 -15
- package/build/unparserInputCompanion.js +0 -13
- package/build/zipEntry.d.ts +0 -28
- package/build/zipFile.d.ts +0 -32
- package/build/zipFileEntry.d.ts +0 -6
- package/src/apk.ts +0 -48
- package/src/apkParser.test.ts.snap +0 -0
- package/src/apkParser.ts +0 -392
- package/src/apkUnparser.test.ts +0 -37
- package/src/apkUnparser.ts +0 -120
- package/src/invariantDefined.ts +0 -6
- package/src/invariantIdentity.ts +0 -8
- /package/build/{apk.js → androidPackage.js} +0 -0
- /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
- /package/build/{apkUnparser.test.d.ts → androidPackageUnparser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.d.ts → dalvikExecutableParser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.js → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
- /package/build/{inputChunkBuffer.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
- /package/build/{jsonParser2.test.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.js → fixedLengthSequenceParser.test.d.ts} +0 -0
- /package/build/{zipEntry.js → leb128Parser.test.d.ts} +0 -0
- /package/build/{zipFile.js → negativeLookaheadParser.test.d.ts} +0 -0
- /package/build/{zipFileEntry.js → nonEmptyArrayParser.test.d.ts} +0 -0
|
@@ -1,21 +1,39 @@
|
|
|
1
|
+
import { promiseSettled } from "./promiseSettled.js";
|
|
1
2
|
export function allSettledStream(tasks) {
|
|
3
|
+
let cancelled = false;
|
|
2
4
|
return new ReadableStream({
|
|
3
|
-
|
|
5
|
+
start(controller) {
|
|
6
|
+
const startStack = ((new Error('allSettledStream ReadableStream start stack holder').stack ?? '')
|
|
7
|
+
.split('\n')
|
|
8
|
+
.slice(1)
|
|
9
|
+
.join('\n'));
|
|
10
|
+
const allSettledStreamTaskAwaiter = async ({ promise, context, }) => {
|
|
11
|
+
const promiseSettledResult = await promiseSettled(promise);
|
|
12
|
+
if (promiseSettledResult.status === 'rejected'
|
|
13
|
+
&& promiseSettledResult.reason instanceof Error
|
|
14
|
+
&& promiseSettledResult.reason.stack) {
|
|
15
|
+
promiseSettledResult.reason.stack += `\n${startStack}`;
|
|
16
|
+
}
|
|
17
|
+
settledCount++;
|
|
18
|
+
if (cancelled) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const allSettedStreamResult = {
|
|
22
|
+
...promiseSettledResult,
|
|
23
|
+
context,
|
|
24
|
+
};
|
|
25
|
+
controller.enqueue(allSettedStreamResult);
|
|
26
|
+
if (settledCount === tasks.length) {
|
|
27
|
+
controller.close();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
4
30
|
let settledCount = 0;
|
|
5
|
-
for (const
|
|
6
|
-
(
|
|
7
|
-
const [promiseSettledResult] = await Promise.allSettled([promise]);
|
|
8
|
-
settledCount++;
|
|
9
|
-
const allSettedStreamResult = {
|
|
10
|
-
...promiseSettledResult,
|
|
11
|
-
context,
|
|
12
|
-
};
|
|
13
|
-
controller.enqueue(allSettedStreamResult);
|
|
14
|
-
if (settledCount === tasks.length) {
|
|
15
|
-
controller.close();
|
|
16
|
-
}
|
|
17
|
-
})();
|
|
31
|
+
for (const task of tasks) {
|
|
32
|
+
allSettledStreamTaskAwaiter(task);
|
|
18
33
|
}
|
|
19
34
|
},
|
|
35
|
+
cancel() {
|
|
36
|
+
cancelled = true;
|
|
37
|
+
},
|
|
20
38
|
});
|
|
21
39
|
}
|
|
@@ -54,3 +54,35 @@ test('allSettledStream', async (t) => {
|
|
|
54
54
|
t.snapshot(results);
|
|
55
55
|
t.is(results.length, 8);
|
|
56
56
|
});
|
|
57
|
+
test('allSettledStream reader cancel', async (t) => {
|
|
58
|
+
const stream = allSettledStream([
|
|
59
|
+
10,
|
|
60
|
+
20,
|
|
61
|
+
0,
|
|
62
|
+
40,
|
|
63
|
+
30,
|
|
64
|
+
].map((delay) => ({
|
|
65
|
+
promise: new Promise((resolve) => {
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
resolve(delay);
|
|
68
|
+
}, delay);
|
|
69
|
+
}),
|
|
70
|
+
context: delay,
|
|
71
|
+
})));
|
|
72
|
+
const results = [];
|
|
73
|
+
for await (const value of stream) {
|
|
74
|
+
results.push(value);
|
|
75
|
+
if (value.context === 30) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
await new Promise(resolve => {
|
|
80
|
+
setTimeout(resolve, 50);
|
|
81
|
+
});
|
|
82
|
+
stream.cancel();
|
|
83
|
+
for await (const value of stream) {
|
|
84
|
+
t.fail();
|
|
85
|
+
results.push(value);
|
|
86
|
+
}
|
|
87
|
+
t.deepEqual(results.map(({ context }) => context), [0, 10, 20, 30]);
|
|
88
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Zip } from './zip.js';
|
|
2
|
+
export type AndroidPackageSigningBlockPair = {
|
|
3
|
+
id: number;
|
|
4
|
+
value: Uint8Array;
|
|
5
|
+
};
|
|
6
|
+
export type AndroidPackageSignatureV2Digest = {
|
|
7
|
+
signatureAlgorithmId: number;
|
|
8
|
+
digest: Uint8Array;
|
|
9
|
+
};
|
|
10
|
+
export type AndroidPackageSignatureV2AdditionalAttribute = {
|
|
11
|
+
id: number;
|
|
12
|
+
value: Uint8Array;
|
|
13
|
+
};
|
|
14
|
+
export type AndroidPackageSignatureV2SignedData = {
|
|
15
|
+
digests: AndroidPackageSignatureV2Digest[];
|
|
16
|
+
certificates: Uint8Array[];
|
|
17
|
+
additionalAttributes: AndroidPackageSignatureV2AdditionalAttribute[];
|
|
18
|
+
zeroPaddingLength?: number;
|
|
19
|
+
};
|
|
20
|
+
export type AndroidPackageSignatureV2Signature = {
|
|
21
|
+
signatureAlgorithmId: number;
|
|
22
|
+
signature: Uint8Array;
|
|
23
|
+
};
|
|
24
|
+
export type AndroidPackageSignatureV2Signer = {
|
|
25
|
+
signedData: AndroidPackageSignatureV2SignedData;
|
|
26
|
+
signatures: AndroidPackageSignatureV2Signature[];
|
|
27
|
+
publicKey: Uint8Array;
|
|
28
|
+
};
|
|
29
|
+
export type AndroidPackageSignatureV2 = {
|
|
30
|
+
signers: AndroidPackageSignatureV2Signer[];
|
|
31
|
+
};
|
|
32
|
+
export type AndroidPackageSigningBlock = {
|
|
33
|
+
pairs: AndroidPackageSigningBlockPair[];
|
|
34
|
+
signatureV2?: AndroidPackageSignatureV2;
|
|
35
|
+
zeroPaddingLength?: number;
|
|
36
|
+
};
|
|
37
|
+
export type AndroidPackage = Zip & {
|
|
38
|
+
signingBlock?: AndroidPackageSigningBlock;
|
|
39
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
|
+
import { ZipCentralDirectoryHeader, ZipEndOfCentralDirectoryRecord, ZipLocalFile } from './zipParser.js';
|
|
3
|
+
import { type AndroidPackage, type AndroidPackageSigningBlock } from './androidPackage.js';
|
|
4
|
+
export declare const androidPackageSigningBlockParser: Parser<AndroidPackageSigningBlock, Uint8Array>;
|
|
5
|
+
export declare const androidPackageParser: Parser<AndroidPackage, Uint8Array>;
|
|
6
|
+
export type AndroidPackageSignableSections = {
|
|
7
|
+
zipLocalFiles: ZipLocalFile[];
|
|
8
|
+
zipLocalFilesZeroPaddingLength: number;
|
|
9
|
+
androidPackageSigningBlock?: AndroidPackageSigningBlock;
|
|
10
|
+
zipCentralDirectory: ZipCentralDirectoryHeader[];
|
|
11
|
+
zipEndOfCentralDirectory: ZipEndOfCentralDirectoryRecord;
|
|
12
|
+
zipLocalFilesUint8Array: Uint8Array;
|
|
13
|
+
androidPackageSigningBlockUint8Array?: Uint8Array;
|
|
14
|
+
zipCentralDirectoryUint8Array: Uint8Array;
|
|
15
|
+
zipEndOfCentralDirectoryUint8Array: Uint8Array;
|
|
16
|
+
};
|
|
17
|
+
export declare const androidPackageSignableSectionsParser: Parser<AndroidPackageSignableSections, Uint8Array>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import invariant from 'invariant';
|
|
2
|
+
import { createArrayParser } from './arrayParser.js';
|
|
3
|
+
import { createOptionalParser } from './optionalParser.js';
|
|
4
|
+
import { setParserName } from './parser.js';
|
|
5
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
6
|
+
import { createTupleParser } from './tupleParser.js';
|
|
7
|
+
import { zip64EndOfCentralDirectoryLocatorParser, zip64EndOfCentralDirectoryRecordParser, zipArchiveDecryptionHeaderParser, zipArchiveExtraDataRecordParser, zipCentralDirectoryHeaderParser, zipEndOfCentralDirectoryRecordParser, zipFromZipSegments, zipLocalFileParser, } from './zipParser.js';
|
|
8
|
+
import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js';
|
|
9
|
+
import { parserCreatorCompose } from './parserCreatorCompose.js';
|
|
10
|
+
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
11
|
+
import { createSliceBoundedParser } from './sliceBoundedParser.js';
|
|
12
|
+
import { createDisjunctionParser } from './disjunctionParser.js';
|
|
13
|
+
import { createExactElementParser } from './exactElementParser.js';
|
|
14
|
+
import { createParserConsumedSequenceParser } from './parserConsumedSequenceParser.js';
|
|
15
|
+
// https://source.android.com/docs/security/features/androidPackagesigning/v2#androidPackage-signing-block
|
|
16
|
+
const uint32LEParser = promiseCompose(createFixedLengthSequenceParser(4), array => Buffer.from(array).readUInt32LE());
|
|
17
|
+
setParserName(uint32LEParser, 'uint32LEParser');
|
|
18
|
+
const uint64LEParser = promiseCompose(createFixedLengthSequenceParser(8), array => Buffer.from(array).readBigUInt64LE());
|
|
19
|
+
setParserName(uint64LEParser, 'uint64LEParser');
|
|
20
|
+
const createUint32LengthPrefixedParser = (createInnerParser) => parserCreatorCompose(() => uint32LEParser, length => createInnerParser(length))();
|
|
21
|
+
const createUint64LengthPrefixedParser = (createInnerParser) => parserCreatorCompose(() => uint64LEParser, length => createInnerParser(length))();
|
|
22
|
+
const createUint32LengthPrefixedSliceBoundedParser = (innerParser) => createUint32LengthPrefixedParser(length => createSliceBoundedParser(innerParser, length));
|
|
23
|
+
const createUint32LengthPrefixedSliceBoundedArrayParser = (innerParser) => createUint32LengthPrefixedSliceBoundedParser(createArrayParser(innerParser));
|
|
24
|
+
const createAndroidPackageSigningBlockZeroPaddingPairInnerParser = (length) => {
|
|
25
|
+
const androidPackageSigningBlockZeroPaddingPairInnerParser = promiseCompose(createTupleParser([
|
|
26
|
+
createExactSequenceParser(Buffer.from('77657242', 'hex')),
|
|
27
|
+
createFixedLengthSequenceParser(length - 4),
|
|
28
|
+
]), ([_magic, zeroPadding]) => ({ type: 'zeroPadding', length: zeroPadding.length }));
|
|
29
|
+
setParserName(androidPackageSigningBlockZeroPaddingPairInnerParser, 'androidPackageSigningBlockZeroPaddingPairInnerParser');
|
|
30
|
+
return androidPackageSigningBlockZeroPaddingPairInnerParser;
|
|
31
|
+
};
|
|
32
|
+
const createAndroidPackageSigningBlockSignatureV2PairInnerParser = (length) => {
|
|
33
|
+
const androidPackageSigningBlockSignatureV2PairInnerParser = promiseCompose(createTupleParser([
|
|
34
|
+
createExactSequenceParser(Buffer.from('1a870971', 'hex')),
|
|
35
|
+
androidPackageSignatureV2SignersParser,
|
|
36
|
+
]), ([_magic, signers = []]) => ({ type: 'signatureV2', signers }));
|
|
37
|
+
return setParserName(androidPackageSigningBlockSignatureV2PairInnerParser, 'androidPackageSigningBlockSignatureV2PairInnerParser');
|
|
38
|
+
};
|
|
39
|
+
const createAndroidPackageSigningBlockGenericPairInnerParser = (length) => promiseCompose(createTupleParser([
|
|
40
|
+
uint32LEParser,
|
|
41
|
+
createFixedLengthSequenceParser(length - 4),
|
|
42
|
+
]), ([id, value]) => ({ type: 'generic', pair: { id, value } }));
|
|
43
|
+
const createAndroidPackageSigningBlockPairInnerParser = (length) => {
|
|
44
|
+
const androidPackageSigningBlockPairInnerParser = promiseCompose(createTupleParser([
|
|
45
|
+
parserContext => {
|
|
46
|
+
parserContext.invariant(Number.isSafeInteger(length), 'Signing block length is unreasonable: %s.', length);
|
|
47
|
+
},
|
|
48
|
+
createDisjunctionParser([
|
|
49
|
+
createAndroidPackageSigningBlockZeroPaddingPairInnerParser(length),
|
|
50
|
+
createAndroidPackageSigningBlockSignatureV2PairInnerParser(length),
|
|
51
|
+
createAndroidPackageSigningBlockGenericPairInnerParser(length),
|
|
52
|
+
]),
|
|
53
|
+
]), ([_lengthInvariant, pair,]) => pair);
|
|
54
|
+
setParserName(androidPackageSigningBlockPairInnerParser, 'androidPackageSigningBlockPairInnerParser');
|
|
55
|
+
return androidPackageSigningBlockPairInnerParser;
|
|
56
|
+
};
|
|
57
|
+
const androidPackageSigningBlockPairParser = createUint64LengthPrefixedParser(length => createAndroidPackageSigningBlockPairInnerParser(Number(length)));
|
|
58
|
+
setParserName(androidPackageSigningBlockPairParser, 'androidPackageSigningBlockPairParser');
|
|
59
|
+
const androidPackageSigningBlockPairsParser = createArrayParser(androidPackageSigningBlockPairParser);
|
|
60
|
+
export const androidPackageSigningBlockParser = createUint64LengthPrefixedParser(sizeOfBlock => promiseCompose(createTupleParser([
|
|
61
|
+
androidPackageSigningBlockPairsParser,
|
|
62
|
+
uint64LEParser,
|
|
63
|
+
createExactSequenceParser(Buffer.from('APK Sig Block 42', 'utf8')),
|
|
64
|
+
]), async ([pairs, sizeOfBlockRepeated, _magic,]) => {
|
|
65
|
+
invariant(sizeOfBlock === sizeOfBlockRepeated, 'Size of block mismatch: %s !== %s.', sizeOfBlock, sizeOfBlockRepeated);
|
|
66
|
+
const zeroPaddingPair = pairs.find(pair => pair.type === 'zeroPadding');
|
|
67
|
+
const signatureV2Pair = pairs.find(pair => pair.type === 'signatureV2');
|
|
68
|
+
const genericPairs = (pairs
|
|
69
|
+
.filter(pair => (pair !== zeroPaddingPair
|
|
70
|
+
&& pair !== signatureV2Pair))
|
|
71
|
+
.map(pair => {
|
|
72
|
+
invariant(pair.type === 'generic', 'Expected generic pair, got %s.', pair.type);
|
|
73
|
+
return pair.pair;
|
|
74
|
+
}));
|
|
75
|
+
return {
|
|
76
|
+
zeroPaddingLength: zeroPaddingPair?.length,
|
|
77
|
+
signatureV2: signatureV2Pair ? {
|
|
78
|
+
signers: signatureV2Pair?.signers,
|
|
79
|
+
} : undefined,
|
|
80
|
+
pairs: genericPairs,
|
|
81
|
+
};
|
|
82
|
+
}));
|
|
83
|
+
const androidPackageSignatureV2DigestParser = createUint32LengthPrefixedParser(pairLength => promiseCompose(createTupleParser([
|
|
84
|
+
uint32LEParser,
|
|
85
|
+
createUint32LengthPrefixedParser(digestLength => createFixedLengthSequenceParser(digestLength)),
|
|
86
|
+
]), ([signatureAlgorithmId, digest]) => ({ signatureAlgorithmId, digest })));
|
|
87
|
+
const androidPackageSignatureV2DigestsParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2DigestParser);
|
|
88
|
+
setParserName(androidPackageSignatureV2DigestsParser, 'androidPackageSignatureV2DigestsParser');
|
|
89
|
+
const androidPackageSignatureV2CertificateParser = createUint32LengthPrefixedParser(certificateLength => createFixedLengthSequenceParser(certificateLength));
|
|
90
|
+
setParserName(androidPackageSignatureV2CertificateParser, 'androidPackageSignatureV2CertificateParser');
|
|
91
|
+
const androidPackageSignatureV2CertificatesParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2CertificateParser);
|
|
92
|
+
setParserName(androidPackageSignatureV2CertificatesParser, 'androidPackageSignatureV2CertificatesParser');
|
|
93
|
+
const androidPackageSignatureV2AdditionalAttributeParser = createUint32LengthPrefixedParser(pairLength => promiseCompose(createTupleParser([
|
|
94
|
+
uint32LEParser,
|
|
95
|
+
createFixedLengthSequenceParser(pairLength - 4),
|
|
96
|
+
]), ([id, value]) => ({ id, value })));
|
|
97
|
+
setParserName(androidPackageSignatureV2AdditionalAttributeParser, 'androidPackageSignatureV2AdditionalAttributeParser');
|
|
98
|
+
const androidPackageSignatureV2AdditionalAttributesParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2AdditionalAttributeParser);
|
|
99
|
+
setParserName(androidPackageSignatureV2AdditionalAttributesParser, 'androidPackageSignatureV2AdditionalAttributesParser');
|
|
100
|
+
const androidPackageSignatureV2SignedDataParser = createUint32LengthPrefixedSliceBoundedParser(promiseCompose(createTupleParser([
|
|
101
|
+
androidPackageSignatureV2DigestsParser,
|
|
102
|
+
androidPackageSignatureV2CertificatesParser,
|
|
103
|
+
androidPackageSignatureV2AdditionalAttributesParser,
|
|
104
|
+
createArrayParser(createExactElementParser(0)),
|
|
105
|
+
]), ([digests, certificates, additionalAttributes, zeroPadding,]) => ({
|
|
106
|
+
digests,
|
|
107
|
+
certificates,
|
|
108
|
+
additionalAttributes,
|
|
109
|
+
zeroPaddingLength: zeroPadding.length,
|
|
110
|
+
})));
|
|
111
|
+
setParserName(androidPackageSignatureV2SignedDataParser, 'androidPackageSignatureV2SignedDataParser');
|
|
112
|
+
const androidPackageSignatureV2SignatureParser = createUint32LengthPrefixedParser(signatureLength => promiseCompose(createTupleParser([
|
|
113
|
+
uint32LEParser,
|
|
114
|
+
createUint32LengthPrefixedParser(signatureLength => createFixedLengthSequenceParser(signatureLength)),
|
|
115
|
+
]), ([signatureAlgorithmId, signature,]) => ({
|
|
116
|
+
signatureAlgorithmId,
|
|
117
|
+
signature,
|
|
118
|
+
})));
|
|
119
|
+
const androidPackageSignatureV2SignaturesParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2SignatureParser);
|
|
120
|
+
setParserName(androidPackageSignatureV2SignaturesParser, 'androidPackageSignatureV2SignaturesParser');
|
|
121
|
+
const androidPackageSignatureV2PublicKeyParser = createUint32LengthPrefixedParser(publicKeyLength => createFixedLengthSequenceParser(publicKeyLength));
|
|
122
|
+
setParserName(androidPackageSignatureV2PublicKeyParser, 'androidPackageSignatureV2PublicKeyParser');
|
|
123
|
+
const androidPackageSignatureV2SignerParser = createUint32LengthPrefixedSliceBoundedParser(promiseCompose(createTupleParser([
|
|
124
|
+
androidPackageSignatureV2SignedDataParser,
|
|
125
|
+
androidPackageSignatureV2SignaturesParser,
|
|
126
|
+
androidPackageSignatureV2PublicKeyParser,
|
|
127
|
+
]), ([signedData, signatures = [], publicKey,]) => ({
|
|
128
|
+
signedData,
|
|
129
|
+
signatures,
|
|
130
|
+
publicKey,
|
|
131
|
+
})));
|
|
132
|
+
setParserName(androidPackageSignatureV2SignerParser, 'androidPackageSignatureV2SignerParser');
|
|
133
|
+
const androidPackageSignatureV2SignersParser = createUint32LengthPrefixedSliceBoundedArrayParser(androidPackageSignatureV2SignerParser);
|
|
134
|
+
setParserName(androidPackageSignatureV2SignersParser, 'androidPackageSignatureV2SignersParser');
|
|
135
|
+
const androidPackageParser_ = createTupleParser([
|
|
136
|
+
createArrayParser(zipLocalFileParser),
|
|
137
|
+
createOptionalParser(zipArchiveDecryptionHeaderParser),
|
|
138
|
+
createOptionalParser(zipArchiveExtraDataRecordParser),
|
|
139
|
+
createOptionalParser(androidPackageSigningBlockParser),
|
|
140
|
+
createArrayParser(zipCentralDirectoryHeaderParser),
|
|
141
|
+
createOptionalParser(zip64EndOfCentralDirectoryRecordParser),
|
|
142
|
+
createOptionalParser(zip64EndOfCentralDirectoryLocatorParser),
|
|
143
|
+
zipEndOfCentralDirectoryRecordParser,
|
|
144
|
+
]);
|
|
145
|
+
setParserName(androidPackageParser_, 'androidPackageParser_');
|
|
146
|
+
export const androidPackageParser = promiseCompose(androidPackageParser_, async ([zipLocalFiles, zipArchiveDecryptionHeader, zipArchiveExtraDataRecord, androidPackageSigningBlock, zipCentralDirectoryHeaders, zip64EndOfCentralDirectoryRecord, zip64EndOfCentralDirectoryLocator, zipEndOfCentralDirectoryRecord,]) => {
|
|
147
|
+
const zip = await zipFromZipSegments({
|
|
148
|
+
zipLocalFiles,
|
|
149
|
+
zipCentralDirectoryHeaders,
|
|
150
|
+
zipEndOfCentralDirectoryRecord,
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
...zip,
|
|
154
|
+
signingBlock: androidPackageSigningBlock,
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
setParserName(androidPackageParser, 'androidPackageParser');
|
|
158
|
+
export const androidPackageSignableSectionsParser = promiseCompose(createTupleParser([
|
|
159
|
+
createParserConsumedSequenceParser(createTupleParser([
|
|
160
|
+
createArrayParser(zipLocalFileParser),
|
|
161
|
+
createOptionalParser(zipArchiveDecryptionHeaderParser),
|
|
162
|
+
createOptionalParser(zipArchiveExtraDataRecordParser),
|
|
163
|
+
])),
|
|
164
|
+
createArrayParser(createExactElementParser(0)),
|
|
165
|
+
createOptionalParser(createParserConsumedSequenceParser(androidPackageSigningBlockParser)),
|
|
166
|
+
createParserConsumedSequenceParser(createTupleParser([
|
|
167
|
+
createArrayParser(zipCentralDirectoryHeaderParser),
|
|
168
|
+
createOptionalParser(zip64EndOfCentralDirectoryRecordParser),
|
|
169
|
+
createOptionalParser(zip64EndOfCentralDirectoryLocatorParser),
|
|
170
|
+
])),
|
|
171
|
+
createParserConsumedSequenceParser(zipEndOfCentralDirectoryRecordParser),
|
|
172
|
+
]), async ([[[zipLocalFiles,], zipLocalFilesUint8Array,], zipLocalFilesZeroPadding, [androidPackageSigningBlock = undefined, androidPackageSigningBlockUint8Array = undefined,] = [], [[zipCentralDirectory,], zipCentralDirectoryUint8Array,], [zipEndOfCentralDirectory, zipEndOfCentralDirectoryUint8Array,],]) => ({
|
|
173
|
+
zipLocalFiles,
|
|
174
|
+
zipLocalFilesZeroPaddingLength: zipLocalFilesZeroPadding.length,
|
|
175
|
+
androidPackageSigningBlock,
|
|
176
|
+
zipCentralDirectory,
|
|
177
|
+
zipEndOfCentralDirectory,
|
|
178
|
+
zipLocalFilesUint8Array,
|
|
179
|
+
androidPackageSigningBlockUint8Array,
|
|
180
|
+
zipCentralDirectoryUint8Array,
|
|
181
|
+
zipEndOfCentralDirectoryUint8Array,
|
|
182
|
+
}));
|
|
183
|
+
setParserName(androidPackageSignableSectionsParser, 'androidPackageSignableSectionsParser');
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
3
3
|
import { runParser } from './parser.js';
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import { androidPackageParser } from './androidPackageParser.js';
|
|
5
|
+
import { fetchCid } from './fetchCid.js';
|
|
6
|
+
for (const androidPackageCid of [
|
|
6
7
|
'bafkreicckcmzrdxwoc3w2in3tivpyxrdtcfpct4zwauq3igew3nkpvfapu',
|
|
7
8
|
'bafkreidqycbgrtp7ywhevsgtm464dqpamxsijpaqfcfz2k3ymc3wrzsb5m',
|
|
8
9
|
]) {
|
|
9
|
-
test('
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const actual = await runParser(apkParser, apkStream, uint8ArrayParserInputCompanion, {
|
|
10
|
+
test('androidPackage ' + androidPackageCid, async (t) => {
|
|
11
|
+
const androidPackageStream = await fetchCid(androidPackageCid);
|
|
12
|
+
const actual = await runParser(androidPackageParser, androidPackageStream, uint8ArrayParserInputCompanion, {
|
|
13
13
|
errorJoinMode: 'all',
|
|
14
14
|
});
|
|
15
15
|
for (const entry of actual.entries) {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AndroidPackageSignatureV2SignedData, AndroidPackageSigningBlock } from "./androidPackage.js";
|
|
2
|
+
import { Unparser } from "./unparser.js";
|
|
3
|
+
export declare const androidPackageSignatureV2SignedDataUnparser: Unparser<AndroidPackageSignatureV2SignedData, Uint8Array>;
|
|
4
|
+
export declare const androidPackageSigningBlockUnparser: Unparser<AndroidPackageSigningBlock, Uint8Array>;
|
|
@@ -21,51 +21,51 @@ const createUint64LengthPrefixedUnparser = (innerUnparser) => async function* (i
|
|
|
21
21
|
yield* innerUnparser(input, unparserContext);
|
|
22
22
|
yield* unparserContext.writeEarlier(length, uint64LEUnparser, unparserContext.position - length.positionEnd);
|
|
23
23
|
};
|
|
24
|
-
const
|
|
24
|
+
const androidPackageSignatureV2DigestUnparser = createUint32LengthPrefixedUnparser(async function* (input, unparserContext) {
|
|
25
25
|
yield* uint32LEUnparser(input.signatureAlgorithmId, unparserContext);
|
|
26
26
|
yield* uint32LEUnparser(input.digest.length, unparserContext);
|
|
27
27
|
yield input.digest;
|
|
28
28
|
});
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
29
|
+
const androidPackageSignatureV2DigestsUnparser = createUint32LengthPrefixedUnparser(createArrayUnparser(androidPackageSignatureV2DigestUnparser));
|
|
30
|
+
const androidPackageSignatureV2CertificateUnparser = createUint32LengthPrefixedUnparser(uint8ArrayUnparser);
|
|
31
|
+
const androidPackageSignatureV2CertificatesUnparser = createUint32LengthPrefixedUnparser(createArrayUnparser(androidPackageSignatureV2CertificateUnparser));
|
|
32
|
+
const androidPackageSignatureV2AdditionalAttributeUnparser = createUint32LengthPrefixedUnparser(async function* (input, unparserContext) {
|
|
33
33
|
yield* uint32LEUnparser(input.id, unparserContext);
|
|
34
34
|
yield input.value;
|
|
35
35
|
});
|
|
36
|
-
const
|
|
37
|
-
export const
|
|
38
|
-
yield*
|
|
39
|
-
yield*
|
|
40
|
-
yield*
|
|
36
|
+
const androidPackageSignatureV2AdditionalAttributesUnparser = createUint32LengthPrefixedUnparser(createArrayUnparser(androidPackageSignatureV2AdditionalAttributeUnparser));
|
|
37
|
+
export const androidPackageSignatureV2SignedDataUnparser = createUint32LengthPrefixedUnparser(async function* (input, unparserContext) {
|
|
38
|
+
yield* androidPackageSignatureV2DigestsUnparser(input.digests, unparserContext);
|
|
39
|
+
yield* androidPackageSignatureV2CertificatesUnparser(input.certificates, unparserContext);
|
|
40
|
+
yield* androidPackageSignatureV2AdditionalAttributesUnparser(input.additionalAttributes, unparserContext);
|
|
41
41
|
if (input.zeroPaddingLength) {
|
|
42
42
|
yield Buffer.alloc(input.zeroPaddingLength);
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
|
-
const
|
|
45
|
+
const androidPackageSignatureV2SignatureUnparser = createUint32LengthPrefixedUnparser(async function* (input, unparserContext) {
|
|
46
46
|
yield* uint32LEUnparser(input.signatureAlgorithmId, unparserContext);
|
|
47
47
|
yield* uint32LEUnparser(input.signature.length, unparserContext);
|
|
48
48
|
yield input.signature;
|
|
49
49
|
});
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
yield*
|
|
54
|
-
yield*
|
|
55
|
-
yield*
|
|
50
|
+
const androidPackageSignatureV2SignaturesUnparser = createUint32LengthPrefixedUnparser(createArrayUnparser(androidPackageSignatureV2SignatureUnparser));
|
|
51
|
+
const androidPackageSignatureV2PublicKeyUnparser = createUint32LengthPrefixedUnparser(uint8ArrayUnparser);
|
|
52
|
+
const androidPackageSignatureV2SignerUnparser = createUint32LengthPrefixedUnparser(async function* (input, unparserContext) {
|
|
53
|
+
yield* androidPackageSignatureV2SignedDataUnparser(input.signedData, unparserContext);
|
|
54
|
+
yield* androidPackageSignatureV2SignaturesUnparser(input.signatures, unparserContext);
|
|
55
|
+
yield* androidPackageSignatureV2PublicKeyUnparser(input.publicKey, unparserContext);
|
|
56
56
|
});
|
|
57
|
-
const
|
|
58
|
-
const
|
|
57
|
+
const androidPackageSignatureV2SignersUnparser = createUint32LengthPrefixedUnparser(createArrayUnparser(androidPackageSignatureV2SignerUnparser));
|
|
58
|
+
const androidPackageSigningBlockPairUnparser = createUint64LengthPrefixedUnparser(async function* (input, unparserContext) {
|
|
59
59
|
yield* uint32LEUnparser(input.id, unparserContext);
|
|
60
60
|
if (input.value instanceof Uint8Array) {
|
|
61
61
|
yield input.value;
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
|
-
yield*
|
|
64
|
+
yield* androidPackageSignatureV2SignersUnparser(input.value, unparserContext);
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
|
-
const
|
|
68
|
-
export const
|
|
67
|
+
const androidPackageSigningBlockPairsUnparser = createArrayUnparser(androidPackageSigningBlockPairUnparser);
|
|
68
|
+
export const androidPackageSigningBlockUnparser = async function* (input, unparserContext) {
|
|
69
69
|
const pairs = [
|
|
70
70
|
...input.pairs,
|
|
71
71
|
...(input.signatureV2 ? [
|
|
@@ -82,7 +82,7 @@ export const apkSigningBlockUnparser = async function* (input, unparserContext)
|
|
|
82
82
|
] : []),
|
|
83
83
|
];
|
|
84
84
|
const sizeOfBlockWriteLater = yield* unparserContext.writeLater(8);
|
|
85
|
-
yield*
|
|
85
|
+
yield* androidPackageSigningBlockPairsUnparser(pairs, unparserContext);
|
|
86
86
|
const sizeOfBlock = unparserContext.position - sizeOfBlockWriteLater.position + 16;
|
|
87
87
|
yield* uint64LEUnparser(sizeOfBlock, unparserContext);
|
|
88
88
|
yield* unparserContext.writeEarlier(sizeOfBlockWriteLater, uint64LEUnparser, sizeOfBlock);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
3
|
+
import { runParser } from './parser.js';
|
|
4
|
+
import { androidPackageParser, androidPackageSigningBlockParser } from './androidPackageParser.js';
|
|
5
|
+
import { runUnparser } from './unparser.js';
|
|
6
|
+
import { androidPackageSigningBlockUnparser } from './androidPackageUnparser.js';
|
|
7
|
+
import { uint8ArrayUnparserOutputCompanion } from './unparserOutputCompanion.js';
|
|
8
|
+
import invariant from 'invariant';
|
|
9
|
+
import { fetchCid } from './fetchCid.js';
|
|
10
|
+
for (const androidPackageCid of [
|
|
11
|
+
'bafkreicckcmzrdxwoc3w2in3tivpyxrdtcfpct4zwauq3igew3nkpvfapu',
|
|
12
|
+
]) {
|
|
13
|
+
test('androidPackage ' + androidPackageCid, async (t) => {
|
|
14
|
+
const androidPackageStream = await fetchCid(androidPackageCid);
|
|
15
|
+
const androidPackage = await runParser(androidPackageParser, androidPackageStream, uint8ArrayParserInputCompanion, {
|
|
16
|
+
errorJoinMode: 'all',
|
|
17
|
+
});
|
|
18
|
+
const androidPackageSigningBlock = androidPackage.signingBlock;
|
|
19
|
+
invariant(androidPackageSigningBlock, 'APK has no signing block');
|
|
20
|
+
const androidPackageSigningBlockStream = runUnparser(androidPackageSigningBlockUnparser, androidPackageSigningBlock, uint8ArrayUnparserOutputCompanion);
|
|
21
|
+
const actual = await runParser(androidPackageSigningBlockParser, androidPackageSigningBlockStream, uint8ArrayParserInputCompanion, {
|
|
22
|
+
errorJoinMode: 'all',
|
|
23
|
+
});
|
|
24
|
+
t.deepEqual(actual, androidPackageSigningBlock);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { type Arbitrary } from 'fast-check';
|
|
2
|
-
export declare function arbitrarilySlicedAsyncIterable<Sliceable extends string | Uint8Array>(arbitrarySliceable: Arbitrary<Sliceable
|
|
2
|
+
export declare function arbitrarilySlicedAsyncIterable<Sliceable extends string | Uint8Array>(arbitrarySliceable: Arbitrary<Sliceable>, { minSlices, }?: {
|
|
3
|
+
minSlices?: number;
|
|
4
|
+
}): Arbitrary<[Sliceable, AsyncIterable<Sliceable>]>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { inspect } from 'node:util';
|
|
2
1
|
import * as fc from 'fast-check';
|
|
3
2
|
import invariant from 'invariant';
|
|
3
|
+
import { inspect } from './inspect.js';
|
|
4
4
|
function concat(slices) {
|
|
5
5
|
const firstSlice = slices.at(0);
|
|
6
6
|
if (firstSlice instanceof Uint8Array) {
|
|
@@ -14,8 +14,8 @@ function equals(a, b) {
|
|
|
14
14
|
}
|
|
15
15
|
return a === b;
|
|
16
16
|
}
|
|
17
|
-
export function arbitrarilySlicedAsyncIterable(arbitrarySliceable) {
|
|
18
|
-
return (fc.tuple(arbitrarySliceable, fc.array(fc.nat(), { minLength: 1 }))
|
|
17
|
+
export function arbitrarilySlicedAsyncIterable(arbitrarySliceable, { minSlices = 1, } = {}) {
|
|
18
|
+
return (fc.tuple(arbitrarySliceable, fc.array(fc.nat(), { minLength: Math.max(1, minSlices) }))
|
|
19
19
|
.map(([sliceable, sliceSizes]) => {
|
|
20
20
|
let start = 0;
|
|
21
21
|
const slices = sliceSizes.map(sliceSize => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import { createArrayParser } from './arrayParser.js';
|
|
3
|
-
import {
|
|
3
|
+
import { runParserWithRemainingInput } from './parser.js';
|
|
4
4
|
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
5
5
|
test('does not loop forever with a child parser that does not consume anything', async (t) => {
|
|
6
6
|
const parser = createArrayParser(async () => undefined);
|
|
7
|
-
const
|
|
8
|
-
t.deepEqual(
|
|
7
|
+
const { output } = await runParserWithRemainingInput(parser, 'foo', stringParserInputCompanion);
|
|
8
|
+
t.deepEqual(output, []);
|
|
9
9
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function baksmaliClass(dexStream: AsyncIterable<Uint8Array>, smaliFilePath: string): Promise<string>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import { execa } from 'execa';
|
|
3
|
+
import { temporaryDirectory, temporaryFile } from 'tempy';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
export async function baksmaliClass(dexStream, smaliFilePath) {
|
|
6
|
+
const inputFilePath = temporaryFile();
|
|
7
|
+
const outputDirectoryPath = temporaryDirectory();
|
|
8
|
+
await fs.writeFile(inputFilePath, dexStream);
|
|
9
|
+
await execa('baksmali', [
|
|
10
|
+
'disassemble',
|
|
11
|
+
'--classes', 'L' + smaliFilePath + ';',
|
|
12
|
+
'--output', outputDirectoryPath,
|
|
13
|
+
inputFilePath,
|
|
14
|
+
]);
|
|
15
|
+
await fs.unlink(inputFilePath);
|
|
16
|
+
const smaliFilePath_ = path.join(outputDirectoryPath, smaliFilePath + '.smali');
|
|
17
|
+
const smali = await fs.readFile(smaliFilePath_, 'utf8');
|
|
18
|
+
await fs.rm(outputDirectoryPath, {
|
|
19
|
+
recursive: true,
|
|
20
|
+
});
|
|
21
|
+
return smali;
|
|
22
|
+
}
|
package/build/bsonParser.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getParserName, setParserName } from './parser.js';
|
|
2
|
-
import { invariantDefined } from './invariantDefined.js';
|
|
3
2
|
import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js';
|
|
4
3
|
import { promiseCompose } from './promiseCompose.js';
|
|
5
4
|
import { createTupleParser } from './tupleParser.js';
|
|
@@ -18,8 +17,11 @@ const elementParser = createElementParser();
|
|
|
18
17
|
const nullByteParser = createExactElementParser(0);
|
|
19
18
|
const cstringParser = promiseCompose(createTerminatedArrayParser(parserCreatorCompose(() => elementParser, (byte) => async (parserContext) => parserContext.invariant(byte, 'Expected non-null byte'))(), nullByteParser), ([sequence]) => Buffer.from(sequence).toString('utf8'));
|
|
20
19
|
const doubleParser = promiseCompose(buffer8Parser, buffer => buffer.readDoubleLE(0));
|
|
20
|
+
setParserName(doubleParser, 'doubleParser');
|
|
21
21
|
const int32Parser = promiseCompose(buffer4Parser, buffer => buffer.readInt32LE(0));
|
|
22
|
+
setParserName(int32Parser, 'int32Parser');
|
|
22
23
|
const uint32Parser = promiseCompose(buffer4Parser, buffer => buffer.readUInt32LE(0));
|
|
24
|
+
setParserName(uint32Parser, 'uint32Parser');
|
|
23
25
|
const createFixedLengthStringParser = (length) => promiseCompose(createFixedLengthBufferParser(length), buffer => buffer.toString('utf8'));
|
|
24
26
|
const createFixedLengthNullTerminatedStringParser = (lengthWihoutNullTerminator) => promiseCompose(createTupleParser([
|
|
25
27
|
createFixedLengthStringParser(lengthWihoutNullTerminator),
|
|
@@ -29,12 +31,14 @@ const bsonStringParser = async (parserContext) => {
|
|
|
29
31
|
const stringSize = await uint32Parser(parserContext);
|
|
30
32
|
return createFixedLengthNullTerminatedStringParser(stringSize - 1)(parserContext);
|
|
31
33
|
};
|
|
34
|
+
setParserName(bsonStringParser, 'bsonStringParser');
|
|
32
35
|
const bsonArrayParser = promiseCompose(createTupleParser([
|
|
33
36
|
createSkipParser(4),
|
|
34
37
|
createParserAccessorParser(() => bsonElementListParser),
|
|
35
38
|
]), ([_, elements]) => elements.map(([_, value]) => value));
|
|
39
|
+
setParserName(bsonArrayParser, 'bsonArrayParser');
|
|
36
40
|
const bsonBooleanParser = async (parserContext) => {
|
|
37
|
-
const booleanValue =
|
|
41
|
+
const booleanValue = await parserContext.read(0);
|
|
38
42
|
return booleanValue === 1;
|
|
39
43
|
};
|
|
40
44
|
const int8Parser = promiseCompose(buffer1Parser, buffer => buffer.readInt8(0));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type Constructor } from 'type-fest';
|
|
2
2
|
export type Falsy = '' | 0 | false | undefined;
|
|
3
3
|
export type ValueOrAccessor<T> = T | (() => T);
|
|
4
|
-
export declare function customInvariant<T>(ErrorConstructor: Constructor<Error, [message: string]> | ((message: string) => Error), value: T, formatOrFormatLines: ValueOrAccessor<string | string[]>, ...formatArguments:
|
|
4
|
+
export declare function customInvariant<T>(ErrorConstructor: Constructor<Error, [message: string]> | ((message: string) => Error), value: T, formatOrFormatLines: ValueOrAccessor<string | string[]>, ...formatArguments: (unknown | (() => unknown))[]): Exclude<T, Falsy>;
|