From 9470831e975b3f44623d29b884075fc4b2b674ef Mon Sep 17 00:00:00 2001 From: Alan Lu Date: Wed, 8 Apr 2020 17:55:35 -0500 Subject: [PATCH 1/2] Use TextEncoder to encode UTF-8 --- packages/web3-utils/package.json | 3 +-- packages/web3-utils/src/utils.js | 34 ++++++++++++++++++++------------ test/utils.toUtf8.js | 3 ++- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/web3-utils/package.json b/packages/web3-utils/package.json index d972bdcebb8..2c72c896648 100644 --- a/packages/web3-utils/package.json +++ b/packages/web3-utils/package.json @@ -19,8 +19,7 @@ "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", - "underscore": "1.9.1", - "utf8": "3.0.0" + "underscore": "1.9.1" }, "devDependencies": { "definitelytyped-header-parser": "^1.0.1", diff --git a/packages/web3-utils/src/utils.js b/packages/web3-utils/src/utils.js index da0ec263031..30268d414c0 100644 --- a/packages/web3-utils/src/utils.js +++ b/packages/web3-utils/src/utils.js @@ -23,10 +23,19 @@ var _ = require('underscore'); var BN = require('bn.js'); var numberToBN = require('number-to-bn'); -var utf8 = require('utf8'); var Hash = require("eth-lib/lib/hash"); var ethereumBloomFilters = require('ethereum-bloom-filters'); +var utf8Encoder; +var utf8Decoder; +if (typeof TextEncoder !== 'undefined' && typeof TextDecoder !== 'undefined') { + utf8Encoder = new TextEncoder(); + utf8Decoder = new TextDecoder(); +} else { + var util = require('util'); + utf8Encoder = new util.TextEncoder(); + utf8Decoder = new util.TextDecoder(); +} /** @@ -166,23 +175,22 @@ var rightPad = function (string, chars, sign) { * @returns {String} hex representation of input string */ var utf8ToHex = function(str) { - str = utf8.encode(str); + var bytes = utf8Encoder.encode(str); var hex = ""; - // remove \u0000 padding from either side - str = str.replace(/^(?:\u0000)*/,''); - str = str.split("").reverse().join(""); - str = str.replace(/^(?:\u0000)*/,''); - str = str.split("").reverse().join(""); - - for(var i = 0; i < str.length; i++) { - var code = str.charCodeAt(i); + for(var i = 0; i < bytes.length; i++) { + var code = bytes[i]; // if (code !== 0) { var n = code.toString(16); hex += n.length < 2 ? '0' + n : n; // } } + hex = hex.replace(/^(?:00)*/,''); + hex = hex.split("").reverse().join(""); + hex = hex.replace(/^(?:00)*/,''); + hex = hex.split("").reverse().join(""); + return "0x" + hex; }; @@ -197,7 +205,7 @@ var hexToUtf8 = function(hex) { if (!isHexStrict(hex)) throw new Error('The parameter "'+ hex +'" must be a valid HEX string.'); - var str = ""; + var bytes = []; var code = 0; hex = hex.replace(/^0x/i,''); @@ -212,11 +220,11 @@ var hexToUtf8 = function(hex) { for (var i=0; i < l; i+=2) { code = parseInt(hex.substr(i, 2), 16); // if (code !== 0) { - str += String.fromCharCode(code); + bytes.push(code); // } } - return utf8.decode(str); + return utf8Decoder.decode(Uint8Array.from(bytes)); }; diff --git a/test/utils.toUtf8.js b/test/utils.toUtf8.js index 22914e8b052..f89a79bda41 100644 --- a/test/utils.toUtf8.js +++ b/test/utils.toUtf8.js @@ -8,7 +8,8 @@ var tests = [ { value: '0x6d79537472696e67', expected: 'myString'}, { value: '0x6d79537472696e6700', expected: 'myString'}, { value: '0x65787065637465642076616c7565000000000000000000000000000000000000', expected: 'expected value'}, - { value: '0x000000000000000000000000000000000000657870656374000065642076616c7565', expected: 'expect\u0000\u0000ed value'} + { value: '0x000000000000000000000000000000000000657870656374000065642076616c7565', expected: 'expect\u0000\u0000ed value'}, + { value: '0x9f90e274657374', expected: '���test' } ]; describe('lib/utils/utils', function () { From e10373623c356c3b995b642ba598a1eddcf8421e Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 9 Apr 2020 10:41:53 -0700 Subject: [PATCH 2/2] Add utf8 tests to headless browser suite --- karma.conf.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 00caf992889..90ab3175749 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -10,14 +10,17 @@ function getTestFiles(){ switch (process.env.BROWSER_BUNDLE_TEST){ case 'publishedDist': return ["packages/web3/dist/web3.min.js", "test/e2e.minified.js"] case 'gitRepoDist': return ["dist/web3.min.js", "test/e2e.minified.js"] - default: return ["test/**/e2e*.js"] + default: return ["test/**/e2e*.js", "test/**/*tf8*.js"] } } // Only loads browserified preprocessor for the logic unit tests so we can `require` stuff. function getPreprocessors(){ if (!process.env.BROWSER_BUNDLE_TEST){ - return { 'test/**/e2e*.js': [ 'browserify' ] } + return { + 'test/**/e2e*.js': [ 'browserify' ], + 'test/**/*tf8*.js': [ 'browserify' ] + } } }