Skip to content

Commit

Permalink
[Fix] ensure that allowPrototypes: false does not ever shadow Objec…
Browse files Browse the repository at this point in the history
…t.prototype properties.
  • Loading branch information
ljharb committed Feb 14, 2017
1 parent 47dfbd6 commit ca844c5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
10 changes: 5 additions & 5 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internals.parseObject = function (chain, val, options) {
obj = obj.concat(internals.parseObject(chain, val, options));
} else {
obj = options.plainObjects ? Object.create(null) : {};
var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
var index = parseInt(cleanRoot, 10);
if (
!isNaN(index) &&
Expand Down Expand Up @@ -84,8 +84,8 @@ internals.parseKeys = function (givenKey, val, options) {

// The regex chunks

var parent = /^([^\[\]]*)/;
var child = /(\[[^\[\]]*\])/g;
var parent = /^([^[]*)/;
var child = /(\[[^[\]]*])/g;

// Get the parent

Expand All @@ -111,9 +111,9 @@ internals.parseKeys = function (givenKey, val, options) {
var i = 0;
while ((segment = child.exec(key)) !== null && i < options.depth) {
i += 1;
if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
if (!options.plainObjects && Object.prototype.hasOwnProperty.call(Object.prototype, segment[1].slice(1, -1))) {
if (!options.allowPrototypes) {
continue;
return;
}
}
keys.push(segment[1]);
Expand Down
36 changes: 32 additions & 4 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,11 @@ test('parse()', function (t) {
st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
st.deepEqual(qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb'), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c'), { a: { '0': 'b', t: 'u', c: true } });
st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y'), { a: { '0': 'b', '1': 'c', x: 'y' } });

st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: false }), { a: { 0: 'b', t: 'u' } });
st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: true }), { a: { 0: 'b', t: 'u', hasOwnProperty: 'c' } });
st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: false }), { a: { 0: 'b', x: 'y' } });
st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: true }), { a: { 0: 'b', hasOwnProperty: 'c', x: 'y' } });
st.end();
});

Expand Down Expand Up @@ -370,9 +373,34 @@ test('parse()', function (t) {
st.end();
});

t.test('does not allow overwriting prototype properties', function (st) {
st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: false }), {});
st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: false }), {});

st.deepEqual(
qs.parse('toString', { allowPrototypes: false }),
{},
'bare "toString" results in {}'
);

st.end();
});

t.test('can allow overwriting prototype properties', function (st) {
st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } }, { prototype: false });
st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' }, { prototype: false });
st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } });
st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' });

st.deepEqual(
qs.parse('toString', { allowPrototypes: true }),
{ toString: '' },
'bare "toString" results in { toString: "" }'
);

st.end();
});

t.test('params starting with a closing bracket', function (st) {
st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
st.end();
});

Expand Down

0 comments on commit ca844c5

Please sign in to comment.