Skip to content
This repository was archived by the owner on Jun 17, 2021. It is now read-only.

Commit 78626a4

Browse files
committed
Enforce hex prefixing for address strings
1 parent 3bbc948 commit 78626a4

File tree

4 files changed

+70
-12
lines changed

4 files changed

+70
-12
lines changed

src/account.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ const ethjsUtil = require('ethjs-util')
22
import * as assert from 'assert'
33
import * as secp256k1 from 'secp256k1'
44
import * as BN from 'bn.js'
5-
import { toBuffer, addHexPrefix, zeros, bufferToHex, unpad } from './bytes'
5+
import { toBuffer, zeros, bufferToHex, unpad } from './bytes'
66
import { keccak, keccak256, rlphash } from './hash'
7+
import { assertIsHexString } from './helpers'
78

89
/**
910
* Returns a zero address.
@@ -17,16 +18,18 @@ export const zeroAddress = function(): string {
1718
/**
1819
* Checks if the address is a valid. Accepts checksummed addresses too.
1920
*/
20-
export const isValidAddress = function(address: string): boolean {
21-
return /^0x[0-9a-fA-F]{40}$/.test(address)
21+
export const isValidAddress = function(hexAddress: string): boolean {
22+
assertIsHexString(hexAddress)
23+
return /^0x[0-9a-fA-F]{40}$/.test(hexAddress)
2224
}
2325

2426
/**
2527
* Checks if a given address is a zero address.
2628
*/
27-
export const isZeroAddress = function(address: string): boolean {
29+
export const isZeroAddress = function(hexAddress: string): boolean {
30+
assertIsHexString(hexAddress)
2831
const zeroAddr = zeroAddress()
29-
return zeroAddr === addHexPrefix(address)
32+
return zeroAddr === hexAddress
3033
}
3134

3235
/**
@@ -39,8 +42,9 @@ export const isZeroAddress = function(address: string): boolean {
3942
* WARNING: Checksums with and without the chainId will differ. As of 2019-06-26, the most commonly
4043
* used variation in Ethereum was without the chainId. This may change in the future.
4144
*/
42-
export const toChecksumAddress = function(address: string, eip1191ChainId?: number): string {
43-
address = ethjsUtil.stripHexPrefix(address).toLowerCase()
45+
export const toChecksumAddress = function(hexAddress: string, eip1191ChainId?: number): string {
46+
assertIsHexString(hexAddress)
47+
const address = ethjsUtil.stripHexPrefix(hexAddress).toLowerCase()
4448

4549
const prefix = eip1191ChainId !== undefined ? eip1191ChainId.toString() + '0x' : ''
4650

@@ -63,8 +67,11 @@ export const toChecksumAddress = function(address: string, eip1191ChainId?: numb
6367
*
6468
* See toChecksumAddress' documentation for details about the eip1191ChainId parameter.
6569
*/
66-
export const isValidChecksumAddress = function(address: string, eip1191ChainId?: number): boolean {
67-
return isValidAddress(address) && toChecksumAddress(address, eip1191ChainId) === address
70+
export const isValidChecksumAddress = function(
71+
hexAddress: string,
72+
eip1191ChainId?: number,
73+
): boolean {
74+
return isValidAddress(hexAddress) && toChecksumAddress(hexAddress, eip1191ChainId) === hexAddress
6875
}
6976

7077
/**

src/helpers.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const ethjsUtil = require('ethjs-util')
2+
3+
/**
4+
* Throws if a string is not hex prefixed
5+
* @param {string} input string to check hex prefix of
6+
*/
7+
export const assertIsHexString = function(input: string): void {
8+
const msg = `This method only supports 0x-prefixed hex strings but input was: ${input}`
9+
if (!ethjsUtil.isHexString(input)) {
10+
throw new Error(msg)
11+
}
12+
}

test/account.spec.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,14 @@ describe('.toChecksumAddress()', function() {
473473
}
474474
})
475475
})
476+
477+
describe('input format', function() {
478+
it('Should throw when the address is not hex-prefixed', function() {
479+
assert.throws(function() {
480+
toChecksumAddress('52908400098527886E0F7030069857D2E4169EE7'.toLowerCase())
481+
})
482+
})
483+
})
476484
})
477485

478486
describe('.isValidChecksumAddress()', function() {
@@ -513,6 +521,14 @@ describe('.isValidChecksumAddress()', function() {
513521
}
514522
})
515523
})
524+
525+
describe('input format', function() {
526+
it('Should throw when the address is not hex-prefixed', function() {
527+
assert.throws(function() {
528+
isValidChecksumAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
529+
})
530+
})
531+
})
516532
})
517533

518534
describe('.isValidAddress()', function() {
@@ -521,10 +537,27 @@ describe('.isValidAddress()', function() {
521537
assert.equal(isValidAddress('0x52908400098527886E0F7030069857D2E4169EE7'), true)
522538
})
523539
it('should return false', function() {
524-
assert.equal(isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
525540
assert.equal(isValidAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6'), false)
526541
assert.equal(isValidAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6aa'), false)
527-
assert.equal(isValidAddress('0X52908400098527886E0F7030069857D2E4169EE7'), false)
528-
assert.equal(isValidAddress('x2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
542+
})
543+
it('should throw when input is not hex prefixed', function() {
544+
assert.throws(function() {
545+
isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
546+
})
547+
assert.throws(function() {
548+
isValidAddress('x2f015c60e0be116b1f0cd534704db9c92118fb6a')
549+
})
550+
assert.throws(function() {
551+
isValidAddress('0X52908400098527886E0F7030069857D2E4169EE7')
552+
})
553+
})
554+
it('error message should have correct format', function() {
555+
const input = '2f015c60e0be116b1f0cd534704db9c92118fb6a'
556+
try {
557+
isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
558+
} catch (err) {
559+
assert(err.message.includes('only supports 0x-prefixed hex strings'))
560+
assert(err.message.includes(input))
561+
}
529562
})
530563
})

test/bytes.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ describe('is zero address', function() {
4040
const nonZeroAddress = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a'
4141
assert.equal(isZeroAddress(nonZeroAddress), false)
4242
})
43+
44+
it('should throw when address is not hex-prefixed', function() {
45+
assert.throws(function() {
46+
isZeroAddress('0000000000000000000000000000000000000000')
47+
})
48+
})
4349
})
4450

4551
describe('unpad', function() {

0 commit comments

Comments
 (0)