Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions tests/wif.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as lib from '@exodus/bytes/wif.js'
import { toBase58checkSync } from '@exodus/bytes/base58check.js'
import { randomValues } from '@exodus/crypto/randomBytes'
import { test } from 'node:test'
import assert from 'node:assert/strict'
Expand Down Expand Up @@ -73,3 +74,26 @@ test('sizes roundtrip, random data', async (t) => {
}
}
})

test('invalid length throws before version check', async (t) => {
// Regression test: length validation before version check
// Old: threw "Invalid network version" for invalid length with wrong expectedVersion
// New: throws "Invalid WIF length" regardless of expectedVersion

const invalidLengths = [0, 1, 4, 10, 32, 35, 50]

for (const len of invalidLengths) {
const arr = new Uint8Array(len).fill(128)
arr[0] = 42
const encoded = toBase58checkSync(arr)
const wrongVersion = 99

await t.assert.rejects(async () => lib.fromWifString(encoded, wrongVersion), {
message: 'Invalid WIF length',
})

t.assert.throws(() => lib.fromWifStringSync(encoded, wrongVersion), {
message: 'Invalid WIF length',
})
}
})
3 changes: 1 addition & 2 deletions wif.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { assertUint8 } from './assert.js'

function from(arr, expectedVersion) {
assertUint8(arr)
if (arr.length !== 33 && arr.length !== 34) throw new Error('Invalid WIF length')
const version = arr[0]
if (expectedVersion !== undefined && version !== expectedVersion) {
throw new Error('Invalid network version')
Expand All @@ -14,15 +15,13 @@ function from(arr, expectedVersion) {
// Makes a copy, regardless of input being a Buffer or a Uint8Array (unlike .slice)
const privateKey = Uint8Array.from(arr.subarray(1, 33))
if (arr.length === 33) return { version, privateKey, compressed: false }
if (arr.length !== 34) throw new Error('Invalid WIF length')
if (arr[33] !== 1) throw new Error('Invalid compression flag')
return { version, privateKey, compressed: true }
}

function to({ version: v, privateKey, compressed }) {
if (!Number.isSafeInteger(v) || v < 0 || v > 0xff) throw new Error('Missing or invalid version')
assertUint8(privateKey, { length: 32, name: 'privateKey' })
if (privateKey.length !== 32) throw new TypeError('Invalid privateKey length')
const out = new Uint8Array(compressed ? 34 : 33)
out[0] = v
out.set(privateKey, 1)
Expand Down