diff --git a/lib/index.js b/lib/index.js index 657701c3..36cdc7a4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,12 +1,14 @@ "use strict"; var Buffer = require("safer-buffer").Buffer; +var objectAssign = require('object-assign') var bomHandling = require("./bom-handling"), iconv = module.exports; // All codecs and aliases are kept here, keyed by encoding name/alias. // They are lazy loaded in `iconv.getCodec` from `encodings/index.js`. +// Cannot initialize with Object.create(null) because Boolean(Object.create(null)) === true iconv.encodings = null; // Characters emitted in case of error. @@ -57,10 +59,13 @@ iconv.toEncoding = iconv.encode; iconv.fromEncoding = iconv.decode; // Search for a codec in iconv.encodings. Cache codec data in iconv._codecDataCache. -iconv._codecDataCache = {}; +iconv._codecDataCache = Object.create(null); + iconv.getCodec = function getCodec(encoding) { - if (!iconv.encodings) - iconv.encodings = require("../encodings"); // Lazy load all encoding definitions. + if (!iconv.encodings) { + var raw = require("../encodings"); + iconv.encodings = objectAssign(Object.create(null), raw); // Lazy load all encoding definitions. + } // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. var enc = iconv._canonicalizeEncoding(encoding); diff --git a/package.json b/package.json index b29b1136..47031cfa 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "unorm": "^1.6.0" }, "dependencies": { + "object-assign": ">= 4.1.1 < 5.0.0", "safer-buffer": ">= 2.1.2 < 3.0.0" } } diff --git a/test/main-test.js b/test/main-test.js index 060bd91d..43b84a1c 100644 --- a/test/main-test.js +++ b/test/main-test.js @@ -7,8 +7,26 @@ var testStringLatin1 = "Hello123!£Å÷×çþÿ¿®"; var testStringBase64 = "SGVsbG8xMjMh"; var testStringHex = "48656c6c6f31323321"; + +describe("Encoding Existence - Prototype Properties", function() { + it("should not detect prototype properties as encodings", function () { + assert.equal(iconv.encodingExists("__proto__"), false); + assert.equal(iconv.encodingExists("constructor"), false); + }); + + it("should detect encodings", function () { + assert.equal(iconv.encodingExists("utf8"), true); + }) +}); + +describe("Encoding Existence - Codec Data Cache", function () { + it("should not detect 'constructor' as encoding when _codecDataCache is defined", function () { + assert.equal(iconv.encodingExists("__proto__"), false); + assert.equal(iconv.encodingExists("constructor"), false); + }); +}); + describe("Generic UTF8-UCS2 tests", function() { - it("Return values are of correct types", function() { assert.ok(Buffer.isBuffer(iconv.encode(testString, "utf8"))); @@ -45,8 +63,10 @@ describe("Generic UTF8-UCS2 tests", function() { }); it("Throws on unknown encodings", function() { - assert.throws(function() { iconv.encode("a", "xxx"); }); + assert. throws(function() { iconv.encode("a", "xxx"); }); assert.throws(function() { iconv.decode(Buffer.from("a"), "xxx"); }); + assert.throws(function () { iconv.encode("abc", "constructor") } ); + assert.throws( function () { iconv.decode(Buffer.from("abc"), "constructor") } ); }); it("Convert non-strings and non-buffers", function() { @@ -64,7 +84,7 @@ describe("Generic UTF8-UCS2 tests", function() { Object.prototype.permits = function() {}; Array.prototype.sample2 = function() {}; - iconv._codecDataCache = {}; // Clean up cache so that all encodings are loaded. + iconv._codecDataCache = Object.create(null); // Clean up cache so that all encodings are loaded. assert.strictEqual(iconv.decode(Buffer.from("abc"), "gbk"), "abc"); assert.strictEqual(iconv.decode(Buffer.from("abc"), "win1251"), "abc");