Skip to content

Commit

Permalink
fix: follow allowPrototypes during merge
Browse files Browse the repository at this point in the history
  • Loading branch information
dead-horse committed Mar 2, 2017
1 parent 556ee0a commit b22352e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
19 changes: 13 additions & 6 deletions dist/qs.js
Expand Up @@ -223,6 +223,7 @@ var defaults = {
delimiter: '&',
encode: true,
encoder: utils.encode,
encodeValuesOnly: false,
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
return toISO.call(date);
},
Expand All @@ -241,7 +242,8 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
sort,
allowDots,
serializeDate,
formatter
formatter,
encodeValuesOnly
) {
var obj = object;
if (typeof filter === 'function') {
Expand All @@ -250,15 +252,16 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
obj = serializeDate(obj);
} else if (obj === null) {
if (strictNullHandling) {
return encoder ? encoder(prefix) : prefix;
return encoder && !encodeValuesOnly ? encoder(prefix) : prefix;
}

obj = '';
}

if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
if (encoder) {
return [formatter(encoder(prefix)) + '=' + formatter(encoder(obj))];
var keyValue = encodeValuesOnly ? prefix : encoder(prefix);
return [formatter(keyValue) + '=' + formatter(encoder(obj))];
}
return [formatter(prefix) + '=' + formatter(String(obj))];
}
Expand Down Expand Up @@ -296,7 +299,8 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
sort,
allowDots,
serializeDate,
formatter
formatter,
encodeValuesOnly
));
} else {
values = values.concat(stringify(
Expand All @@ -310,7 +314,8 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
sort,
allowDots,
serializeDate,
formatter
formatter,
encodeValuesOnly
));
}
}
Expand All @@ -334,6 +339,7 @@ module.exports = function (object, opts) {
var sort = typeof options.sort === 'function' ? options.sort : null;
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
if (typeof options.format === 'undefined') {
options.format = formats.default;
} else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
Expand Down Expand Up @@ -394,7 +400,8 @@ module.exports = function (object, opts) {
sort,
allowDots,
serializeDate,
formatter
formatter,
encodeValuesOnly
));
}

Expand Down
4 changes: 3 additions & 1 deletion lib/utils.js
Expand Up @@ -31,7 +31,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];
}
Expand Down
40 changes: 38 additions & 2 deletions test/parse.js
Expand Up @@ -152,8 +152,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();
Expand Down Expand Up @@ -444,6 +442,44 @@ test('parse()', function (t) {
st.end();
});

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);
Expand Down

0 comments on commit b22352e

Please sign in to comment.