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

Commit 5670bdd

Browse files
committed
Enforce hex prefixing for address strings
1 parent 3bbc948 commit 5670bdd

File tree

3 files changed

+76
-15
lines changed

3 files changed

+76
-15
lines changed

src/account.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ export const zeroAddress = function(): string {
1818
* Checks if the address is a valid. Accepts checksummed addresses too.
1919
*/
2020
export const isValidAddress = function(address: string): boolean {
21+
enforceHexString(address)
2122
return /^0x[0-9a-fA-F]{40}$/.test(address)
2223
}
2324

2425
/**
2526
* Checks if a given address is a zero address.
2627
*/
2728
export const isZeroAddress = function(address: string): boolean {
29+
enforceHexString(address)
2830
const zeroAddr = zeroAddress()
29-
return zeroAddr === addHexPrefix(address)
31+
return zeroAddr === address
3032
}
3133

3234
/**
@@ -40,6 +42,7 @@ export const isZeroAddress = function(address: string): boolean {
4042
* used variation in Ethereum was without the chainId. This may change in the future.
4143
*/
4244
export const toChecksumAddress = function(address: string, eip1191ChainId?: number): string {
45+
enforceHexString(address)
4346
address = ethjsUtil.stripHexPrefix(address).toLowerCase()
4447

4548
const prefix = eip1191ChainId !== undefined ? eip1191ChainId.toString() + '0x' : ''
@@ -115,6 +118,9 @@ export const generateAddress2 = function(
115118
* Returns true if the supplied address belongs to a precompiled account (Byzantium).
116119
*/
117120
export const isPrecompiled = function(address: Buffer | string): boolean {
121+
if (typeof address === 'string') {
122+
enforceHexString(address)
123+
}
118124
const a = unpad(address)
119125
return a.length === 1 && a[0] >= 1 && a[0] <= 8
120126
}
@@ -190,3 +196,14 @@ export const importPublic = function(publicKey: Buffer): Buffer {
190196
}
191197
return publicKey
192198
}
199+
200+
/**
201+
* Helper method which throws if a string is not hex prefixed
202+
* @param {string} input string to check hex prefix of
203+
*/
204+
const enforceHexString = function(input: string): void {
205+
const msg = `This method only supports 0x-prefixed hex strings but input was: ${input}`
206+
if (!ethjsUtil.isHexString(input)) {
207+
throw new Error(msg)
208+
}
209+
}

test/account.spec.ts

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -377,28 +377,33 @@ describe('generateAddress2: EIP-1014 testdata examples', function() {
377377

378378
describe('isPrecompiled', function() {
379379
it('should return true', function() {
380-
assert.equal(isPrecompiled('0000000000000000000000000000000000000001'), true)
381-
assert.equal(isPrecompiled('0000000000000000000000000000000000000002'), true)
382-
assert.equal(isPrecompiled('0000000000000000000000000000000000000003'), true)
383-
assert.equal(isPrecompiled('0000000000000000000000000000000000000004'), true)
384-
assert.equal(isPrecompiled('0000000000000000000000000000000000000005'), true)
385-
assert.equal(isPrecompiled('0000000000000000000000000000000000000006'), true)
386-
assert.equal(isPrecompiled('0000000000000000000000000000000000000007'), true)
387-
assert.equal(isPrecompiled('0000000000000000000000000000000000000008'), true)
380+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000001'), true)
381+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000002'), true)
382+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000003'), true)
383+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000004'), true)
384+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000005'), true)
385+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000006'), true)
386+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000007'), true)
387+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000008'), true)
388388
assert.equal(
389389
isPrecompiled(Buffer.from('0000000000000000000000000000000000000001', 'hex')),
390390
true,
391391
)
392392
})
393393
it('should return false', function() {
394-
assert.equal(isPrecompiled('0000000000000000000000000000000000000000'), false)
395-
assert.equal(isPrecompiled('0000000000000000000000000000000000000009'), false)
396-
assert.equal(isPrecompiled('1000000000000000000000000000000000000000'), false)
394+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000000'), false)
395+
assert.equal(isPrecompiled('0x0000000000000000000000000000000000000009'), false)
396+
assert.equal(isPrecompiled('0x1000000000000000000000000000000000000000'), false)
397397
assert.equal(
398398
isPrecompiled(Buffer.from('0000000000000000000000000000000000000000', 'hex')),
399399
false,
400400
)
401401
})
402+
it('should throw when address is string and not hex-prefixed', function() {
403+
assert.throws(function() {
404+
isPrecompiled('0000000000000000000000000000000000000001')
405+
})
406+
})
402407
})
403408

404409
const eip55ChecksumAddresses = [
@@ -473,6 +478,14 @@ describe('.toChecksumAddress()', function() {
473478
}
474479
})
475480
})
481+
482+
describe('input format', function() {
483+
it('Should throw when the address is not hex-prefixed', function() {
484+
assert.throws(function() {
485+
toChecksumAddress('52908400098527886E0F7030069857D2E4169EE7'.toLowerCase())
486+
})
487+
})
488+
})
476489
})
477490

478491
describe('.isValidChecksumAddress()', function() {
@@ -513,6 +526,14 @@ describe('.isValidChecksumAddress()', function() {
513526
}
514527
})
515528
})
529+
530+
describe('input format', function() {
531+
it('Should throw when the address is not hex-prefixed', function() {
532+
assert.throws(function() {
533+
isValidChecksumAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
534+
})
535+
})
536+
})
516537
})
517538

518539
describe('.isValidAddress()', function() {
@@ -521,10 +542,27 @@ describe('.isValidAddress()', function() {
521542
assert.equal(isValidAddress('0x52908400098527886E0F7030069857D2E4169EE7'), true)
522543
})
523544
it('should return false', function() {
524-
assert.equal(isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
525545
assert.equal(isValidAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6'), false)
526546
assert.equal(isValidAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6aa'), false)
527-
assert.equal(isValidAddress('0X52908400098527886E0F7030069857D2E4169EE7'), false)
528-
assert.equal(isValidAddress('x2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
547+
})
548+
it('should throw when input is not hex prefixed', function() {
549+
assert.throws(function() {
550+
isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
551+
})
552+
assert.throws(function() {
553+
isValidAddress('x2f015c60e0be116b1f0cd534704db9c92118fb6a')
554+
})
555+
assert.throws(function() {
556+
isValidAddress('0X52908400098527886E0F7030069857D2E4169EE7')
557+
})
558+
})
559+
it('error message should have correct format', function() {
560+
const input = '2f015c60e0be116b1f0cd534704db9c92118fb6a'
561+
try {
562+
isValidAddress('2f015c60e0be116b1f0cd534704db9c92118fb6a')
563+
} catch (err) {
564+
assert(err.message.includes('only supports 0x-prefixed hex strings'))
565+
assert(err.message.includes(input))
566+
}
529567
})
530568
})

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)