qs 2.2.0 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,47 @@
1
+
2
+ ## [**2.2.3**](https://github.com/hapijs/qs/issues?milestone=12&state=closed)
3
+ - [**#37**](https://github.com/hapijs/qs/issues/37) parser discards first empty value in array
4
+ - [**#36**](https://github.com/hapijs/qs/issues/36) Update to lab 4.x
5
+
6
+ ## [**2.2.2**](https://github.com/hapijs/qs/issues?milestone=11&state=closed)
7
+ - [**#33**](https://github.com/hapijs/qs/issues/33) Error when plain object in a value
8
+ - [**#34**](https://github.com/hapijs/qs/issues/34) use Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty
9
+ - [**#24**](https://github.com/hapijs/qs/issues/24) Changelog? Semver?
10
+
11
+ ## [**2.2.1**](https://github.com/hapijs/qs/issues?milestone=10&state=closed)
12
+ - [**#32**](https://github.com/hapijs/qs/issues/32) account for circular references properly, closes #31
13
+ - [**#31**](https://github.com/hapijs/qs/issues/31) qs.parse stackoverflow on circular objects
14
+
15
+ ## [**2.2.0**](https://github.com/hapijs/qs/issues?milestone=9&state=closed)
16
+ - [**#26**](https://github.com/hapijs/qs/issues/26) Don't use Buffer global if it's not present
17
+ - [**#30**](https://github.com/hapijs/qs/issues/30) Bug when merging non-object values into arrays
18
+ - [**#29**](https://github.com/hapijs/qs/issues/29) Don't call Utils.clone at the top of Utils.merge
19
+ - [**#23**](https://github.com/hapijs/qs/issues/23) Ability to not limit parameters?
20
+
21
+ ## [**2.1.0**](https://github.com/hapijs/qs/issues?milestone=8&state=closed)
22
+ - [**#22**](https://github.com/hapijs/qs/issues/22) Enable using a RegExp as delimiter
23
+
24
+ ## [**2.0.0**](https://github.com/hapijs/qs/issues?milestone=7&state=closed)
25
+ - [**#18**](https://github.com/hapijs/qs/issues/18) Why is there arrayLimit?
26
+ - [**#20**](https://github.com/hapijs/qs/issues/20) Configurable parametersLimit
27
+ - [**#21**](https://github.com/hapijs/qs/issues/21) make all limits optional, for #18, for #20
28
+
29
+ ## [**1.2.2**](https://github.com/hapijs/qs/issues?milestone=6&state=closed)
30
+ - [**#19**](https://github.com/hapijs/qs/issues/19) Don't overwrite null values
31
+
32
+ ## [**1.2.1**](https://github.com/hapijs/qs/issues?milestone=5&state=closed)
33
+ - [**#16**](https://github.com/hapijs/qs/issues/16) ignore non-string delimiters
34
+ - [**#15**](https://github.com/hapijs/qs/issues/15) Close code block
35
+
36
+ ## [**1.2.0**](https://github.com/hapijs/qs/issues?milestone=4&state=closed)
37
+ - [**#12**](https://github.com/hapijs/qs/issues/12) Add optional delim argument
38
+ - [**#13**](https://github.com/hapijs/qs/issues/13) fix #11: flattened keys in array are now correctly parsed
39
+
40
+ ## [**1.1.0**](https://github.com/hapijs/qs/issues?milestone=3&state=closed)
41
+ - [**#7**](https://github.com/hapijs/qs/issues/7) Empty values of a POST array disappear after being submitted
42
+ - [**#9**](https://github.com/hapijs/qs/issues/9) Should not omit equals signs (=) when value is null
43
+ - [**#6**](https://github.com/hapijs/qs/issues/6) Minor grammar fix in README
44
+
45
+ ## [**1.0.2**](https://github.com/hapijs/qs/issues?milestone=2&state=closed)
46
+ - [**#5**](https://github.com/hapijs/qs/issues/5) array holes incorrectly copied into object on large index
47
+
package/lib/parse.js CHANGED
@@ -29,7 +29,7 @@ internals.parseValues = function (str, options) {
29
29
  var key = Utils.decode(part.slice(0, pos));
30
30
  var val = Utils.decode(part.slice(pos + 1));
31
31
 
32
- if (!obj[key]) {
32
+ if (!obj.hasOwnProperty(key)) {
33
33
  obj[key] = val;
34
34
  }
35
35
  else {
@@ -58,8 +58,10 @@ internals.parseObject = function (chain, val, options) {
58
58
  else {
59
59
  var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
60
60
  var index = parseInt(cleanRoot, 10);
61
+ var indexString = '' + index;
61
62
  if (!isNaN(index) &&
62
63
  root !== cleanRoot &&
64
+ indexString === cleanRoot &&
63
65
  index <= options.arrayLimit) {
64
66
 
65
67
  obj = [];
@@ -138,16 +140,16 @@ module.exports = function (str, options) {
138
140
  options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
139
141
  options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
140
142
 
141
- var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : Utils.clone(str);
143
+ var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
142
144
  var obj = {};
143
145
 
144
146
  // Iterate over the keys and setup the new object
145
- //
146
- for (var key in tempObj) {
147
- if (tempObj.hasOwnProperty(key)) {
148
- var newObj = internals.parseKeys(key, tempObj[key], options);
149
- obj = Utils.merge(obj, newObj);
150
- }
147
+
148
+ var keys = Object.keys(tempObj);
149
+ for (var i = 0, il = keys.length; i < il; ++i) {
150
+ var key = keys[i];
151
+ var newObj = internals.parseKeys(key, tempObj[key], options);
152
+ obj = Utils.merge(obj, newObj);
151
153
  }
152
154
 
153
155
  return Utils.compact(obj);
package/lib/utils.js CHANGED
@@ -20,29 +20,6 @@ exports.arrayToObject = function (source) {
20
20
  };
21
21
 
22
22
 
23
- exports.clone = function (source) {
24
-
25
- if (typeof source !== 'object' ||
26
- source === null) {
27
-
28
- return source;
29
- }
30
-
31
- if (exports.isBuffer(source)) {
32
- return source.toString();
33
- }
34
-
35
- var obj = Array.isArray(source) ? [] : {};
36
- for (var i in source) {
37
- if (source.hasOwnProperty(i)) {
38
- obj[i] = exports.clone(source[i]);
39
- }
40
- }
41
-
42
- return obj;
43
- };
44
-
45
-
46
23
  exports.merge = function (target, source) {
47
24
 
48
25
  if (!source) {
@@ -83,7 +60,7 @@ exports.merge = function (target, source) {
83
60
  typeof value === 'object') {
84
61
 
85
62
  if (!target[key]) {
86
- target[key] = exports.clone(value);
63
+ target[key] = value;
87
64
  }
88
65
  else {
89
66
  target[key] = exports.merge(target[key], value);
@@ -108,32 +85,41 @@ exports.decode = function (str) {
108
85
  };
109
86
 
110
87
 
111
- exports.compact = function (obj) {
88
+ exports.compact = function (obj, refs) {
89
+
90
+ if (typeof obj !== 'object' ||
91
+ obj === null) {
112
92
 
113
- if (typeof obj !== 'object' || obj === null) {
114
93
  return obj;
115
94
  }
116
95
 
117
- var compacted = {};
96
+ refs = refs || [];
97
+ var lookup = refs.indexOf(obj);
98
+ if (lookup !== -1) {
99
+ return refs[lookup];
100
+ }
118
101
 
119
- for (var key in obj) {
120
- if (obj.hasOwnProperty(key)) {
121
- if (Array.isArray(obj[key])) {
122
- compacted[key] = [];
102
+ refs.push(obj);
123
103
 
124
- for (var i = 0, l = obj[key].length; i < l; i++) {
125
- if (typeof obj[key][i] !== 'undefined') {
126
- compacted[key].push(obj[key][i]);
127
- }
128
- }
129
- }
130
- else {
131
- compacted[key] = exports.compact(obj[key]);
104
+ if (Array.isArray(obj)) {
105
+ var compacted = [];
106
+
107
+ for (var i = 0, l = obj.length; i < l; ++i) {
108
+ if (typeof obj[i] !== 'undefined') {
109
+ compacted.push(obj[i]);
132
110
  }
133
111
  }
112
+
113
+ return compacted;
134
114
  }
135
115
 
136
- return compacted;
116
+ var keys = Object.keys(obj);
117
+ for (var i = 0, il = keys.length; i < il; ++i) {
118
+ var key = keys[i];
119
+ obj[key] = exports.compact(obj[key], refs);
120
+ }
121
+
122
+ return obj;
137
123
  };
138
124
 
139
125
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "qs",
3
- "version": "2.2.0",
3
+ "version": "2.2.4",
4
4
  "description": "A querystring parser that supports nesting and arrays, with a depth limit",
5
5
  "homepage": "https://github.com/hapijs/qs",
6
6
  "main": "index.js",
7
7
  "dependencies": {},
8
8
  "devDependencies": {
9
- "lab": "3.x.x"
9
+ "lab": "4.x.x"
10
10
  },
11
11
  "scripts": {
12
12
  "test": "make test-cov"
package/test/parse.js CHANGED
@@ -11,11 +11,12 @@ var internals = {};
11
11
 
12
12
  // Test shortcuts
13
13
 
14
+ var lab = exports.lab = Lab.script();
14
15
  var expect = Lab.expect;
15
- var before = Lab.before;
16
- var after = Lab.after;
17
- var describe = Lab.experiment;
18
- var it = Lab.test;
16
+ var before = lab.before;
17
+ var after = lab.after;
18
+ var describe = lab.experiment;
19
+ var it = lab.test;
19
20
 
20
21
 
21
22
  describe('#parse', function () {
@@ -103,6 +104,12 @@ describe('#parse', function () {
103
104
  done();
104
105
  });
105
106
 
107
+ it('supports keys that begin with a number', function (done) {
108
+
109
+ expect(Qs.parse('a[12b]=c')).to.deep.equal({ a: { '12b': 'c' } });
110
+ done();
111
+ });
112
+
106
113
  it('supports encoded = signs', function (done) {
107
114
 
108
115
  expect(Qs.parse('he%3Dllo=th%3Dere')).to.deep.equal({ 'he=llo': 'th=ere' });
@@ -189,6 +196,7 @@ describe('#parse', function () {
189
196
 
190
197
  expect(Qs.parse('a[]=b&a[]=&a[]=c')).to.deep.equal({ a: ['b', '', 'c'] });
191
198
  expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]=')).to.deep.equal({ a: ['b', '', 'c', ''] });
199
+ expect(Qs.parse('a[]=&a[]=b&a[]=c')).to.deep.equal({ a: ['', 'b', 'c'] });
192
200
  done();
193
201
  });
194
202
 
@@ -205,10 +213,10 @@ describe('#parse', function () {
205
213
  done();
206
214
  });
207
215
 
208
- it('parses buffers to strings', function (done) {
216
+ it('parses buffers correctly', function (done) {
209
217
 
210
218
  var b = new Buffer('test');
211
- expect(Qs.parse({ a: b })).to.deep.equal({ a: b.toString() });
219
+ expect(Qs.parse({ a: b })).to.deep.equal({ a: b });
212
220
  done();
213
221
  });
214
222
 
@@ -337,4 +345,47 @@ describe('#parse', function () {
337
345
  expect(Qs.parse('roomInfoList[0].childrenAges[0]=15&roomInfoList[0].numberOfAdults=2')).to.deep.equal({ roomInfoList: [['15', '2']] });
338
346
  done();
339
347
  });
348
+
349
+ it('does not crash when parsing circular references', function (done) {
350
+
351
+ var a = {};
352
+ a.b = a;
353
+
354
+ var parsed;
355
+
356
+ expect(function () {
357
+
358
+ parsed = Qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
359
+ }).to.not.throw(Error);
360
+
361
+ expect(parsed).to.have.key('foo');
362
+ expect(parsed.foo).to.have.keys('bar', 'baz');
363
+ expect(parsed.foo.bar).to.equal('baz');
364
+ expect(parsed.foo.baz).to.deep.equal(a);
365
+ done();
366
+ });
367
+
368
+ it('parses plain objects correctly', function (done) {
369
+
370
+ var a = Object.create(null);
371
+ a.b = 'c';
372
+
373
+ expect(Qs.parse(a)).to.deep.equal({ b: 'c' });
374
+ expect(Qs.parse({ a: a })).to.deep.equal({ a: { b: 'c' } });
375
+ done();
376
+ });
377
+
378
+ it('parses dates correctly', function (done) {
379
+
380
+ var now = new Date();
381
+ expect(Qs.parse({ a: now })).to.deep.equal({ a: now });
382
+ done();
383
+ });
384
+
385
+ it('parses regular expressions correctly', function (done) {
386
+
387
+ var re = /^test$/;
388
+ expect(Qs.parse({ a: re })).to.deep.equal({ a: re });
389
+ done();
390
+ });
340
391
  });
package/test/stringify.js CHANGED
@@ -11,11 +11,12 @@ var internals = {};
11
11
 
12
12
  // Test shortcuts
13
13
 
14
+ var lab = exports.lab = Lab.script();
14
15
  var expect = Lab.expect;
15
- var before = Lab.before;
16
- var after = Lab.after;
17
- var describe = Lab.experiment;
18
- var it = Lab.test;
16
+ var before = lab.before;
17
+ var after = lab.after;
18
+ var describe = lab.experiment;
19
+ var it = lab.test;
19
20
 
20
21
 
21
22
  describe('#stringify', function () {