Skip to content

Commit

Permalink
use plain objects, closes #74 closes #80
Browse files Browse the repository at this point in the history
  • Loading branch information
nlf committed May 22, 2015
1 parent 05a5855 commit 211ba0f
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 126 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var str = Qs.stringify(obj); // 'a=c'
Qs.parse(string, [options]);
```

**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`.
**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`, or prefixing the sub-key with a dot `.`.
For example, the string `'foo[bar]=baz'` converts to:

```javascript
Expand All @@ -34,6 +34,13 @@ For example, the string `'foo[bar]=baz'` converts to:
}
```

The parsed value is returned as a plain object, created via `Object.create(null)` and as such you should be aware that prototype methods do not exist on it and a user may set those names to whatever value they like:

```javascript
Qs.parse('a.hasOwnProperty=b');
// { a: { hasOwnProperty: 'b' } }
```

URI encoded strings work too:

```javascript
Expand Down
17 changes: 5 additions & 12 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ internals.parseObject = function (chain, val, options) {

var root = chain.shift();

var obj = {};
var obj;
if (root === '[]') {
obj = [];
obj = obj.concat(internals.parseObject(chain, val, options));
}
else {
obj = Object.create(null);
var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
var index = parseInt(cleanRoot, 10);
var indexString = '' + index;
Expand Down Expand Up @@ -101,12 +102,6 @@ internals.parseKeys = function (key, val, options) {

var segment = parent.exec(key);

// Don't allow them to overwrite object prototype properties

if (Object.prototype.hasOwnProperty(segment[1])) {
return;
}

// Stash the parent if it exists

var keys = [];
Expand All @@ -120,9 +115,7 @@ internals.parseKeys = function (key, val, options) {
while ((segment = child.exec(key)) !== null && i < options.depth) {

++i;
if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
keys.push(segment[1]);
}
keys.push(segment[1]);
}

// If there's a remainder, just add whatever is left
Expand All @@ -141,7 +134,7 @@ module.exports = function (str, options) {
str === null ||
typeof str === 'undefined') {

return {};
return Object.create(null);
}

options = options || {};
Expand All @@ -153,7 +146,7 @@ module.exports = function (str, options) {


var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
var obj = {};
var obj = Object.create(null);

// Iterate over the keys and setup the new object

Expand Down
2 changes: 1 addition & 1 deletion lib/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
}
else if (obj === null) {
if (strictNullHandling) {
return encodeURIComponent(prefix);
return Utils.fixedEncodeURIComponent(prefix);
}

obj = '';
Expand Down
2 changes: 1 addition & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var internals = {};

exports.arrayToObject = function (source) {

var obj = {};
var obj = Object.create(null);
for (var i = 0, il = source.length; i < il; ++i) {
if (typeof source[i] !== 'undefined') {

Expand Down
Loading

0 comments on commit 211ba0f

Please sign in to comment.