From 13d06de54f1c2338c24d400e3b05932e2b5c15c6 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Thu, 14 May 2026 11:06:29 -0700 Subject: [PATCH] Enforce stronger type checks on async results. Rethrow errors encountered in async worker. --- src/lib/nano25519.ts | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/lib/nano25519.ts b/src/lib/nano25519.ts index 8dfcb43..42b869a 100644 --- a/src/lib/nano25519.ts +++ b/src/lib/nano25519.ts @@ -187,7 +187,7 @@ const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: typeof */ function handleMessage (message: unknown): void { NODE: if (host == null) setTimeout(() => handleMessage(message), 0) - let result: any = null + let result: undefined | boolean | string | Uint8Array try { if (message == null || typeof message !== 'object' @@ -210,11 +210,11 @@ const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: typeof const { action } = data if (action === 'derive') { const { privateKey } = data - const publicKeyBytes = derive(privateKey) - if (publicKeyBytes == null) { + const publicKey = derive(privateKey) + if (publicKey == null) { throw new TypeError('Invalid public key from WASM derive()') } - result = publicKeyBytes + result = publicKey } else if (action === 'sign') { const { message, secretKey } = data const signature = sign(message, secretKey) @@ -238,9 +238,9 @@ const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: typeof buffer.setUint8(inPtr + i, 0) } if (typeof err === 'object' && err != null) { - const e = err as { [k: string]: unknown } - if (e.message !== 'divide by zero') { - result = e.message + const { message } = err as { [k: string]: unknown } + if (typeof message === 'string' && message !== 'divide by zero') { + result = message } } else { result = JSON.stringify(err) @@ -276,6 +276,10 @@ let isWorkerListening: boolean = false let worker: Worker | NodeWorker let url: string +function isBytes (a: unknown): a is Uint8Array { + return a instanceof Uint8Array && a.buffer instanceof ArrayBuffer +} + // Create worker module function init (): void { try { @@ -337,14 +341,17 @@ async function dispatch (data: { [key: string]: string | ArrayBuffer | Uint8Arra return new Promise((resolve, reject) => { const transfer: ArrayBuffer[] = [] for (let k of Object.keys(data)) { - if (data[k] instanceof Uint8Array) { + if (isBytes(data[k])) { data[k] = data[k].buffer.slice() transfer.push(data[k]) } } - const onresult = (msg: any): void => { + const onresult = (msg: Record<"data", unknown>): void => { const result = msg.data console.log(`received result from worker: `, result) + if (typeof result !== 'boolean' && typeof result !== 'string' && !isBytes(result)) { + return reject('Invalid return type') + } resolve(result) } //@ts-expect-error @@ -400,20 +407,20 @@ export async function run (data: Record } try { const result = await dispatch(data) - if (typeof result !== 'boolean' && typeof result !== 'string' && !(result instanceof Uint8Array)) { + if (typeof result === 'string' && !/^([a-f0-9]{64}|[a-f0-9]{128})$/i.test(result)) { throw new Error(result) } return result } catch (err: any) { + console.error(err) + console.error(data) try { - console.error(err) - console.error(data) await stop() } catch (e: any) { console.error('failed to stop worker', err?.message ?? err ?? 'unknown reason') reset() } finally { - return '' + throw new Error(err?.message ?? err ?? 'unknown error') } } } -- 2.47.3