From a4e725810ea18db2e948bfca49c264edde2a26b3 Mon Sep 17 00:00:00 2001 From: junderw Date: Sat, 16 Oct 2021 20:17:56 +0900 Subject: [PATCH 1/3] Fix: NodeJS Buffer behavior differed, also perf improvement on hex parsing --- index.js | 20 +++++++++++++++++--- test/node/test-buffer-badhex.js | 6 ++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index cc199262..99e6b76c 100644 --- a/index.js +++ b/index.js @@ -844,9 +844,12 @@ function hexWrite (buf, string, offset, length) { } let i for (i = 0; i < length; ++i) { - const parsed = parseInt(string.substr(i * 2, 2), 16) - if (numberIsNaN(parsed)) return i - buf[offset + i] = parsed + const a = hexCharValueTable[string[i * 2]] + const b = hexCharValueTable[string[i * 2 + 1]] + if (a === undefined || b === undefined) { + return i + } + buf[offset + i] = a << 4 | b } return i } @@ -2098,6 +2101,17 @@ const hexSliceLookupTable = (function () { return table })() +// Lookup table for Buffer.from(x, 'hex') +const hexCharValueTable = (function () { + const alphabet = '0123456789abcdefABCDEF' + const table = {} + for (let i = 0; i < 22; ++i) { + // ABCDEF should be same value as abcdef + table[alphabet[i]] = i < 16 ? i : i - 6 + } + return table +})() + // Return not function with Error if BigInt not supported function defineBigIntMethod (fn) { return typeof BigInt === 'undefined' ? BufferBigIntNotDefined : fn diff --git a/test/node/test-buffer-badhex.js b/test/node/test-buffer-badhex.js index a6388e31..486e166c 100644 --- a/test/node/test-buffer-badhex.js +++ b/test/node/test-buffer-badhex.js @@ -14,6 +14,12 @@ const assert = require('assert'); assert.strictEqual(buf.write('abcdef01', 0, 'hex'), 4); assert.deepStrictEqual(buf, new Buffer([0xab, 0xcd, 0xef, 0x01])); assert.strictEqual(buf.toString('hex'), 'abcdef01'); + // Node Buffer behavior check + // > Buffer.from('abc def01','hex') + // + assert.strictEqual(buf.write('abc def01', 0, 'hex'), 1); + assert.deepStrictEqual(buf, new Buffer([0xab])); + assert.strictEqual(buf.toString('hex'), 'ab'); const copy = Buffer.from(buf.toString('hex'), 'hex'); assert.strictEqual(buf.toString('hex'), copy.toString('hex')); From ddd37ec84287d37fc5136ae1835b27324e9c7e1a Mon Sep 17 00:00:00 2001 From: junderw Date: Sat, 16 Oct 2021 21:54:29 +0900 Subject: [PATCH 2/3] Add myself to AUTHORS.md with the script --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 468aa190..3f4918c7 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -69,5 +69,6 @@ - jkkang (jkkang@smartauth.kr) - Deklan Webster (deklanw@gmail.com) - Martin Heidegger (martin.heidegger@gmail.com) +- junderw (junderwood@bitcoinbank.co.jp) #### Generated by bin/update-authors.sh. From d2d197807628d1dad8cf336a7bc68e5f13ae570a Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Wed, 11 Oct 2023 15:43:14 +1100 Subject: [PATCH 3/3] prefer constant table --- index.js | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 99e6b76c..4c24ca8b 100644 --- a/index.js +++ b/index.js @@ -2101,16 +2101,31 @@ const hexSliceLookupTable = (function () { return table })() -// Lookup table for Buffer.from(x, 'hex') -const hexCharValueTable = (function () { - const alphabet = '0123456789abcdefABCDEF' - const table = {} - for (let i = 0; i < 22; ++i) { - // ABCDEF should be same value as abcdef - table[alphabet[i]] = i < 16 ? i : i - 6 - } - return table -})() +// hex lookup table for Buffer.from(x, 'hex') +const hexCharValueTable = { + '0': 0, + '1': 1, + '2': 2, + '3': 3, + '4': 4, + '5': 5, + '6': 6, + '7': 7, + '8': 8, + '9': 9, + a: 10, + b: 11, + c: 12, + d: 13, + e: 14, + f: 15, + A: 10, + B: 11, + C: 12, + D: 13, + E: 14, + F: 15 +} // Return not function with Error if BigInt not supported function defineBigIntMethod (fn) {