From 4d8ed03c008d1f3266e600a96417813e36d64a8e Mon Sep 17 00:00:00 2001 From: dead-horse Date: Thu, 2 Mar 2017 20:55:20 +0800 Subject: [PATCH] [Fix] follow `allowPrototypes` option during merge Fixes #200. --- lib/utils.js | 4 +++- test/parse.js | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index 5d433560..d829b082 100755 --- a/lib/utils.js +++ b/lib/utils.js @@ -29,7 +29,9 @@ exports.merge = function (target, source, options) { if (Array.isArray(target)) { target.push(source); } else if (typeof target === 'object') { - target[source] = true; + if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) { + target[source] = true; + } } else { return [target, source]; } diff --git a/test/parse.js b/test/parse.js index 1ea6dfca..65f6f287 100755 --- a/test/parse.js +++ b/test/parse.js @@ -142,8 +142,6 @@ test('parse()', function (t) { st.end(); }); - t.deepEqual(qs.parse('a[b]=c&a=d'), { a: { b: 'c', d: true } }, 'can add keys to objects'); - t.test('correctly prunes undefined values when converting an array to an object', function (st) { st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { '2': 'b', '99999999': 'c' } }); st.end(); @@ -404,7 +402,45 @@ test('parse()', function (t) { st.end(); }); - t.test('can return plain objects', function (st) { + t.test('params starting with a starting bracket', function (st) { + st.deepEqual(qs.parse('[=toString'), {}); + st.end(); + }); + + t.test('params starting with a starting bracket', function (st) { + st.deepEqual(qs.parse('[=toString'), {}); + st.end(); + }); + + t.test('add keys to objects', function (st) { + st.deepEqual( + qs.parse('a[b]=c&a=d'), + { a: { b: 'c', d: true } }, + 'can add keys to objects' + ); + + st.deepEqual( + qs.parse('a[b]=c&a=toString'), + { a: { b: 'c' } }, + 'can not overwrite prototype' + ); + + st.deepEqual( + qs.parse('a[b]=c&a=toString', { allowPrototypes: true }), + { a: { b: 'c', toString: true } }, + 'can overwrite prototype with allowPrototypes true' + ); + + st.deepEqual( + qs.parse('a[b]=c&a=toString', { plainObjects: true }), + { a: { b: 'c', toString: true } }, + 'can overwrite prototype with plainObjects true' + ); + + st.end(); + }); + + t.test('can return null objects', { skip: !Object.create }, function (st) { var expected = Object.create(null); expected.a = Object.create(null); expected.a.b = 'c';