From c4a4dd5682b266192369f1a09c3426bb3586144b Mon Sep 17 00:00:00 2001 From: Rob Halff Date: Sun, 16 Feb 2020 19:15:35 +0100 Subject: [PATCH] prepare v2.1.3 --- CHANGELOG.md | 3 + bower.json | 2 +- dist/dot-object.js | 122 ++++++++++++++++++++++++----------------- dist/dot-object.min.js | 2 +- index.js | 7 ++- package.json | 2 +- src/dot-object.js | 7 ++- 7 files changed, 85 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ea1fb5..5735436 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # ChangeLog +## 2020-16-02 Version 2.1.3 +* fix possible pollution of prototype for paths containing __proto__ + ## 2019-11-02 Version 2.1.1 * fix undefined key with root level array. diff --git a/bower.json b/bower.json index e3686db..ce2bb83 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "dot-object", - "version": "2.1.2", + "version": "2.1.3", "description": "dot-object makes it possible to transform and read (JSON) objects using dot notation.", "main": "dist/dot-object.js", "authors": [ diff --git a/dist/dot-object.js b/dist/dot-object.js index 208a405..32d457d 100644 --- a/dist/dot-object.js +++ b/dist/dot-object.js @@ -46,11 +46,25 @@ return Object.keys(val).length === 0 } + var blacklist = ['__proto__', 'prototype', 'constructor'] + var blacklistFilter = function(part) { + return blacklist.indexOf(part) === -1 + } + function parsePath(path, sep) { if (path.indexOf('[') >= 0) { path = path.replace(/\[/g, '.').replace(/]/g, '') } - return path.split(sep) + + var parts = path.split(sep) + + var check = parts.filter(blacklistFilter) + + if (check.length !== parts.length) { + throw Error('Refusing to update blacklisted property ' + path) + } + + return parts } var hasOwnProperty = Object.prototype.hasOwnProperty @@ -85,8 +99,7 @@ var k = a.shift() if (a.length > 0) { - obj[k] = obj[k] || - (this.useArray && isIndex(a[0]) ? [] : {}) + obj[k] = obj[k] || (this.useArray && isIndex(a[0]) ? [] : {}) if (!isArrayOrObject(obj[k])) { if (this.override) { @@ -104,8 +117,7 @@ this._fill(a, obj[k], v, mod) } else { - if (!this.override && - isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) { + if (!this.override && isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) { if (!(isArrayOrObject(v) && isEmptyObject(v))) { throw new Error("Trying to redefine non-empty obj['" + k + "']") } @@ -197,7 +209,7 @@ for (i = 0; i < keys.length; i++) { key = parseKey(keys[i], obj) if (obj && typeof obj === 'object' && key in obj) { - if (i === (keys.length - 1)) { + if (i === keys.length - 1) { if (remove) { val = obj[key] if (reindexArray && Array.isArray(obj)) { @@ -342,13 +354,21 @@ * @param {Function|Array} mods * @param {Boolean} merge */ - DotObject.prototype.transfer = function(source, target, obj1, obj2, mods, merge) { + DotObject.prototype.transfer = function( + source, + target, + obj1, + obj2, + mods, + merge + ) { if (typeof mods === 'function' || Array.isArray(mods)) { - this.set(target, - _process( - this.pick(source, obj1, true), - mods - ), obj2, merge) + this.set( + target, + _process(this.pick(source, obj1, true), mods), + obj2, + merge + ) } else { merge = mods this.set(target, this.pick(source, obj1, true), obj2, merge) @@ -373,16 +393,16 @@ */ DotObject.prototype.copy = function(source, target, obj1, obj2, mods, merge) { if (typeof mods === 'function' || Array.isArray(mods)) { - this.set(target, + this.set( + target, _process( // clone what is picked - JSON.parse( - JSON.stringify( - this.pick(source, obj1, false) - ) - ), + JSON.parse(JSON.stringify(this.pick(source, obj1, false))), mods - ), obj2, merge) + ), + obj2, + merge + ) } else { merge = mods this.set(target, this.pick(source, obj1, false), obj2, merge) @@ -414,7 +434,7 @@ for (i = 0; i < keys.length; i++) { key = keys[i] - if (i === (keys.length - 1)) { + if (i === keys.length - 1) { if (merge && isObject(val) && isObject(obj[key])) { for (k in val) { if (hasOwnProperty.call(val, k)) { @@ -472,9 +492,11 @@ DotObject.prototype.transform = function(recipe, obj, tgt) { obj = obj || {} tgt = tgt || {} - Object.keys(recipe).forEach(function(key) { - this.set(recipe[key], this.pick(key, obj), tgt) - }.bind(this)) + Object.keys(recipe).forEach( + function(key) { + this.set(recipe[key], this.pick(key, obj), tgt) + }.bind(this) + ) return tgt } @@ -500,31 +522,33 @@ path = path || [] var isArray = Array.isArray(obj) - Object.keys(obj).forEach(function(key) { - var index = isArray && this.useBrackets ? '[' + key + ']' : key - if ( - ( + Object.keys(obj).forEach( + function(key) { + var index = isArray && this.useBrackets ? '[' + key + ']' : key + if ( isArrayOrObject(obj[key]) && - ( - (isObject(obj[key]) && !isEmptyObject(obj[key])) || - (Array.isArray(obj[key]) && (!this.keepArray && (obj[key].length !== 0))) - ) - ) - ) { - if (isArray && this.useBrackets) { - var previousKey = path[path.length - 1] || '' - return this.dot(obj[key], tgt, path.slice(0, -1).concat(previousKey + index)) - } else { - return this.dot(obj[key], tgt, path.concat(index)) - } - } else { - if (isArray && this.useBrackets) { - tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key] + ((isObject(obj[key]) && !isEmptyObject(obj[key])) || + (Array.isArray(obj[key]) && !this.keepArray && obj[key].length !== 0)) + ) { + if (isArray && this.useBrackets) { + var previousKey = path[path.length - 1] || '' + return this.dot( + obj[key], + tgt, + path.slice(0, -1).concat(previousKey + index) + ) + } else { + return this.dot(obj[key], tgt, path.concat(index)) + } } else { - tgt[path.concat(index).join(this.separator)] = obj[key] + if (isArray && this.useBrackets) { + tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key] + } else { + tgt[path.concat(index).join(this.separator)] = obj[key] + } } - } - }.bind(this)) + }.bind(this) + ) return tgt } @@ -538,9 +562,7 @@ DotObject.set = wrap('set') DotObject.delete = wrap('delete') DotObject.del = DotObject.remove = wrap('remove') - DotObject.dot = wrap('dot') - - ; + DotObject.dot = wrap('dot'); ['override', 'overwrite'].forEach(function(prop) { Object.defineProperty(DotObject, prop, { get: function() { @@ -550,9 +572,7 @@ dotDefault.override = !!val } }) - }) - - ; + }); ['useArray', 'keepArray', 'useBrackets'].forEach(function(prop) { Object.defineProperty(DotObject, prop, { get: function() { diff --git a/dist/dot-object.min.js b/dist/dot-object.min.js index 356a592..a7cdf42 100644 --- a/dist/dot-object.min.js +++ b/dist/dot-object.min.js @@ -1 +1 @@ -!function(t){"use strict";function s(t,r){var e,i;if("function"==typeof r)void 0!==(i=r(t))&&(t=i);else if(Array.isArray(r))for(e=0;e= 0) { path = path.replace(/\[/g, '.').replace(/]/g, '') } - const parts = path.split(sep) + var parts = path.split(sep) - const check = parts.filter(part => blacklist.indexOf(part) === -1) + var check = parts.filter(blacklistFilter) if (check.length !== parts.length) { throw Error('Refusing to update blacklisted property ' + path) diff --git a/package.json b/package.json index 1a64564..3162967 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dot-object", "description": "dot-object makes it possible to transform and read (JSON) objects using dot notation.", - "version": "2.1.2", + "version": "2.1.3", "author": { "name": "Rob Halff", "email": "rob.halff@gmail.com" diff --git a/src/dot-object.js b/src/dot-object.js index a7f5c9e..6a3a0e5 100644 --- a/src/dot-object.js +++ b/src/dot-object.js @@ -45,16 +45,17 @@ function isEmptyObject (val) { return Object.keys(val).length === 0 } -const blacklist = ['__proto__', 'prototype', 'constructor'] +var blacklist = ['__proto__', 'prototype', 'constructor'] +var blacklistFilter = function (part) { return blacklist.indexOf(part) === -1 } function parsePath (path, sep) { if (path.indexOf('[') >= 0) { path = path.replace(/\[/g, '.').replace(/]/g, '') } - const parts = path.split(sep) + var parts = path.split(sep) - const check = parts.filter(part => blacklist.indexOf(part) === -1) + var check = parts.filter(blacklistFilter) if (check.length !== parts.length) { throw Error('Refusing to update blacklisted property ' + path)