]> git.codecow.com Git - nano25519.git/commitdiff
Enforce stronger type checks on async results. Rethrow errors encountered in async...
authorChris Duncan <chris@codecow.com>
Thu, 14 May 2026 18:06:29 +0000 (11:06 -0700)
committerChris Duncan <chris@codecow.com>
Thu, 14 May 2026 18:06:29 +0000 (11:06 -0700)
src/lib/nano25519.ts

index 8dfcb433aa55ce18663bfd7796116a9535205561..42b869a686d9d641fbda9b7dd76aac8328ffd7cc 100644 (file)
@@ -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<ArrayBuffer>
                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<ArrayBuffer> {
+       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<string, string | Uint8Array<ArrayBuffer>
        }
        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')
                }
        }
 }