refactor: extend transformBlob to take cleanup function
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

This commit is contained in:
鲁树人 2023-06-10 16:22:36 +01:00
parent 6d925f744e
commit b3ef596a93
2 changed files with 20 additions and 15 deletions

View File

@ -9,11 +9,11 @@ export class QMC2Crypto implements CryptoBase {
checkByDecryptHeader = false; checkByDecryptHeader = false;
async decrypt(buffer: ArrayBuffer): Promise<Blob> { async decrypt(buffer: ArrayBuffer): Promise<Blob> {
// FIXME: Move the cleanup to transformBlob const parakeet = await fetchParakeet();
const mod = await fetchParakeet(); const footerParser = parakeet.make.QMCv2FooterParser(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2);
const footerParser = mod.make.QMCv2FooterParser(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2); return transformBlob(buffer, (p) => p.make.QMCv2(footerParser), {
return transformBlob(buffer, (p) => p.make.QMCv2(footerParser)).finally(() => { parakeet,
footerParser.delete(); cleanup: () => footerParser.delete(),
}); });
} }
@ -35,12 +35,14 @@ export class QMC2CryptoWithKey implements CryptoBase {
throw new Error('key was not provided'); throw new Error('key was not provided');
} }
// FIXME: Move the cleanup to transformBlob const parakeet = await fetchParakeet();
const mod = await fetchParakeet();
const textEncoder = new TextEncoder(); const textEncoder = new TextEncoder();
const key = textEncoder.encode(options.qmc2Key); const key = textEncoder.encode(options.qmc2Key);
const keyCrypto = mod.make.QMCv2KeyCrypto(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2); const keyCrypto = parakeet.make.QMCv2KeyCrypto(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2);
return transformBlob(buffer, (p) => p.make.QMCv2EKey(key, keyCrypto)); return transformBlob(buffer, (p) => p.make.QMCv2EKey(key, keyCrypto), {
parakeet,
cleanup: () => keyCrypto.delete(),
});
} }
public static make() { public static make() {

View File

@ -5,21 +5,24 @@ import { UnsupportedSourceFile } from './DecryptError';
export async function transformBlob( export async function transformBlob(
blob: Blob | ArrayBuffer, blob: Blob | ArrayBuffer,
transformerFactory: (p: Parakeet) => Transformer | Promise<Transformer>, transformerFactory: (p: Parakeet) => Transformer | Promise<Transformer>,
parakeet?: Parakeet { cleanup, parakeet }: { cleanup?: () => void; parakeet?: Parakeet } = {}
) { ) {
const cleanup: (() => void)[] = []; const registeredCleanupFns: (() => void)[] = [];
if (cleanup) {
registeredCleanupFns.push(cleanup);
}
try { try {
const mod = parakeet ?? (await fetchParakeet()); const mod = parakeet ?? (await fetchParakeet());
const transformer = await transformerFactory(mod); const transformer = await transformerFactory(mod);
cleanup.push(() => transformer.delete()); registeredCleanupFns.push(() => transformer.delete());
const reader = mod.make.Reader(await toArrayBuffer(blob)); const reader = mod.make.Reader(await toArrayBuffer(blob));
cleanup.push(() => reader.delete()); registeredCleanupFns.push(() => reader.delete());
const sink = mod.make.WriterSink(); const sink = mod.make.WriterSink();
const writer = sink.getWriter(); const writer = sink.getWriter();
cleanup.push(() => writer.delete()); registeredCleanupFns.push(() => writer.delete());
const result = transformer.Transform(writer, reader); const result = transformer.Transform(writer, reader);
if (result === TransformResult.ERROR_INVALID_FORMAT) { if (result === TransformResult.ERROR_INVALID_FORMAT) {
@ -30,6 +33,6 @@ export async function transformBlob(
return sink.collectBlob(); return sink.collectBlob();
} finally { } finally {
cleanup.forEach((clean) => clean()); registeredCleanupFns.forEach((cleanup) => cleanup());
} }
} }