fix: throw error if hexToBytes or hexToString is provided a string that is not in hex (#2657)

* better error handling

* fix browser tests

* add shared variable

* re-add test case
This commit is contained in:
Mayukha Vadari
2024-05-08 13:02:34 -04:00
committed by GitHub
parent d441361999
commit 9b3bb9c14b
9 changed files with 31 additions and 98 deletions

View File

@@ -1,5 +1,11 @@
# @xrplf/isomorphic Release History
## Unreleased
### Fixed
* Throw error if `hexToBytes` or `hexToString` is provided a string that is not in hex
## 1.0.0 (2024-02-01)
Initial release providing isomorphic and tree-shakable implementations of:
@@ -14,21 +20,3 @@ Initial release providing isomorphic and tree-shakable implementations of:
* randomBytes
* stringToHex
* ws
## 1.0.0 Beta 1 (2023-11-30)
## Added
* hexToString
* stringToHex
## 1.0.0 Beta 0 (2023-10-19)
Initial release providing isomorphic and tree-shakable implementations of:
* ripemd160
* sha256
* sha512
* bytesToHash
* hashToBytes
* randomBytes
* ws_

View File

@@ -9,6 +9,7 @@ import type {
RandomBytesFn,
StringToHexFn,
} from './types'
import { HEX_REGEX } from './shared'
/* eslint-disable func-style -- Typed to ensure uniformity between node and browser implementations and docs */
export const bytesToHex: typeof BytesToHexFn = (bytes) => {
@@ -22,6 +23,9 @@ export const bytesToHex: typeof BytesToHexFn = (bytes) => {
export const hexToBytes: typeof HexToBytesFn = (hex): Uint8Array => {
const len = hex.length
const array = new Uint8Array(len / 2)
if (!HEX_REGEX.test(hex)) {
throw new Error('Invalid hex string')
}
for (let i = 0; i < array.length; i++) {
const j = i * 2
const hexByte = hex.slice(j, j + 2)

View File

@@ -1,6 +1,7 @@
import { randomBytes as cryptoRandomBytes } from 'crypto'
import type { BytesToHexFn, HexToBytesFn, RandomBytesFn } from './types'
import { HexToStringFn, StringToHexFn } from './types'
import { HEX_REGEX } from './shared'
const OriginalBuffer = Symbol('OriginalBuffer')
@@ -64,6 +65,9 @@ export const bytesToHex: typeof BytesToHexFn = (bytes) => {
}
export const hexToBytes: typeof HexToBytesFn = (hex) => {
if (!HEX_REGEX.test(hex)) {
throw new Error('Invalid hex string')
}
return toUint8Array(Buffer.from(hex, 'hex'))
}
@@ -75,6 +79,9 @@ export const hexToString: typeof HexToStringFn = (
hex: string,
encoding = 'utf8',
): string => {
if (!HEX_REGEX.test(hex)) {
throw new Error('Invalid hex string')
}
return new TextDecoder(encoding).decode(hexToBytes(hex))
}

View File

@@ -1,5 +1,7 @@
import { concatBytes } from '@noble/hashes/utils'
export const HEX_REGEX = /^[A-F0-9]*$/iu
export function concat(views: Uint8Array[]): Uint8Array {
return concatBytes(...views)
}

View File

@@ -23,10 +23,18 @@ describe('utils', function () {
expect(hexToBytes('DEADBEEF')).toEqual(new Uint8Array([222, 173, 190, 239]))
})
it('hexToBytes - DEADBEEF', () => {
expect(hexToBytes('DEADBEEF')).toEqual(new Uint8Array([222, 173, 190, 239]))
})
it('bytesToHex - DEADBEEF', () => {
expect(bytesToHex([222, 173, 190, 239])).toEqual('DEADBEEF')
})
it('bytesToHex - bad hex', () => {
expect(() => hexToBytes('hello')).toThrow(new Error('Invalid hex string'))
})
it('bytesToHex - 010203', () => {
expect(bytesToHex([1, 2, 3])).toEqual('010203')
})
@@ -43,6 +51,10 @@ describe('utils', function () {
expect(hexToString('6465616462656566D68D')).toEqual('deadbeef֍')
})
it('hexToString - bad hex', () => {
expect(() => hexToString('hello')).toThrow(new Error('Invalid hex string'))
})
it('stringToHex - deadbeef+infinity symbol (utf8)', () => {
expect(stringToHex('deadbeef֍')).toEqual('6465616462656566D68D')
})