From de9c33ab2a0a1df207b89a3183cb7b1917b7f17e Mon Sep 17 00:00:00 2001 From: Alex Dupre Date: Tue, 24 May 2022 12:31:33 +0200 Subject: [PATCH] Fix serious issue in `.toString(16)` (#295) * Add test for `.toString(16)` * Fix serious issue in `.toString(16)` The hex encoding of some numbers is wrong. Since the string representation is also used for interoperability between BigInt libraries, this bug is causing a number modification when a BN.js number is converted into another BigInt class, for example the BigNumber of ethers.js. --- lib/bn.js | 10 +++++----- test/utils-test.js | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/bn.js b/lib/bn.js index 3a4371ea..ee786466 100644 --- a/lib/bn.js +++ b/lib/bn.js @@ -452,16 +452,16 @@ var w = this.words[i]; var word = (((w << off) | carry) & 0xffffff).toString(16); carry = (w >>> (24 - off)) & 0xffffff; - if (carry !== 0 || i !== this.length - 1) { - out = zeros[6 - word.length] + word + out; - } else { - out = word + out; - } off += 2; if (off >= 26) { off -= 26; i--; } + if (carry !== 0 || i !== this.length - 1) { + out = zeros[6 - word.length] + word + out; + } else { + out = word + out; + } } if (carry !== 0) { out = carry.toString(16) + out; diff --git a/test/utils-test.js b/test/utils-test.js index 8571905a..d800873a 100644 --- a/test/utils-test.js +++ b/test/utils-test.js @@ -5,6 +5,16 @@ var BN = require('../').BN; describe('BN.js/Utils', function () { describe('.toString()', function () { + describe('hex no padding', function () { + it('should have same length as input', function () { + var hex = '1'; + for (var i = 1; i <= 128; i++) { + var n = new BN(hex, 16); + assert.equal(n.toString(16).length, i); + hex = hex + '0'; + } + }); + }); describe('binary padding', function () { it('should have a length of 256', function () { var a = new BN(0);