qs 6.12.2 → 6.13.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/CHANGELOG.md +10 -2
- package/README.md +12 -1
- package/dist/qs.js +1 -1
- package/lib/parse.js +9 -2
- package/package.json +2 -3
- package/test/parse.js +109 -0
- package/test/stringify.js +12 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
## **6.13.0**
|
|
2
|
+
- [New] `parse`: add `strictDepth` option (#511)
|
|
3
|
+
- [Tests] use `npm audit` instead of `aud`
|
|
4
|
+
|
|
5
|
+
## **6.12.3**
|
|
6
|
+
- [Fix] `parse`: properly account for `strictNullHandling` when `allowEmptyArrays`
|
|
7
|
+
- [meta] fix changelog indentation
|
|
8
|
+
|
|
1
9
|
## **6.12.2**
|
|
2
|
-
|
|
3
|
-
|
|
10
|
+
- [Fix] `parse`: parse encoded square brackets (#506)
|
|
11
|
+
- [readme] add CII best practices badge
|
|
4
12
|
|
|
5
13
|
## **6.12.1**
|
|
6
14
|
- [Fix] `parse`: Disable `decodeDotInKeys` by default to restore previous behavior (#501)
|
package/README.md
CHANGED
|
@@ -115,7 +115,18 @@ var deep = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
|
|
|
115
115
|
assert.deepEqual(deep, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } });
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
You can configure **qs** to throw an error when parsing nested input beyond this depth using the `strictDepth` option (defaulted to false):
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
try {
|
|
122
|
+
qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true });
|
|
123
|
+
} catch (err) {
|
|
124
|
+
assert(err instanceof RangeError);
|
|
125
|
+
assert.strictEqual(err.message, 'Input depth exceeded depth option of 1 and strictDepth is true');
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number. The strictDepth option adds a layer of protection by throwing an error when the limit is exceeded, allowing you to catch and handle such cases.
|
|
119
130
|
|
|
120
131
|
For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option:
|
|
121
132
|
|
package/dist/qs.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"use strict";var stringify=require(4),parse=require(3),formats=require(1);module.exports={formats:formats,parse:parse,stringify:stringify};
|
|
6
6
|
|
|
7
7
|
},{"1":1,"3":3,"4":4}],3:[function(require,module,exports){
|
|
8
|
-
"use strict";var utils=require(5),has=Object.prototype.hasOwnProperty,isArray=Array.isArray,defaults={allowDots:!1,allowEmptyArrays:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decodeDotInKeys:!1,decoder:utils.decode,delimiter:"&",depth:5,duplicates:"combine",ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},interpretNumericEntities=function(e){return e.replace(/&#(\d+);/g,(function(e,t){return String.fromCharCode(parseInt(t,10))}))},parseArrayValue=function(e,t){return e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1?e.split(","):e},isoSentinel="utf8=%26%2310003%3B",charsetSentinel="utf8=%E2%9C%93",parseValues=function parseQueryStringValues(e,t){var r={__proto__:null},a=t.ignoreQueryPrefix?e.replace(/^\?/,""):e;a=a.replace(/%5B/gi,"[").replace(/%5D/gi,"]");var i,o=t.parameterLimit===1/0?void 0:t.parameterLimit,l=a.split(t.delimiter,o),s=-1,n=t.charset;if(t.charsetSentinel)for(i=0;i<l.length;++i)0===l[i].indexOf("utf8=")&&(l[i]===charsetSentinel?n="utf-8":l[i]===isoSentinel&&(n="iso-8859-1"),s=i,i=l.length);for(i=0;i<l.length;++i)if(i!==s){var p,c,d=l[i],u=d.indexOf("]="),
|
|
8
|
+
"use strict";var utils=require(5),has=Object.prototype.hasOwnProperty,isArray=Array.isArray,defaults={allowDots:!1,allowEmptyArrays:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decodeDotInKeys:!1,decoder:utils.decode,delimiter:"&",depth:5,duplicates:"combine",ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictDepth:!1,strictNullHandling:!1},interpretNumericEntities=function(e){return e.replace(/&#(\d+);/g,(function(e,t){return String.fromCharCode(parseInt(t,10))}))},parseArrayValue=function(e,t){return e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1?e.split(","):e},isoSentinel="utf8=%26%2310003%3B",charsetSentinel="utf8=%E2%9C%93",parseValues=function parseQueryStringValues(e,t){var r={__proto__:null},a=t.ignoreQueryPrefix?e.replace(/^\?/,""):e;a=a.replace(/%5B/gi,"[").replace(/%5D/gi,"]");var i,o=t.parameterLimit===1/0?void 0:t.parameterLimit,l=a.split(t.delimiter,o),s=-1,n=t.charset;if(t.charsetSentinel)for(i=0;i<l.length;++i)0===l[i].indexOf("utf8=")&&(l[i]===charsetSentinel?n="utf-8":l[i]===isoSentinel&&(n="iso-8859-1"),s=i,i=l.length);for(i=0;i<l.length;++i)if(i!==s){var p,c,d=l[i],u=d.indexOf("]="),f=-1===u?d.indexOf("="):u+1;-1===f?(p=t.decoder(d,defaults.decoder,n,"key"),c=t.strictNullHandling?null:""):(p=t.decoder(d.slice(0,f),defaults.decoder,n,"key"),c=utils.maybeMap(parseArrayValue(d.slice(f+1),t),(function(e){return t.decoder(e,defaults.decoder,n,"value")}))),c&&t.interpretNumericEntities&&"iso-8859-1"===n&&(c=interpretNumericEntities(c)),d.indexOf("[]=")>-1&&(c=isArray(c)?[c]:c);var y=has.call(r,p);y&&"combine"===t.duplicates?r[p]=utils.combine(r[p],c):y&&"last"!==t.duplicates||(r[p]=c)}return r},parseObject=function(e,t,r,a){for(var i=a?t:parseArrayValue(t,r),o=e.length-1;o>=0;--o){var l,s=e[o];if("[]"===s&&r.parseArrays)l=r.allowEmptyArrays&&(""===i||r.strictNullHandling&&null===i)?[]:[].concat(i);else{l=r.plainObjects?Object.create(null):{};var n="["===s.charAt(0)&&"]"===s.charAt(s.length-1)?s.slice(1,-1):s,p=r.decodeDotInKeys?n.replace(/%2E/g,"."):n,c=parseInt(p,10);r.parseArrays||""!==p?!isNaN(c)&&s!==p&&String(c)===p&&c>=0&&r.parseArrays&&c<=r.arrayLimit?(l=[])[c]=i:"__proto__"!==p&&(l[p]=i):l={0:i}}i=l}return i},parseKeys=function parseQueryStringKeys(e,t,r,a){if(e){var i=r.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,o=/(\[[^[\]]*])/g,l=r.depth>0&&/(\[[^[\]]*])/.exec(i),s=l?i.slice(0,l.index):i,n=[];if(s){if(!r.plainObjects&&has.call(Object.prototype,s)&&!r.allowPrototypes)return;n.push(s)}for(var p=0;r.depth>0&&null!==(l=o.exec(i))&&p<r.depth;){if(p+=1,!r.plainObjects&&has.call(Object.prototype,l[1].slice(1,-1))&&!r.allowPrototypes)return;n.push(l[1])}if(l){if(!0===r.strictDepth)throw new RangeError("Input depth exceeded depth option of "+r.depth+" and strictDepth is true");n.push("["+i.slice(l.index)+"]")}return parseObject(n,t,r,a)}},normalizeParseOptions=function normalizeParseOptions(e){if(!e)return defaults;if(void 0!==e.allowEmptyArrays&&"boolean"!=typeof e.allowEmptyArrays)throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");if(void 0!==e.decodeDotInKeys&&"boolean"!=typeof e.decodeDotInKeys)throw new TypeError("`decodeDotInKeys` option can only be `true` or `false`, when provided");if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=void 0===e.charset?defaults.charset:e.charset,r=void 0===e.duplicates?defaults.duplicates:e.duplicates;if("combine"!==r&&"first"!==r&&"last"!==r)throw new TypeError("The duplicates option must be either combine, first, or last");return{allowDots:void 0===e.allowDots?!0===e.decodeDotInKeys||defaults.allowDots:!!e.allowDots,allowEmptyArrays:"boolean"==typeof e.allowEmptyArrays?!!e.allowEmptyArrays:defaults.allowEmptyArrays,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:defaults.allowPrototypes,allowSparse:"boolean"==typeof e.allowSparse?e.allowSparse:defaults.allowSparse,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:defaults.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:defaults.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:defaults.comma,decodeDotInKeys:"boolean"==typeof e.decodeDotInKeys?e.decodeDotInKeys:defaults.decodeDotInKeys,decoder:"function"==typeof e.decoder?e.decoder:defaults.decoder,delimiter:"string"==typeof e.delimiter||utils.isRegExp(e.delimiter)?e.delimiter:defaults.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:defaults.depth,duplicates:r,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:defaults.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:defaults.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:defaults.plainObjects,strictDepth:"boolean"==typeof e.strictDepth?!!e.strictDepth:defaults.strictDepth,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:defaults.strictNullHandling}};module.exports=function(e,t){var r=normalizeParseOptions(t);if(""===e||null==e)return r.plainObjects?Object.create(null):{};for(var a="string"==typeof e?parseValues(e,r):e,i=r.plainObjects?Object.create(null):{},o=Object.keys(a),l=0;l<o.length;++l){var s=o[l],n=parseKeys(s,a[s],r,"string"==typeof e);i=utils.merge(i,n,r)}return!0===r.allowSparse?i:utils.compact(i)};
|
|
9
9
|
|
|
10
10
|
},{"5":5}],4:[function(require,module,exports){
|
|
11
11
|
"use strict";var getSideChannel=require(29),utils=require(5),formats=require(1),has=Object.prototype.hasOwnProperty,arrayPrefixGenerators={brackets:function brackets(e){return e+"[]"},comma:"comma",indices:function indices(e,r){return e+"["+r+"]"},repeat:function repeat(e){return e}},isArray=Array.isArray,push=Array.prototype.push,pushToArray=function(e,r){push.apply(e,isArray(r)?r:[r])},toISO=Date.prototype.toISOString,defaultFormat=formats.default,defaults={addQueryPrefix:!1,allowDots:!1,allowEmptyArrays:!1,arrayFormat:"indices",charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encodeDotInKeys:!1,encoder:utils.encode,encodeValuesOnly:!1,format:defaultFormat,formatter:formats.formatters[defaultFormat],indices:!1,serializeDate:function serializeDate(e){return toISO.call(e)},skipNulls:!1,strictNullHandling:!1},isNonNullishPrimitive=function isNonNullishPrimitive(e){return"string"==typeof e||"number"==typeof e||"boolean"==typeof e||"symbol"==typeof e||"bigint"==typeof e},sentinel={},stringify=function stringify(e,r,t,o,a,n,i,l,s,f,u,d,y,c,p,m,h,v){for(var w=e,b=v,g=0,A=!1;void 0!==(b=b.get(sentinel))&&!A;){var D=b.get(e);if(g+=1,void 0!==D){if(D===g)throw new RangeError("Cyclic object value");A=!0}void 0===b.get(sentinel)&&(g=0)}if("function"==typeof f?w=f(r,w):w instanceof Date?w=y(w):"comma"===t&&isArray(w)&&(w=utils.maybeMap(w,(function(e){return e instanceof Date?y(e):e}))),null===w){if(n)return s&&!m?s(r,defaults.encoder,h,"key",c):r;w=""}if(isNonNullishPrimitive(w)||utils.isBuffer(w))return s?[p(m?r:s(r,defaults.encoder,h,"key",c))+"="+p(s(w,defaults.encoder,h,"value",c))]:[p(r)+"="+p(String(w))];var E,N=[];if(void 0===w)return N;if("comma"===t&&isArray(w))m&&s&&(w=utils.maybeMap(w,s)),E=[{value:w.length>0?w.join(",")||null:void 0}];else if(isArray(f))E=f;else{var S=Object.keys(w);E=u?S.sort(u):S}var O=l?r.replace(/\./g,"%2E"):r,T=o&&isArray(w)&&1===w.length?O+"[]":O;if(a&&isArray(w)&&0===w.length)return T+"[]";for(var k=0;k<E.length;++k){var I=E[k],P="object"==typeof I&&void 0!==I.value?I.value:w[I];if(!i||null!==P){var x=d&&l?I.replace(/\./g,"%2E"):I,z=isArray(w)?"function"==typeof t?t(T,x):T:T+(d?"."+x:"["+x+"]");v.set(e,g);var K=getSideChannel();K.set(sentinel,v),pushToArray(N,stringify(P,z,t,o,a,n,i,l,"comma"===t&&m&&isArray(w)?null:s,f,u,d,y,c,p,m,h,K))}}return N},normalizeStringifyOptions=function normalizeStringifyOptions(e){if(!e)return defaults;if(void 0!==e.allowEmptyArrays&&"boolean"!=typeof e.allowEmptyArrays)throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");if(void 0!==e.encodeDotInKeys&&"boolean"!=typeof e.encodeDotInKeys)throw new TypeError("`encodeDotInKeys` option can only be `true` or `false`, when provided");if(null!==e.encoder&&void 0!==e.encoder&&"function"!=typeof e.encoder)throw new TypeError("Encoder has to be a function.");var r=e.charset||defaults.charset;if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=formats.default;if(void 0!==e.format){if(!has.call(formats.formatters,e.format))throw new TypeError("Unknown format option provided.");t=e.format}var o,a=formats.formatters[t],n=defaults.filter;if(("function"==typeof e.filter||isArray(e.filter))&&(n=e.filter),o=e.arrayFormat in arrayPrefixGenerators?e.arrayFormat:"indices"in e?e.indices?"indices":"repeat":defaults.arrayFormat,"commaRoundTrip"in e&&"boolean"!=typeof e.commaRoundTrip)throw new TypeError("`commaRoundTrip` must be a boolean, or absent");var i=void 0===e.allowDots?!0===e.encodeDotInKeys||defaults.allowDots:!!e.allowDots;return{addQueryPrefix:"boolean"==typeof e.addQueryPrefix?e.addQueryPrefix:defaults.addQueryPrefix,allowDots:i,allowEmptyArrays:"boolean"==typeof e.allowEmptyArrays?!!e.allowEmptyArrays:defaults.allowEmptyArrays,arrayFormat:o,charset:r,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:defaults.charsetSentinel,commaRoundTrip:e.commaRoundTrip,delimiter:void 0===e.delimiter?defaults.delimiter:e.delimiter,encode:"boolean"==typeof e.encode?e.encode:defaults.encode,encodeDotInKeys:"boolean"==typeof e.encodeDotInKeys?e.encodeDotInKeys:defaults.encodeDotInKeys,encoder:"function"==typeof e.encoder?e.encoder:defaults.encoder,encodeValuesOnly:"boolean"==typeof e.encodeValuesOnly?e.encodeValuesOnly:defaults.encodeValuesOnly,filter:n,format:t,formatter:a,serializeDate:"function"==typeof e.serializeDate?e.serializeDate:defaults.serializeDate,skipNulls:"boolean"==typeof e.skipNulls?e.skipNulls:defaults.skipNulls,sort:"function"==typeof e.sort?e.sort:null,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:defaults.strictNullHandling}};module.exports=function(e,r){var t,o=e,a=normalizeStringifyOptions(r);"function"==typeof a.filter?o=(0,a.filter)("",o):isArray(a.filter)&&(t=a.filter);var n=[];if("object"!=typeof o||null===o)return"";var i=arrayPrefixGenerators[a.arrayFormat],l="comma"===i&&a.commaRoundTrip;t||(t=Object.keys(o)),a.sort&&t.sort(a.sort);for(var s=getSideChannel(),f=0;f<t.length;++f){var u=t[f];a.skipNulls&&null===o[u]||pushToArray(n,stringify(o[u],u,i,l,a.allowEmptyArrays,a.strictNullHandling,a.skipNulls,a.encodeDotInKeys,a.encode?a.encoder:null,a.filter,a.sort,a.allowDots,a.serializeDate,a.format,a.formatter,a.encodeValuesOnly,a.charset,s))}var d=n.join(a.delimiter),y=!0===a.addQueryPrefix?"?":"";return a.charsetSentinel&&("iso-8859-1"===a.charset?y+="utf8=%26%2310003%3B&":y+="utf8=%E2%9C%93&"),d.length>0?y+d:""};
|
package/lib/parse.js
CHANGED
|
@@ -24,6 +24,7 @@ var defaults = {
|
|
|
24
24
|
parameterLimit: 1000,
|
|
25
25
|
parseArrays: true,
|
|
26
26
|
plainObjects: false,
|
|
27
|
+
strictDepth: false,
|
|
27
28
|
strictNullHandling: false
|
|
28
29
|
};
|
|
29
30
|
|
|
@@ -126,7 +127,9 @@ var parseObject = function (chain, val, options, valuesParsed) {
|
|
|
126
127
|
var root = chain[i];
|
|
127
128
|
|
|
128
129
|
if (root === '[]' && options.parseArrays) {
|
|
129
|
-
obj = options.allowEmptyArrays && leaf === ''
|
|
130
|
+
obj = options.allowEmptyArrays && (leaf === '' || (options.strictNullHandling && leaf === null))
|
|
131
|
+
? []
|
|
132
|
+
: [].concat(leaf);
|
|
130
133
|
} else {
|
|
131
134
|
obj = options.plainObjects ? Object.create(null) : {};
|
|
132
135
|
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
|
|
@@ -199,9 +202,12 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesPars
|
|
|
199
202
|
keys.push(segment[1]);
|
|
200
203
|
}
|
|
201
204
|
|
|
202
|
-
// If there's a remainder, just add whatever is left
|
|
205
|
+
// If there's a remainder, check strictDepth option for throw, else just add whatever is left
|
|
203
206
|
|
|
204
207
|
if (segment) {
|
|
208
|
+
if (options.strictDepth === true) {
|
|
209
|
+
throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true');
|
|
210
|
+
}
|
|
205
211
|
keys.push('[' + key.slice(segment.index) + ']');
|
|
206
212
|
}
|
|
207
213
|
|
|
@@ -258,6 +264,7 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
|
|
|
258
264
|
parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
|
|
259
265
|
parseArrays: opts.parseArrays !== false,
|
|
260
266
|
plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
|
|
267
|
+
strictDepth: typeof opts.strictDepth === 'boolean' ? !!opts.strictDepth : defaults.strictDepth,
|
|
261
268
|
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
|
|
262
269
|
};
|
|
263
270
|
};
|
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.13.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"@browserify/envify": "^6.0.0",
|
|
38
38
|
"@browserify/uglifyify": "^6.0.0",
|
|
39
39
|
"@ljharb/eslint-config": "^21.1.1",
|
|
40
|
-
"aud": "^2.0.4",
|
|
41
40
|
"browserify": "^16.5.2",
|
|
42
41
|
"bundle-collapser": "^1.4.0",
|
|
43
42
|
"common-shakeify": "~1.0.0",
|
|
@@ -72,7 +71,7 @@
|
|
|
72
71
|
"pretest": "npm run --silent readme && npm run --silent lint",
|
|
73
72
|
"test": "npm run tests-only",
|
|
74
73
|
"tests-only": "nyc tape 'test/**/*.js'",
|
|
75
|
-
"posttest": "
|
|
74
|
+
"posttest": "npx npm@'>=10.2' audit --production",
|
|
76
75
|
"readme": "evalmd README.md",
|
|
77
76
|
"postlint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)",
|
|
78
77
|
"lint": "eslint --ext=js,mjs .",
|
package/test/parse.js
CHANGED
|
@@ -183,6 +183,15 @@ test('parse()', function (t) {
|
|
|
183
183
|
st.end();
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
+
t.test('allowEmptyArrays + strictNullHandling', function (st) {
|
|
187
|
+
st.deepEqual(
|
|
188
|
+
qs.parse('testEmptyArray[]', { strictNullHandling: true, allowEmptyArrays: true }),
|
|
189
|
+
{ testEmptyArray: [] }
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
st.end();
|
|
193
|
+
});
|
|
194
|
+
|
|
186
195
|
t.deepEqual(qs.parse('a[b]=c'), { a: { b: 'c' } }, 'parses a single nested string');
|
|
187
196
|
t.deepEqual(qs.parse('a[b][c]=d'), { a: { b: { c: 'd' } } }, 'parses a double nested string');
|
|
188
197
|
t.deepEqual(
|
|
@@ -1059,3 +1068,103 @@ test('`duplicates` option', function (t) {
|
|
|
1059
1068
|
|
|
1060
1069
|
t.end();
|
|
1061
1070
|
});
|
|
1071
|
+
|
|
1072
|
+
test('qs strictDepth option - throw cases', function (t) {
|
|
1073
|
+
t.test('throws an exception when depth exceeds the limit with strictDepth: true', function (st) {
|
|
1074
|
+
st['throws'](
|
|
1075
|
+
function () {
|
|
1076
|
+
qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true });
|
|
1077
|
+
},
|
|
1078
|
+
RangeError,
|
|
1079
|
+
'Should throw RangeError'
|
|
1080
|
+
);
|
|
1081
|
+
st.end();
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
t.test('throws an exception for multiple nested arrays with strictDepth: true', function (st) {
|
|
1085
|
+
st['throws'](
|
|
1086
|
+
function () {
|
|
1087
|
+
qs.parse('a[0][1][2][3][4]=b', { depth: 3, strictDepth: true });
|
|
1088
|
+
},
|
|
1089
|
+
RangeError,
|
|
1090
|
+
'Should throw RangeError'
|
|
1091
|
+
);
|
|
1092
|
+
st.end();
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
t.test('throws an exception for nested objects and arrays with strictDepth: true', function (st) {
|
|
1096
|
+
st['throws'](
|
|
1097
|
+
function () {
|
|
1098
|
+
qs.parse('a[b][c][0][d][e]=f', { depth: 3, strictDepth: true });
|
|
1099
|
+
},
|
|
1100
|
+
RangeError,
|
|
1101
|
+
'Should throw RangeError'
|
|
1102
|
+
);
|
|
1103
|
+
st.end();
|
|
1104
|
+
});
|
|
1105
|
+
|
|
1106
|
+
t.test('throws an exception for different types of values with strictDepth: true', function (st) {
|
|
1107
|
+
st['throws'](
|
|
1108
|
+
function () {
|
|
1109
|
+
qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 3, strictDepth: true });
|
|
1110
|
+
},
|
|
1111
|
+
RangeError,
|
|
1112
|
+
'Should throw RangeError'
|
|
1113
|
+
);
|
|
1114
|
+
st.end();
|
|
1115
|
+
});
|
|
1116
|
+
|
|
1117
|
+
});
|
|
1118
|
+
|
|
1119
|
+
test('qs strictDepth option - non-throw cases', function (t) {
|
|
1120
|
+
t.test('when depth is 0 and strictDepth true, do not throw', function (st) {
|
|
1121
|
+
st.doesNotThrow(
|
|
1122
|
+
function () {
|
|
1123
|
+
qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 0, strictDepth: true });
|
|
1124
|
+
},
|
|
1125
|
+
RangeError,
|
|
1126
|
+
'Should not throw RangeError'
|
|
1127
|
+
);
|
|
1128
|
+
st.end();
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
t.test('parses successfully when depth is within the limit with strictDepth: true', function (st) {
|
|
1132
|
+
st.doesNotThrow(
|
|
1133
|
+
function () {
|
|
1134
|
+
var result = qs.parse('a[b]=c', { depth: 1, strictDepth: true });
|
|
1135
|
+
st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly');
|
|
1136
|
+
}
|
|
1137
|
+
);
|
|
1138
|
+
st.end();
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
t.test('does not throw an exception when depth exceeds the limit with strictDepth: false', function (st) {
|
|
1142
|
+
st.doesNotThrow(
|
|
1143
|
+
function () {
|
|
1144
|
+
var result = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
|
|
1145
|
+
st.deepEqual(result, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }, 'Should parse with depth limit');
|
|
1146
|
+
}
|
|
1147
|
+
);
|
|
1148
|
+
st.end();
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
t.test('parses successfully when depth is within the limit with strictDepth: false', function (st) {
|
|
1152
|
+
st.doesNotThrow(
|
|
1153
|
+
function () {
|
|
1154
|
+
var result = qs.parse('a[b]=c', { depth: 1 });
|
|
1155
|
+
st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly');
|
|
1156
|
+
}
|
|
1157
|
+
);
|
|
1158
|
+
st.end();
|
|
1159
|
+
});
|
|
1160
|
+
|
|
1161
|
+
t.test('does not throw when depth is exactly at the limit with strictDepth: true', function (st) {
|
|
1162
|
+
st.doesNotThrow(
|
|
1163
|
+
function () {
|
|
1164
|
+
var result = qs.parse('a[b][c]=d', { depth: 2, strictDepth: true });
|
|
1165
|
+
st.deepEqual(result, { a: { b: { c: 'd' } } }, 'Should parse correctly');
|
|
1166
|
+
}
|
|
1167
|
+
);
|
|
1168
|
+
st.end();
|
|
1169
|
+
});
|
|
1170
|
+
});
|
package/test/stringify.js
CHANGED
|
@@ -315,6 +315,18 @@ test('stringify()', function (t) {
|
|
|
315
315
|
st.end();
|
|
316
316
|
});
|
|
317
317
|
|
|
318
|
+
t.test('allowEmptyArrays + strictNullHandling', function (st) {
|
|
319
|
+
st.equal(
|
|
320
|
+
qs.stringify(
|
|
321
|
+
{ testEmptyArray: [] },
|
|
322
|
+
{ strictNullHandling: true, allowEmptyArrays: true }
|
|
323
|
+
),
|
|
324
|
+
'testEmptyArray[]'
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
st.end();
|
|
328
|
+
});
|
|
329
|
+
|
|
318
330
|
t.test('stringifies an array value with one item vs multiple items', function (st) {
|
|
319
331
|
st.test('non-array item', function (s2t) {
|
|
320
332
|
s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a=c');
|