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

Commit ebe0723

Browse files
authored
Merge pull request #241 from ethereumjs/enforce-hex-value-format
Enforce hex prefixing for address strings
2 parents 615d0c6 + 26bad87 commit ebe0723

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 } from './bytes'
5+
import { toBuffer, zeros, bufferToHex } 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
@@ -446,6 +446,14 @@ describe('.toChecksumAddress()', function() {
446446
}
447447
})
448448
})
449+
450+
describe('input format', function() {
451+
it('Should throw when the address is not hex-prefixed', function() {
452+
assert.throws(function() {
453+
toChecksumAddress('52908400098527886E0F7030069857D2E4169EE7'.toLowerCase())
454+
})
455+
})
456+
})
449457
})
450458

451459
describe('.isValidChecksumAddress()', function() {
@@ -486,6 +494,14 @@ describe('.isValidChecksumAddress()', function() {
486494
}
487495
})
488496
})
497+
498+
describe('input format', function() {
499+
it('Should throw when the address is not hex-prefixed', function() {
500+
assert.throws(function() {
501+
isValidChecksumAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
502+
})
503+
})
504+
})
489505
})
490506

491507
describe('.isValidAddress()', function() {
@@ -494,10 +510,27 @@ describe('.isValidAddress()', function() {
494510
assert.equal(isValidAddress('0x52908400098527886E0F7030069857D2E4169EE7'), true)
495511
})
496512
it('should return false', function() {
497-
assert.equal(isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
498513
assert.equal(isValidAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6'), false)
499514
assert.equal(isValidAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6aa'), false)
500-
assert.equal(isValidAddress('0X52908400098527886E0F7030069857D2E4169EE7'), false)
501-
assert.equal(isValidAddress('x2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
515+
})
516+
it('should throw when input is not hex prefixed', function() {
517+
assert.throws(function() {
518+
isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
519+
})
520+
assert.throws(function() {
521+
isValidAddress('x2f015c60e0be116b1f0cd534704db9c92118fb6a')
522+
})
523+
assert.throws(function() {
524+
isValidAddress('0X52908400098527886E0F7030069857D2E4169EE7')
525+
})
526+
})
527+
it('error message should have correct format', function() {
528+
const input = '2f015c60e0be116b1f0cd534704db9c92118fb6a'
529+
try {
530+
isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
531+
} catch (err) {
532+
assert(err.message.includes('only supports 0x-prefixed hex strings'))
533+
assert(err.message.includes(input))
534+
}
502535
})
503536
})

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)