Skip to content

Commit c709f6e

Browse files
dead-horseljharb
authored andcommitted
[Fix] support keys starting with brackets.
Relates to #200.
1 parent 65270af commit c709f6e

3 files changed

Lines changed: 18 additions & 14 deletions

File tree

lib/parse.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ var internals = {
1313
allowDots: false
1414
};
1515

16+
var has = Object.prototype.hasOwnProperty;
17+
1618
internals.parseValues = function (str, options) {
1719
var obj = {};
1820
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
@@ -31,7 +33,7 @@ internals.parseValues = function (str, options) {
3133
var key = Utils.decode(part.slice(0, pos));
3234
var val = Utils.decode(part.slice(pos + 1));
3335

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

8587
// The regex chunks
8688

87-
var parent = /^([^[]*)/;
89+
var brackets = /(\[[^[\]]*])/;
8890
var child = /(\[[^[\]]*])/g;
8991

9092
// Get the parent
9193

92-
var segment = parent.exec(key);
94+
var segment = brackets.exec(key);
95+
var parent = segment ? key.slice(0, segment.index) : key;
9396

9497
// Stash the parent if it exists
9598

9699
var keys = [];
97-
if (segment[1]) {
100+
if (parent) {
98101
// If we aren't using plain objects, optionally prefix keys
99102
// that would overwrite object prototype properties
100-
if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
103+
if (!options.plainObjects && has.call(Object.prototype, parent)) {
101104
if (!options.allowPrototypes) {
102105
return;
103106
}
104107
}
105108

106-
keys.push(segment[1]);
109+
keys.push(parent);
107110
}
108111

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

111114
var i = 0;
112115
while ((segment = child.exec(key)) !== null && i < options.depth) {
113116
i += 1;
114-
if (!options.plainObjects && Object.prototype.hasOwnProperty.call(Object.prototype, segment[1].slice(1, -1))) {
117+
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
115118
if (!options.allowPrototypes) {
116119
return;
117120
}

lib/utils.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ var hexTable = (function () {
99
return array;
1010
}());
1111

12+
var has = Object.prototype.hasOwnProperty;
13+
1214
exports.arrayToObject = function (source, options) {
1315
var obj = options.plainObjects ? Object.create(null) : {};
1416
for (var i = 0; i < source.length; ++i) {
@@ -51,7 +53,7 @@ exports.merge = function (target, source, options) {
5153
return Object.keys(source).reduce(function (acc, key) {
5254
var value = source[key];
5355

54-
if (Object.prototype.hasOwnProperty.call(acc, key)) {
56+
if (has.call(acc, key)) {
5557
acc[key] = exports.merge(acc[key], value, options);
5658
} else {
5759
acc[key] = value;

test/parse.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -399,16 +399,15 @@ test('parse()', function (t) {
399399

400400
t.test('params starting with a closing bracket', function (st) {
401401
st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
402+
st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' });
403+
st.deepEqual(qs.parse(']hello]=toString'), { ']hello]': 'toString' });
402404
st.end();
403405
});
404406

405407
t.test('params starting with a starting bracket', function (st) {
406-
st.deepEqual(qs.parse('[=toString'), {});
407-
st.end();
408-
});
409-
410-
t.test('params starting with a starting bracket', function (st) {
411-
st.deepEqual(qs.parse('[=toString'), {});
408+
st.deepEqual(qs.parse('[=toString'), { '[': 'toString' });
409+
st.deepEqual(qs.parse('[[=toString'), { '[[': 'toString' });
410+
st.deepEqual(qs.parse('[hello[=toString'), { '[hello[': 'toString' });
412411
st.end();
413412
});
414413

0 commit comments

Comments
 (0)