Skip to content

Commit

Permalink
[Fix] support keys starting with brackets.
Browse files Browse the repository at this point in the history
Relates to #200.
  • Loading branch information
dead-horse authored and ljharb committed Mar 6, 2017
1 parent 8905f88 commit efd5f33
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 13 deletions.
17 changes: 10 additions & 7 deletions lib/parse.js
Expand Up @@ -13,6 +13,8 @@ var internals = {
allowDots: false
};

var has = Object.prototype.hasOwnProperty;

internals.parseValues = function (str, options) {
var obj = {};
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
Expand All @@ -31,7 +33,7 @@ internals.parseValues = function (str, options) {
var key = Utils.decode(part.slice(0, pos));
var val = Utils.decode(part.slice(pos + 1));

if (Object.prototype.hasOwnProperty.call(obj, key)) {
if (has.call(obj, key)) {
obj[key] = [].concat(obj[key]).concat(val);
} else {
obj[key] = val;
Expand Down Expand Up @@ -84,34 +86,35 @@ internals.parseKeys = function (givenKey, val, options) {

// The regex chunks

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

// Get the parent

var segment = parent.exec(key);
var segment = brackets.exec(key);
var parent = segment ? key.slice(0, segment.index) : key;

// Stash the parent if it exists

var keys = [];
if (segment[1]) {
if (parent) {
// If we aren't using plain objects, optionally prefix keys
// that would overwrite object prototype properties
if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
if (!options.plainObjects && has.call(Object.prototype, parent)) {
if (!options.allowPrototypes) {
return;
}
}

keys.push(segment[1]);
keys.push(parent);
}

// Loop through children appending to the array until we hit depth

var i = 0;
while ((segment = child.exec(key)) !== null && i < options.depth) {
i += 1;
if (!options.plainObjects && Object.prototype.hasOwnProperty.call(Object.prototype, segment[1].slice(1, -1))) {
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
if (!options.allowPrototypes) {
return;
}
Expand Down
11 changes: 5 additions & 6 deletions test/parse.js
Expand Up @@ -399,16 +399,15 @@ test('parse()', function (t) {

t.test('params starting with a closing bracket', function (st) {
st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' });
st.deepEqual(qs.parse(']hello]=toString'), { ']hello]': 'toString' });
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.deepEqual(qs.parse('[=toString'), { '[': 'toString' });
st.deepEqual(qs.parse('[[=toString'), { '[[': 'toString' });
st.deepEqual(qs.parse('[hello[=toString'), { '[hello[': 'toString' });
st.end();
});

Expand Down

0 comments on commit efd5f33

Please sign in to comment.