diff --git a/ini.js b/ini.js index 0401258..527f0e3 100644 --- a/ini.js +++ b/ini.js @@ -18,7 +18,7 @@ function encode (obj, opt) { whitespace: false } } else { - opt = opt || {} + opt = opt || Object.create(null) opt.whitespace = opt.whitespace === true } @@ -67,7 +67,7 @@ function dotSplit (str) { } function decode (str) { - var out = {} + var out = Object.create(null) var p = out var section = null // section |key = value @@ -83,13 +83,14 @@ function decode (str) { if (section === '__proto__') { // not allowed // keep parsing the section, but don't attach it. - p = {} + p = Object.create(null) return } - p = out[section] = out[section] || {} + p = out[section] = out[section] || Object.create(null) return } var key = unsafe(match[2]) + if (key === '__proto__') return var value = match[3] ? unsafe(match[4]) : true switch (value) { case 'true': @@ -133,7 +134,7 @@ function decode (str) { var nl = l.replace(/\\\./g, '.') parts.forEach(function (part, _, __) { if (part === '__proto__') return - if (!p[part] || typeof p[part] !== 'object') p[part] = {} + if (!p[part] || typeof p[part] !== 'object') p[part] = Object.create(null) p = p[part] }) if (p === out && nl === l) { diff --git a/test/proto.js b/test/proto.js index ab35533..381fda6 100644 --- a/test/proto.js +++ b/test/proto.js @@ -3,6 +3,7 @@ var t = require('tap') var data = ` __proto__ = quux +constructor.prototype.foo = asdfasdf foo = baz [__proto__] foo = bar @@ -15,27 +16,39 @@ hello = snyk __proto__[] = you did a good job __proto__[] = so you deserve arrays thanks = true +[ctor.constructor.prototype] +foo = asdfasdf ` + var res = ini.parse(data) -t.deepEqual(res, { + +t.deepEqual(res, Object.assign(Object.create(null), { + 'constructor.prototype.foo': 'asdfasdf', foo: 'baz', - other: { + other: Object.assign(Object.create(null), { foo: 'asdf', - }, - kid: { - foo: { + }), + kid: Object.assign(Object.create(null), { + foo: Object.assign(Object.create(null), { foo: 'kid', - }, - }, - arrproto: { + }), + }), + arrproto: Object.assign(Object.create(null), { hello: 'snyk', thanks: true, - }, -}) -t.equal(res.__proto__, Object.prototype) -t.equal(res.kid.__proto__, Object.prototype) -t.equal(res.kid.foo.__proto__, Object.prototype) -t.equal(res.arrproto.__proto__, Object.prototype) + }), + ctor: Object.assign(Object.create(null), { + constructor: Object.assign(Object.create(null), { + prototype: Object.assign(Object.create(null), { + foo: 'asdfasdf', + }), + }), + }), +})) +t.equal(res.__proto__, undefined) +t.equal(res.kid.__proto__, undefined) +t.equal(res.kid.foo.__proto__, undefined) +t.equal(res.arrproto.__proto__, undefined) t.equal(Object.prototype.foo, undefined) t.equal(Object.prototype[0], undefined) t.equal(Object.prototype['0'], undefined)