qs 6.9.6 → 6.10.0
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/.eslintrc +1 -1
- package/CHANGELOG.md +10 -0
- package/README.md +8 -1
- package/dist/qs.js +1076 -5
- package/lib/parse.js +6 -0
- package/lib/stringify.js +14 -3
- package/package.json +12 -9
- package/test/parse.js +9 -0
- package/test/stringify.js +34 -1
package/lib/parse.js
CHANGED
|
@@ -8,6 +8,7 @@ var isArray = Array.isArray;
|
|
|
8
8
|
var defaults = {
|
|
9
9
|
allowDots: false,
|
|
10
10
|
allowPrototypes: false,
|
|
11
|
+
allowSparse: false,
|
|
11
12
|
arrayLimit: 20,
|
|
12
13
|
charset: 'utf-8',
|
|
13
14
|
charsetSentinel: false,
|
|
@@ -217,6 +218,7 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
|
|
|
217
218
|
return {
|
|
218
219
|
allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
|
|
219
220
|
allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
|
|
221
|
+
allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
|
|
220
222
|
arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
|
|
221
223
|
charset: charset,
|
|
222
224
|
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
|
@@ -253,5 +255,9 @@ module.exports = function (str, opts) {
|
|
|
253
255
|
obj = utils.merge(obj, newObj, options);
|
|
254
256
|
}
|
|
255
257
|
|
|
258
|
+
if (options.allowSparse === true) {
|
|
259
|
+
return obj;
|
|
260
|
+
}
|
|
261
|
+
|
|
256
262
|
return utils.compact(obj);
|
|
257
263
|
};
|
package/lib/stringify.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var getSideChannel = require('side-channel');
|
|
3
4
|
var utils = require('./utils');
|
|
4
5
|
var formats = require('./formats');
|
|
5
6
|
var has = Object.prototype.hasOwnProperty;
|
|
@@ -68,9 +69,15 @@ var stringify = function stringify(
|
|
|
68
69
|
format,
|
|
69
70
|
formatter,
|
|
70
71
|
encodeValuesOnly,
|
|
71
|
-
charset
|
|
72
|
+
charset,
|
|
73
|
+
sideChannel
|
|
72
74
|
) {
|
|
73
75
|
var obj = object;
|
|
76
|
+
|
|
77
|
+
if (sideChannel.has(object)) {
|
|
78
|
+
throw new RangeError('Cyclic object value');
|
|
79
|
+
}
|
|
80
|
+
|
|
74
81
|
if (typeof filter === 'function') {
|
|
75
82
|
obj = filter(prefix, obj);
|
|
76
83
|
} else if (obj instanceof Date) {
|
|
@@ -129,6 +136,7 @@ var stringify = function stringify(
|
|
|
129
136
|
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
|
|
130
137
|
: prefix + (allowDots ? '.' + key : '[' + key + ']');
|
|
131
138
|
|
|
139
|
+
sideChannel.set(object, true);
|
|
132
140
|
pushToArray(values, stringify(
|
|
133
141
|
value,
|
|
134
142
|
keyPrefix,
|
|
@@ -143,7 +151,8 @@ var stringify = function stringify(
|
|
|
143
151
|
format,
|
|
144
152
|
formatter,
|
|
145
153
|
encodeValuesOnly,
|
|
146
|
-
charset
|
|
154
|
+
charset,
|
|
155
|
+
sideChannel
|
|
147
156
|
));
|
|
148
157
|
}
|
|
149
158
|
|
|
@@ -237,6 +246,7 @@ module.exports = function (object, opts) {
|
|
|
237
246
|
objKeys.sort(options.sort);
|
|
238
247
|
}
|
|
239
248
|
|
|
249
|
+
var sideChannel = getSideChannel();
|
|
240
250
|
for (var i = 0; i < objKeys.length; ++i) {
|
|
241
251
|
var key = objKeys[i];
|
|
242
252
|
|
|
@@ -257,7 +267,8 @@ module.exports = function (object, opts) {
|
|
|
257
267
|
options.format,
|
|
258
268
|
options.formatter,
|
|
259
269
|
options.encodeValuesOnly,
|
|
260
|
-
options.charset
|
|
270
|
+
options.charset,
|
|
271
|
+
sideChannel
|
|
261
272
|
));
|
|
262
273
|
}
|
|
263
274
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "qs",
|
|
3
3
|
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
|
4
4
|
"homepage": "https://github.com/ljharb/qs",
|
|
5
|
-
"version": "6.
|
|
5
|
+
"version": "6.10.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -29,33 +29,36 @@
|
|
|
29
29
|
"engines": {
|
|
30
30
|
"node": ">=0.6"
|
|
31
31
|
},
|
|
32
|
-
"dependencies": {
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"side-channel": "^1.0.4"
|
|
34
|
+
},
|
|
33
35
|
"devDependencies": {
|
|
34
|
-
"@ljharb/eslint-config": "^17.
|
|
35
|
-
"aud": "^1.1.
|
|
36
|
+
"@ljharb/eslint-config": "^17.5.1",
|
|
37
|
+
"aud": "^1.1.4",
|
|
36
38
|
"browserify": "^16.5.2",
|
|
37
39
|
"eclint": "^2.8.1",
|
|
38
|
-
"eslint": "^7.
|
|
40
|
+
"eslint": "^7.22.0",
|
|
39
41
|
"evalmd": "^0.0.19",
|
|
40
42
|
"for-each": "^0.3.3",
|
|
41
|
-
"has-symbols": "^1.0.
|
|
43
|
+
"has-symbols": "^1.0.2",
|
|
42
44
|
"iconv-lite": "^0.5.1",
|
|
45
|
+
"in-publish": "^2.0.1",
|
|
43
46
|
"mkdirp": "^0.5.5",
|
|
44
47
|
"nyc": "^10.3.2",
|
|
45
48
|
"object-inspect": "^1.9.0",
|
|
46
49
|
"qs-iconv": "^1.0.4",
|
|
47
50
|
"safe-publish-latest": "^1.1.4",
|
|
48
51
|
"safer-buffer": "^2.1.2",
|
|
49
|
-
"tape": "^5.
|
|
52
|
+
"tape": "^5.2.2"
|
|
50
53
|
},
|
|
51
54
|
"scripts": {
|
|
52
|
-
"prepublish": "safe-publish-latest && npm run dist",
|
|
55
|
+
"prepublish": "safe-publish-latest && (not-in-publish || npm run dist)",
|
|
53
56
|
"pretest": "npm run --silent readme && npm run --silent lint",
|
|
54
57
|
"test": "npm run tests-only",
|
|
55
58
|
"tests-only": "nyc tape 'test/**/*.js'",
|
|
56
59
|
"posttest": "aud --production",
|
|
57
60
|
"readme": "evalmd README.md",
|
|
58
|
-
"postlint": "eclint check * lib/* test/*",
|
|
61
|
+
"postlint": "eclint check * lib/* test/* !dist/*",
|
|
59
62
|
"lint": "eslint lib/*.js test/*.js",
|
|
60
63
|
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
61
64
|
},
|
package/test/parse.js
CHANGED
|
@@ -269,6 +269,15 @@ test('parse()', function (t) {
|
|
|
269
269
|
st.end();
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
+
t.test('parses sparse arrays', function (st) {
|
|
273
|
+
/* eslint no-sparse-arrays: 0 */
|
|
274
|
+
st.deepEqual(qs.parse('a[4]=1&a[1]=2', { allowSparse: true }), { a: [, '2', , , '1'] });
|
|
275
|
+
st.deepEqual(qs.parse('a[1][b][2][c]=1', { allowSparse: true }), { a: [, { b: [, , { c: '1' }] }] });
|
|
276
|
+
st.deepEqual(qs.parse('a[1][2][3][c]=1', { allowSparse: true }), { a: [, [, , [, , , { c: '1' }]]] });
|
|
277
|
+
st.deepEqual(qs.parse('a[1][2][3][c][1]=1', { allowSparse: true }), { a: [, [, , [, , , { c: [, '1'] }]]] });
|
|
278
|
+
st.end();
|
|
279
|
+
});
|
|
280
|
+
|
|
272
281
|
t.test('parses semi-parsed strings', function (st) {
|
|
273
282
|
st.deepEqual(qs.parse({ 'a[b]': 'c' }), { a: { b: 'c' } });
|
|
274
283
|
st.deepEqual(qs.parse({ 'a[b]': 'c', 'a[d]': 'e' }), { a: { b: 'c', d: 'e' } });
|
package/test/stringify.js
CHANGED
|
@@ -433,7 +433,7 @@ test('stringify()', function (t) {
|
|
|
433
433
|
st.end();
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
-
t.test('
|
|
436
|
+
t.test('does not blow up when Buffer global is missing', function (st) {
|
|
437
437
|
var tempBuffer = global.Buffer;
|
|
438
438
|
delete global.Buffer;
|
|
439
439
|
var result = qs.stringify({ a: 'b', c: 'd' });
|
|
@@ -442,6 +442,29 @@ test('stringify()', function (t) {
|
|
|
442
442
|
st.end();
|
|
443
443
|
});
|
|
444
444
|
|
|
445
|
+
t.test('does not crash when parsing circular references', function (st) {
|
|
446
|
+
var a = {};
|
|
447
|
+
a.b = a;
|
|
448
|
+
|
|
449
|
+
st['throws'](
|
|
450
|
+
function () { qs.stringify({ 'foo[bar]': 'baz', 'foo[baz]': a }); },
|
|
451
|
+
RangeError,
|
|
452
|
+
'cyclic values throw'
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
var circular = {
|
|
456
|
+
a: 'value'
|
|
457
|
+
};
|
|
458
|
+
circular.a = circular;
|
|
459
|
+
st['throws'](
|
|
460
|
+
function () { qs.stringify(circular); },
|
|
461
|
+
RangeError,
|
|
462
|
+
'cyclic values throw'
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
st.end();
|
|
466
|
+
});
|
|
467
|
+
|
|
445
468
|
t.test('selects properties when filter=array', function (st) {
|
|
446
469
|
st.equal(qs.stringify({ a: 'b' }, { filter: ['a'] }), 'a=b');
|
|
447
470
|
st.equal(qs.stringify({ a: 1 }, { filter: [] }), '');
|
|
@@ -789,5 +812,15 @@ test('stringify()', function (t) {
|
|
|
789
812
|
st.end();
|
|
790
813
|
});
|
|
791
814
|
|
|
815
|
+
t.test('stringifies sparse arrays', function (st) {
|
|
816
|
+
/* eslint no-sparse-arrays: 0 */
|
|
817
|
+
st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true }), 'a[1]=2&a[4]=1');
|
|
818
|
+
st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true }), 'a[1][b][2][c]=1');
|
|
819
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true }), 'a[1][2][3][c]=1');
|
|
820
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true }), 'a[1][2][3][c][1]=1');
|
|
821
|
+
|
|
822
|
+
st.end();
|
|
823
|
+
});
|
|
824
|
+
|
|
792
825
|
t.end();
|
|
793
826
|
});
|