All new
alle new
This commit is contained in:
1 parent
da64472251
commit
5b20adee48
1605 files changed
+396517
-1674
No files matched your search
BIN
Binary file not shown.
+3
-3
@@ -25,7 +25,7 @@ Caller Application → qs.stringify(obj, options) → Stringifying Engine → Ou
|
||||
|
||||
**Trust Boundaries:**
|
||||
- **Input string (parse):** May come from untrusted sources (e.g., user input, network requests)
|
||||
- **Input object (stringify):** May contain cycles, which can lead to infinite loops during stringification
|
||||
- **Input object (stringify):** The calling application's own data, not a direct untrusted channel. May contain cycles (handled by the cycle detector). Deeply-nested non-cyclic input surfaces as a catchable synchronous `RangeError` (stack overflow), not unbounded resource consumption; callers that serialize externally-influenced objects should bound their depth/size beforehand.
|
||||
- **Options:** Provided by the caller
|
||||
- **Cycle Tracking:** Used only during stringification to detect and handle circular references
|
||||
|
||||
@@ -58,7 +58,7 @@ Caller Application → qs.stringify(obj, options) → Stringifying Engine → Ou
|
||||
|---------------------------------------------------|---------------------|
|
||||
| Tampering (malicious input, prototype pollution) | Strict input validation; keep `allowPrototypes: false` by default; use `plainObjects` for output; ensure builtins/globals are never modified by parse[4][8]. |
|
||||
| Information Disclosure (error messages) | Generic error messages without stack traces or internal paths. |
|
||||
| Denial of Service (memory/CPU exhaustion) | Enforce `arrayLimit` and `parameterLimit` with safe defaults; enable `throwOnLimitExceeded`; limit nesting depth[7]. |
|
||||
| Denial of Service (memory/CPU exhaustion) | `arrayLimit`, `parameterLimit`, and depth limiting apply with safe defaults. Note that `arrayLimit` is a representation threshold (array vs. object), and `parameterLimit` bounds only the number of `&`-delimited parameters - neither caps the elements produced by `comma: true` splitting. For a hard cap that rejects oversized untrusted input, opt in to `throwOnLimitExceeded: true` (default `false`), and always bound input size at the transport layer[7]. On the `stringify` side, the input is the caller's own object rather than an untrusted string, so unbounded nesting manifests as a catchable `RangeError` (stack overflow) rather than exhaustion; callers serializing externally-influenced objects should bound depth/size beforehand, and may opt into `stringify`'s `depth` option (default `Infinity`) for a deterministic, catchable error. |
|
||||
| Elevation of Privilege (prototype pollution) | Keep `allowPrototypes: false`; validate options against allowlist; use `plainObjects` to avoid prototype pollution[4][8]. |
|
||||
|
||||
### 7. Risk Ranking
|
||||
@@ -70,7 +70,7 @@ Caller Application → qs.stringify(obj, options) → Stringifying Engine → Ou
|
||||
### 8. Next Steps & Review
|
||||
|
||||
1. **Audit option validation logic.**
|
||||
2. **Add depth limiting to nested parsing and stringification.**
|
||||
2. **Depth limiting:** `parse` enforces a `depth` bound by default (with `strictDepth` to throw); `stringify` offers an opt-in `depth` bound (default `Infinity`, since its input is caller-produced) for defense-in-depth.
|
||||
3. **Implement fuzz testing for parser and stringifier edge cases.**
|
||||
4. **Regularly review dependencies for vulnerabilities.**
|
||||
5. **Keep documentation and threat model up to date.**
|
||||
|
||||
+15
@@ -1,3 +1,18 @@
|
||||
## **6.16.0**
|
||||
- [New] `stringify`: add a `depth` option to bound recursion depth (default `Infinity`)
|
||||
- [Fix] stringify: serialize Date values when a filter is provided
|
||||
- [Fix] `parse`: enforce `arrayLimit` on comma groups under `[]=` when `throwOnLimitExceeded` is set
|
||||
- [Fix] `parse`: flatten a collection appended to an overflowed array (#571)
|
||||
- [Fix] `utils`: `isBuffer`: do not invoke a non-callable `constructor.isBuffer`
|
||||
- [Fix] `stringify`: do not let `allowEmptyArrays` skip cycle detection (or drop own keys) on an empty array with own properties
|
||||
- [Fix] `stringify`: encode dots in a top-level key with a primitive value when encodeDotInKeys is set (#562)
|
||||
- [Docs] threat model: clarify `stringify` deep-nesting DoS is caller-bounded
|
||||
- [Docs] clarify `arrayLimit` is a representation threshold, not an element-count cap
|
||||
- [Tests] `parse`: remove a test that pinned `[]=` comma groups escaping `arrayLimit`
|
||||
- [Tests] `stringify`: pin current `encodeDotInKeys` separator-dot behavior
|
||||
- [Dev Deps] update `@ljharb/eslint-config`, `eslint`
|
||||
- [Dev Deps] update `eslint`, `evalmd`
|
||||
|
||||
## **6.15.3**
|
||||
- [Fix] `parse`: enforce `throwOnLimitExceeded` for cumulative array growth via `combine`/`merge`
|
||||
- [Fix] `utils`: respect encoding of surrogate pairs across chunks (#559)
|
||||
|
||||
+19
-1
@@ -147,6 +147,8 @@ try {
|
||||
|
||||
When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `parameterLimit` and ignore the rest without throwing an error.
|
||||
|
||||
Note that `parameterLimit` only bounds the number of `&`-delimited parameters; it does not limit how many values a single parameter expands into. In particular, when `comma: true` is enabled, a single parameter's value is split on commas into arbitrarily many elements, which `parameterLimit` does not constrain. To bound the total element count from untrusted input, set `throwOnLimitExceeded: true` (see `arrayLimit` below), and always bound the input size at the transport layer (e.g. an HTTP body-size limit).
|
||||
|
||||
To bypass the leading question mark, use `ignoreQueryPrefix`:
|
||||
|
||||
```javascript
|
||||
@@ -313,7 +315,9 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `arrayLimit` and if the limit is exceeded, the array will instead be converted to an object with the index as the key
|
||||
When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `arrayLimit` and if the limit is exceeded, the array will instead be converted to an object with the index as the key.
|
||||
|
||||
Note that `arrayLimit` is a *representation* threshold that controls when a numerically-indexed collection switches from an array to an object — it is **not** a hard cap on the total number of elements parsed. With the default `throwOnLimitExceeded: false`, exceeding `arrayLimit` never rejects or truncates input; it only changes the container type, and the resulting object still holds every element (so its size stays proportional to the input). This conversion is itself a safeguard: it avoids allocating a huge sparse array for input like `a[999999999]`. If you need a hard limit that rejects oversized input from untrusted sources, set `throwOnLimitExceeded: true`.
|
||||
|
||||
To prevent array syntax (`a[]`, `a[0]`) from being parsed as arrays, set `parseArrays` to `false`.
|
||||
Note that duplicate keys (e.g. `a=b&a=c`) may still produce arrays when `duplicates` is `'combine'` (the default).
|
||||
@@ -410,6 +414,20 @@ var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str) {
|
||||
|
||||
_(Note: the `encoder` option does not apply if `encode` is `false`)_
|
||||
|
||||
By default, `qs.stringify` serializes an object of any nesting depth.
|
||||
For backwards compatibility, and because its input is the caller's own object rather than a query string parsed by **qs**, this is unbounded.
|
||||
If you serialize objects whose nesting can be influenced by untrusted input, bound it with the numeric `depth` option (default `Infinity`);
|
||||
exceeding it throws a catchable `RangeError` instead of eventually overflowing the call stack:
|
||||
|
||||
```javascript
|
||||
try {
|
||||
qs.stringify({ a: { b: { c: { d: 'e' } } } }, { depth: 2 });
|
||||
} catch (err) {
|
||||
assert(err instanceof RangeError);
|
||||
assert.strictEqual(err.message, 'Input depth exceeded depth option of 2');
|
||||
}
|
||||
```
|
||||
|
||||
Analogue to the `encoder` there is a `decoder` option for `parse` to override decoding of properties and values:
|
||||
|
||||
```javascript
|
||||
|
||||
+21
-21
@@ -5,13 +5,13 @@
|
||||
"use strict";var stringify=require(4),parse=require(3),formats=require(1);module.exports={formats:formats,parse:parse,stringify:stringify};
|
||||
|
||||
},{"1":1,"3":3,"4":4}],3:[function(require,module,exports){
|
||||
"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,strictMerge:!0,strictNullHandling:!1,throwOnLimitExceeded:!1},interpretNumericEntities=function(e){return e.replace(/&#(\d+);/g,function(e,t){return String.fromCharCode(parseInt(t,10))})},parseArrayValue=function(e,t,r,i){if(e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1){if(i&&t.throwOnLimitExceeded)for(var a=0,o=e.indexOf(",");o>-1;){if((a+=1)>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");o=e.indexOf(",",o+1)}return e.split(",")}if(t.throwOnLimitExceeded&&r>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return e},isoSentinel="utf8=%26%2310003%3B",charsetSentinel="utf8=%E2%9C%93",parseValues=function parseQueryStringValues(e,t){var r={__proto__:null},i=t.ignoreQueryPrefix?e.replace(/^\?/,""):e;i=i.replace(/%5B/gi,"[").replace(/%5D/gi,"]");var a=t.parameterLimit===1/0?void 0:t.parameterLimit,o=i.split(t.delimiter,t.throwOnLimitExceeded&&void 0!==a?a+1:a);if(t.throwOnLimitExceeded&&void 0!==a&&o.length>a)throw new RangeError("Parameter limit exceeded. Only "+a+" parameter"+(1===a?"":"s")+" allowed.");var l,n=-1,s=t.charset;if(t.charsetSentinel)for(l=0;l<o.length;++l)0===o[l].indexOf("utf8=")&&(o[l]===charsetSentinel?s="utf-8":o[l]===isoSentinel&&(s="iso-8859-1"),n=l,l=o.length);for(l=0;l<o.length;++l)if(l!==n){var d,c,p=o[l],u=p.indexOf("]="),y=-1===u?p.indexOf("="):u+1;if(-1===y?(d=t.decoder(p,defaults.decoder,s,"key"),c=t.strictNullHandling?null:""):null!==(d=t.decoder(p.slice(0,y),defaults.decoder,s,"key"))&&(c=utils.maybeMap(parseArrayValue(p.slice(y+1),t,isArray(r[d])?r[d].length:0,-1===p.indexOf("[]=")),function(e){return t.decoder(e,defaults.decoder,s,"value")})),c&&t.interpretNumericEntities&&"iso-8859-1"===s&&(c=interpretNumericEntities(String(c))),p.indexOf("[]=")>-1&&(c=isArray(c)?[c]:c),t.comma&&isArray(c)&&c.length>t.arrayLimit&&(c=utils.combine([],c,t.arrayLimit,t.plainObjects,t.throwOnLimitExceeded)),null!==d){var f=has.call(r,d);f&&("combine"===t.duplicates||p.indexOf("[]=")>-1)?r[d]=utils.combine(r[d],c,t.arrayLimit,t.plainObjects,t.throwOnLimitExceeded):f&&"last"!==t.duplicates||(r[d]=c)}}return r},parseObject=function(e,t,r,i){var a=0;if(e.length>0&&"[]"===e[e.length-1]){var o=e.slice(0,-1).join("");a=Array.isArray(t)&&t[o]?t[o].length:0}for(var l=i?t:parseArrayValue(t,r,a),n=e.length-1;n>=0;--n){var s,d=e[n];if("[]"===d&&r.parseArrays)s=utils.isOverflow(l)?l:r.allowEmptyArrays&&(""===l||r.strictNullHandling&&null===l)?[]:utils.combine([],l,r.arrayLimit,r.plainObjects,r.throwOnLimitExceeded);else{s=r.plainObjects?{__proto__:null}:{};var c="["===d.charAt(0)&&"]"===d.charAt(d.length-1)?d.slice(1,-1):d,p=r.decodeDotInKeys?c.replace(/%2E/g,"."):c,u=parseInt(p,10),y=!isNaN(u)&&d!==p&&String(u)===p&&u>=0&&r.parseArrays;if(r.parseArrays||""!==p)if(y&&u<r.arrayLimit)(s=[])[u]=l;else{if(y&&r.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+r.arrayLimit+" element"+(1===r.arrayLimit?"":"s")+" allowed in an array.");y?(s[u]=l,utils.markOverflow(s,u)):"__proto__"!==p&&(s[p]=l)}else s={0:l}}l=s}return l},splitKeyIntoSegments=function splitKeyIntoSegments(e,t){var r=t.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e;if(t.depth<=0){if(!t.plainObjects&&has.call(Object.prototype,r)&&!t.allowPrototypes)return;return[r]}var i=[],a=r.indexOf("["),o=a>=0?r.slice(0,a):r;if(o){if(!t.plainObjects&&has.call(Object.prototype,o)&&!t.allowPrototypes)return;i[i.length]=o}for(var l=r.length,n=a,s=0;n>=0&&s<t.depth;){for(var d=1,c=n+1,p=-1;c<l&&p<0;){var u=r.charCodeAt(c);91===u?d+=1:93===u&&0==(d-=1)&&(p=c),c+=1}if(p<0)return i[i.length]="["+r.slice(n)+"]",i;var y=r.slice(n,p+1),f=y.slice(1,-1);if(!t.plainObjects&&has.call(Object.prototype,f)&&!t.allowPrototypes)return;i[i.length]=y,s+=1,n=r.indexOf("[",p+1)}if(n>=0){if(!0===t.strictDepth)throw new RangeError("Input depth exceeded depth option of "+t.depth+" and strictDepth is true");i[i.length]="["+r.slice(n)+"]"}return i},parseKeys=function parseQueryStringKeys(e,t,r,i){if(e){var a=splitKeyIntoSegments(e,r);if(a)return parseObject(a,t,r,i)}},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.Line truncated
|
||||
"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,strictMerge:!0,strictNullHandling:!1,throwOnLimitExceeded:!1},interpretNumericEntities=function(e){return e.replace(/&#(\d+);/g,function(e,t){return String.fromCharCode(parseInt(t,10))})},parseArrayValue=function(e,t,r){if(e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1){if(t.throwOnLimitExceeded)for(var i=0,a=e.indexOf(",");a>-1;){if((i+=1)>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");a=e.indexOf(",",a+1)}return e.split(",")}if(t.throwOnLimitExceeded&&r>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return e},isoSentinel="utf8=%26%2310003%3B",charsetSentinel="utf8=%E2%9C%93",parseValues=function parseQueryStringValues(e,t){var r={__proto__:null},i=t.ignoreQueryPrefix?e.replace(/^\?/,""):e;i=i.replace(/%5B/gi,"[").replace(/%5D/gi,"]");var a=t.parameterLimit===1/0?void 0:t.parameterLimit,o=i.split(t.delimiter,t.throwOnLimitExceeded&&void 0!==a?a+1:a);if(t.throwOnLimitExceeded&&void 0!==a&&o.length>a)throw new RangeError("Parameter limit exceeded. Only "+a+" parameter"+(1===a?"":"s")+" allowed.");var l,n=-1,s=t.charset;if(t.charsetSentinel)for(l=0;l<o.length;++l)0===o[l].indexOf("utf8=")&&(o[l]===charsetSentinel?s="utf-8":o[l]===isoSentinel&&(s="iso-8859-1"),n=l,l=o.length);for(l=0;l<o.length;++l)if(l!==n){var d,c,p=o[l],u=p.indexOf("]="),y=-1===u?p.indexOf("="):u+1;if(-1===y?(d=t.decoder(p,defaults.decoder,s,"key"),c=t.strictNullHandling?null:""):null!==(d=t.decoder(p.slice(0,y),defaults.decoder,s,"key"))&&(c=utils.maybeMap(parseArrayValue(p.slice(y+1),t,isArray(r[d])?r[d].length:0),function(e){return t.decoder(e,defaults.decoder,s,"value")})),c&&t.interpretNumericEntities&&"iso-8859-1"===s&&(c=interpretNumericEntities(String(c))),p.indexOf("[]=")>-1&&(c=isArray(c)?[c]:c),t.comma&&isArray(c)&&c.length>t.arrayLimit&&(c=utils.combine([],c,t.arrayLimit,t.plainObjects,t.throwOnLimitExceeded)),null!==d){var f=has.call(r,d);f&&("combine"===t.duplicates||p.indexOf("[]=")>-1)?r[d]=utils.combine(r[d],c,t.arrayLimit,t.plainObjects,t.throwOnLimitExceeded):f&&"last"!==t.duplicates||(r[d]=c)}}return r},parseObject=function(e,t,r,i){var a=0;if(e.length>0&&"[]"===e[e.length-1]){var o=e.slice(0,-1).join("");a=Array.isArray(t)&&t[o]?t[o].length:0}for(var l=i?t:parseArrayValue(t,r,a),n=e.length-1;n>=0;--n){var s,d=e[n];if("[]"===d&&r.parseArrays)s=utils.isOverflow(l)?l:r.allowEmptyArrays&&(""===l||r.strictNullHandling&&null===l)?[]:utils.combine([],l,r.arrayLimit,r.plainObjects,r.throwOnLimitExceeded);else{s=r.plainObjects?{__proto__:null}:{};var c="["===d.charAt(0)&&"]"===d.charAt(d.length-1)?d.slice(1,-1):d,p=r.decodeDotInKeys?c.replace(/%2E/g,"."):c,u=parseInt(p,10),y=!isNaN(u)&&d!==p&&String(u)===p&&u>=0&&r.parseArrays;if(r.parseArrays||""!==p)if(y&&u<r.arrayLimit)(s=[])[u]=l;else{if(y&&r.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+r.arrayLimit+" element"+(1===r.arrayLimit?"":"s")+" allowed in an array.");y?(s[u]=l,utils.markOverflow(s,u)):"__proto__"!==p&&(s[p]=l)}else s={0:l}}l=s}return l},splitKeyIntoSegments=function splitKeyIntoSegments(e,t){var r=t.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e;if(t.depth<=0){if(!t.plainObjects&&has.call(Object.prototype,r)&&!t.allowPrototypes)return;return[r]}var i=[],a=r.indexOf("["),o=a>=0?r.slice(0,a):r;if(o){if(!t.plainObjects&&has.call(Object.prototype,o)&&!t.allowPrototypes)return;i[i.length]=o}for(var l=r.length,n=a,s=0;n>=0&&s<t.depth;){for(var d=1,c=n+1,p=-1;c<l&&p<0;){var u=r.charCodeAt(c);91===u?d+=1:93===u&&0==(d-=1)&&(p=c),c+=1}if(p<0)return i[i.length]="["+r.slice(n)+"]",i;var y=r.slice(n,p+1),f=y.slice(1,-1);if(!t.plainObjects&&has.call(Object.prototype,f)&&!t.allowPrototypes)return;i[i.length]=y,s+=1,n=r.indexOf("[",p+1)}if(n>=0){if(!0===t.strictDepth)throw new RangeError("Input depth exceeded depth option of "+t.depth+" and strictDepth is true");i[i.length]="["+r.slice(n)+"]"}return i},parseKeys=function parseQueryStringKeys(e,t,r,i){if(e){var a=splitKeyIntoSegments(e,r);if(a)return parseObject(a,t,r,i)}},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.decoderLine truncated
|
||||
|
||||
},{"5":5}],4:[function(require,module,exports){
|
||||
"use strict";var getSideChannel=require(46),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,commaRoundTrip:!1,delimiter:"&",encode:!0,encodeDotInKeys:!1,encoder:utils.encode,encodeValuesOnly:!1,filter:void 0,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 g=e,w=v,b=0,A=!1;void 0!==(w=w.get(sentinel))&&!A;){var D=w.get(e);if(b+=1,void 0!==D){if(D===b)throw new RangeError("Cyclic object value");A=!0}void 0===w.get(sentinel)&&(b=0)}if("function"==typeof f?g=f(r,g):g instanceof Date?g=y(g):"comma"===t&&isArray(g)&&(g=utils.maybeMap(g,function(e){return e instanceof Date?y(e):e})),null===g){if(n)return p(s&&!m?s(r,defaults.encoder,h,"key",c):r);g=""}if(isNonNullishPrimitive(g)||utils.isBuffer(g))return s?[p(m?r:s(r,defaults.encoder,h,"key",c))+"="+p(s(g,defaults.encoder,h,"value",c))]:[p(r)+"="+p(String(g))];var S,E=[];if(void 0===g)return E;if("comma"===t&&isArray(g))m&&s&&(g=utils.maybeMap(g,function(e){return null==e?e:s(e)})),S=[{value:g.length>0?g.join(",")||null:void 0}];else if(isArray(f))S=f;else{var N=Object.keys(g);S=u?N.sort(u):N}var T=l?String(r).replace(/\./g,"%2E"):String(r),O=o&&isArray(g)&&1===g.length?T+"[]":T;if(a&&isArray(g)&&0===g.length)return O+"[]";for(var k=0;k<S.length;++k){var I=S[k],P="object"==typeof I&&I&&void 0!==I.value?I.value:g[I];if(!i||null!==P){var x=d&&l?String(I).replace(/\./g,"%2E"):String(I),z=isArray(g)?"function"==typeof t?t(O,x):O:O+(d?"."+x:"["+x+"]");v.set(e,b);var K=getSideChannel();K.set(sentinel,v),pushToArray(E,stringify(P,z,t,o,a,n,i,l,"comma"===t&&m&&isArray(g)?null:s,f,u,d,y,c,p,m,h,K))}}return E},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"Line truncated
|
||||
"use strict";var getSideChannel=require(46),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,commaRoundTrip:!1,delimiter:"&",depth:1/0,encode:!0,encodeDotInKeys:!1,encoder:utils.encode,encodeValuesOnly:!1,filter:void 0,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,n,a,i,l,s,f,u,d,y,c,p,m,h,v,g,w){var b=e;if(w>g)throw new RangeError("Input depth exceeded depth option of "+g);for(var D=v,A=0,S=!1;void 0!==(D=D.get(sentinel))&&!S;){var E=D.get(e);if(A+=1,void 0!==E){if(E===A)throw new RangeError("Cyclic object value");S=!0}void 0===D.get(sentinel)&&(A=0)}if((b="function"==typeof f?f(r,b):b)instanceof Date?b=y(b):"comma"===t&&isArray(b)&&(b=utils.maybeMap(b,function(e){return e instanceof Date?y(e):e})),null===b){if(a)return p(s&&!m?s(r,defaults.encoder,h,"key",c):r);b=""}if(isNonNullishPrimitive(b)||utils.isBuffer(b))return s?[p(m?r:s(r,defaults.encoder,h,"key",c))+"="+p(s(b,defaults.encoder,h,"value",c))]:[p(r)+"="+p(String(b))];var N,O=[];if(void 0===b)return O;if("comma"===t&&isArray(b))m&&s&&(b=utils.maybeMap(b,function(e){return null==e?e:s(e)})),N=[{value:b.length>0?b.join(",")||null:void 0}];else if(isArray(f))N=f;else{var T=Object.keys(b);N=u?T.sort(u):T}var k=l?String(r).replace(/\./g,"%2E"):String(r),I=o&&isArray(b)&&1===b.length?k+"[]":k;if(n&&isArray(b)&&0===b.length&&0===Object.keys(b).length)return I+"[]";for(var P=0;P<N.length;++P){var x=N[P],K="object"==typeof x&&x&&void 0!==x.value?x.value:b[x];if(!i||null!==K){var z=d&&l?String(x).replace(/\./g,"%2E"):String(x),j=isArray(b)?"function"==typeof t?t(I,z):I:I+(d?"."+z:"["+z+"]");v.set(e,A);var F=getSideChannel();F.set(sentinel,v),pushToArray(O,stringify(K,j,t,o,n,a,i,l,"comma"===t&&m&&isArray(b)?null:s,f,u,d,y,c,p,m,h,F,g,w+1))}}return O},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,n=formats.formatters[t],a=defaults.filter;if(("function"==typeof e.filter||isArray(e.filter))&&(a=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,depth:"number"==typeof e.depth?e.depth:defaults.depth,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:a,format:t,formatter:n,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.strictNullHandlLine truncated
|
||||
|
||||
},{"1":1,"46":46,"5":5}],5:[function(require,module,exports){
|
||||
"use strict";var formats=require(1),getSideChannel=require(46),defineProperty=require(14),has=Object.prototype.hasOwnProperty,isArray=Array.isArray,overflowChannel=getSideChannel(),markOverflow=function markOverflow(e,r){return overflowChannel.set(e,r),e},isOverflow=function isOverflow(e){return overflowChannel.has(e)},getMaxIndex=function getMaxIndex(e){return overflowChannel.get(e)},setMaxIndex=function setMaxIndex(e,r){overflowChannel.set(e,r)},hexTable=function(){for(var e=[],r=0;r<256;++r)e[e.length]="%"+((r<16?"0":"")+r.toString(16)).toUpperCase();return e}(),compactQueue=function compactQueue(e){for(;e.length>1;){var r=e.pop(),t=r.obj[r.prop];if(isArray(t)){for(var n=[],a=0;a<t.length;++a)void 0!==t[a]&&(n[n.length]=t[a]);r.obj[r.prop]=n}}},arrayToObject=function arrayToObject(e,r){for(var t=r&&r.plainObjects?{__proto__:null}:{},n=0;n<e.length;++n)void 0!==e[n]&&(t[n]=e[n]);return t},setProperty=function setProperty(e,r,t){"__proto__"===r&&defineProperty?defineProperty(e,r,{configurable:!0,enumerable:!0,value:t,writable:!0}):e[r]=t},merge=function merge(e,r,t){if(!r)return e;if("object"!=typeof r&&"function"!=typeof r){if(isArray(e)){var n=e.length;if(t&&"number"==typeof t.arrayLimit&&n>=t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(e.concat(r),t),n)}e[n]=r}else{if(!e||"object"!=typeof e)return[e,r];if(isOverflow(e)){var a=getMaxIndex(e)+1;e[a]=r,setMaxIndex(e,a)}else{if(t&&t.strictMerge)return[e,r];(t&&(t.plainObjects||t.allowPrototypes)||!has.call(Object.prototype,r))&&(e[r]=!0)}}return e}if(!e||"object"!=typeof e){if(isOverflow(r)){for(var o=Object.keys(r),i=t&&t.plainObjects?{__proto__:null,0:e}:{0:e},l=0;l<o.length;l++)i[parseInt(o[l],10)+1]=r[o[l]];return markOverflow(i,getMaxIndex(r)+1)}var c=[e].concat(r);if(t&&"number"==typeof t.arrayLimit&&c.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(c,t),c.length-1)}return c}var f=e;if(isArray(e)&&!isArray(r)&&(f=arrayToObject(e,t)),isArray(e)&&isArray(r)){if(r.forEach(function(r,n){if(has.call(e,n)){var a=e[n];a&&"object"==typeof a&&r&&"object"==typeof r?e[n]=merge(a,r,t):e[e.length]=r}else e[n]=r}),t&&"number"==typeof t.arrayLimit&&e.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(e,t),e.length-1)}return e}return Object.keys(r).reduce(function(e,n){var a=r[n];if(has.call(e,n)?setProperty(e,n,merge(e[n],a,t)):setProperty(e,n,a),isOverflow(r)&&!isOverflow(e)&&markOverflow(e,getMaxIndex(r)),isOverflow(e)){var o=parseInt(n,10);String(o)===n&&o>=0&&o>getMaxIndex(e)&&setMaxIndex(e,o)}return e},f)},assign=function assignSingleSource(e,r){return Object.keys(r).reduce(function(e,t){return setProperty(e,t,r[t]),e},e)},decode=function(e,r,t){var n=e.replace(/\+/g," ");if("iso-8859-1"===t)return n.replace(/%[0-9a-f]{2}/gi,unescape);try{return decodeURIComponent(n)}catch(e){return n}},limit=1024,encode=function encode(e,r,t,n,a){if(0===e.length)return e;var o=e;if("symbol"==typeof e?o=Symbol.prototype.toString.call(e):"string"!=typeof e&&(o=String(e)),"iso-8859-1"===t)return escape(o).replace(/%u[0-9a-f]{4}/gi,function(e){return"%26%23"+parseInt(e.slice(2),16)+"%3B"});for(var i="",l=0;l<o.length;l+=limit){var c=o.length>=limit?o.slice(l,l+limit):o;if(l+limit<o.length){var f=c.charCodeAt(c.length-1);f>=55296&&f<=56319&&(c=c.slice(0,-1),l-=1)}for(var s=[],u=0;u<c.length;++u){var y=c.charCodeAt(u);45===y||46===y||95===y||126===y||y>=48&&y<=57||y>=65&&y<=90||y>=97&&y<=122||a===formats.RFC1738&&(40===y||41===y)?s[s.length]=c.charAt(u):y<128?s[s.length]=hexTable[y]:y<2048?s[s.length]=hexTable[192|y>>6]+hexTable[128|63&y]:y<55296||y>=57344?s[s.length]=hexTable[224|y>>12]+hexTable[128|y>>6&63]+hexTable[128|63&y]:(u+=1,y=65536+((1023&y)<<10|1023&c.charCodeAt(u)),s[s.length]=hexTable[240|y>>18]+hexTable[128|y>>12&63]+hexTable[128|y>>6&63]+hexTable[128|63&y])}i+=s.join("")}return i},compact=function compact(e){for(var r=[{obj:{o:e},prop:"o"}],t=getSideChannel(),n=0;n<r.length;++n)for(var a=r[n],o=a.obj[a.prop],i=Object.keys(o),l=0;l<i.length;++l){var c=i[l],f=o[c];"object"!=typeof f||null===f||t.has(f)||(r[r.length]={obj:o,prop:c},t.set(f,!0))}return compactQueue(r),e},isRegExp=function isRegExp(e){return"[object RegExp]"===Object.prototype.toString.call(e)},isBuffer=function isBuffer(e){return!(!e||"object"!=typeof e||!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e)))},combine=function combine(e,r,t,n,a){if(isOverflow(e)){if(a)throw new RangeError("Array limit exceeded. Only "+t+" element"+(1===t?"":"s")+" allowed in an array.");var o=getMaxIndex(e)+1;return e[o]=r,setMaxIndex(e,o),e}var i=Line truncated
|
||||
"use strict";var formats=require(1),getSideChannel=require(46),defineProperty=require(14),has=Object.prototype.hasOwnProperty,isArray=Array.isArray,overflowChannel=getSideChannel(),markOverflow=function markOverflow(e,r){return overflowChannel.set(e,r),e},isOverflow=function isOverflow(e){return overflowChannel.has(e)},getMaxIndex=function getMaxIndex(e){return overflowChannel.get(e)},setMaxIndex=function setMaxIndex(e,r){overflowChannel.set(e,r)},hexTable=function(){for(var e=[],r=0;r<256;++r)e[e.length]="%"+((r<16?"0":"")+r.toString(16)).toUpperCase();return e}(),compactQueue=function compactQueue(e){for(;e.length>1;){var r=e.pop(),t=r.obj[r.prop];if(isArray(t)){for(var n=[],a=0;a<t.length;++a)void 0!==t[a]&&(n[n.length]=t[a]);r.obj[r.prop]=n}}},arrayToObject=function arrayToObject(e,r){for(var t=r&&r.plainObjects?{__proto__:null}:{},n=0;n<e.length;++n)void 0!==e[n]&&(t[n]=e[n]);return t},setProperty=function setProperty(e,r,t){"__proto__"===r&&defineProperty?defineProperty(e,r,{configurable:!0,enumerable:!0,value:t,writable:!0}):e[r]=t},merge=function merge(e,r,t){if(!r)return e;if("object"!=typeof r&&"function"!=typeof r){if(isArray(e)){var n=e.length;if(t&&"number"==typeof t.arrayLimit&&n>=t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(e.concat(r),t),n)}e[n]=r}else{if(!e||"object"!=typeof e)return[e,r];if(isOverflow(e)){var a=getMaxIndex(e)+1;e[a]=r,setMaxIndex(e,a)}else{if(t&&t.strictMerge)return[e,r];(t&&(t.plainObjects||t.allowPrototypes)||!has.call(Object.prototype,r))&&(e[r]=!0)}}return e}if(!e||"object"!=typeof e){if(isOverflow(r)){for(var o=Object.keys(r),i=t&&t.plainObjects?{__proto__:null,0:e}:{0:e},l=0;l<o.length;l++)i[parseInt(o[l],10)+1]=r[o[l]];return markOverflow(i,getMaxIndex(r)+1)}var c=[e].concat(r);if(t&&"number"==typeof t.arrayLimit&&c.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(c,t),c.length-1)}return c}var f=e;if(isArray(e)&&!isArray(r)&&(f=arrayToObject(e,t)),isArray(e)&&isArray(r)){if(r.forEach(function(r,n){if(has.call(e,n)){var a=e[n];a&&"object"==typeof a&&r&&"object"==typeof r?e[n]=merge(a,r,t):e[e.length]=r}else e[n]=r}),t&&"number"==typeof t.arrayLimit&&e.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(e,t),e.length-1)}return e}return Object.keys(r).reduce(function(e,n){var a=r[n];if(has.call(e,n)?setProperty(e,n,merge(e[n],a,t)):setProperty(e,n,a),isOverflow(r)&&!isOverflow(e)&&markOverflow(e,getMaxIndex(r)),isOverflow(e)){var o=parseInt(n,10);String(o)===n&&o>=0&&o>getMaxIndex(e)&&setMaxIndex(e,o)}return e},f)},assign=function assignSingleSource(e,r){return Object.keys(r).reduce(function(e,t){return setProperty(e,t,r[t]),e},e)},decode=function(e,r,t){var n=e.replace(/\+/g," ");if("iso-8859-1"===t)return n.replace(/%[0-9a-f]{2}/gi,unescape);try{return decodeURIComponent(n)}catch(e){return n}},limit=1024,encode=function encode(e,r,t,n,a){if(0===e.length)return e;var o=e;if("symbol"==typeof e?o=Symbol.prototype.toString.call(e):"string"!=typeof e&&(o=String(e)),"iso-8859-1"===t)return escape(o).replace(/%u[0-9a-f]{4}/gi,function(e){return"%26%23"+parseInt(e.slice(2),16)+"%3B"});for(var i="",l=0;l<o.length;l+=limit){var c=o.length>=limit?o.slice(l,l+limit):o;if(l+limit<o.length){var f=c.charCodeAt(c.length-1);f>=55296&&f<=56319&&(c=c.slice(0,-1),l-=1)}for(var s=[],u=0;u<c.length;++u){var y=c.charCodeAt(u);45===y||46===y||95===y||126===y||y>=48&&y<=57||y>=65&&y<=90||y>=97&&y<=122||a===formats.RFC1738&&(40===y||41===y)?s[s.length]=c.charAt(u):y<128?s[s.length]=hexTable[y]:y<2048?s[s.length]=hexTable[192|y>>6]+hexTable[128|63&y]:y<55296||y>=57344?s[s.length]=hexTable[224|y>>12]+hexTable[128|y>>6&63]+hexTable[128|63&y]:(u+=1,y=65536+((1023&y)<<10|1023&c.charCodeAt(u)),s[s.length]=hexTable[240|y>>18]+hexTable[128|y>>12&63]+hexTable[128|y>>6&63]+hexTable[128|63&y])}i+=s.join("")}return i},compact=function compact(e){for(var r=[{obj:{o:e},prop:"o"}],t=getSideChannel(),n=0;n<r.length;++n)for(var a=r[n],o=a.obj[a.prop],i=Object.keys(o),l=0;l<i.length;++l){var c=i[l],f=o[c];"object"!=typeof f||null===f||t.has(f)||(r[r.length]={obj:o,prop:c},t.set(f,!0))}return compactQueue(r),e},isRegExp=function isRegExp(e){return"[object RegExp]"===Object.prototype.toString.call(e)},isBuffer=function isBuffer(e){return!(!e||"object"!=typeof e||!e.constructor||"function"!=typeof e.constructor.isBuffer||!e.constructor.isBuffer(e))},combine=function combine(e,r,t,n,a){if(isOverflow(e)){if(a)throw new RangeError("Array limit exceeded. Only "+t+" element"+(1===t?"":"s")+" allowed in an array.");for(var o=isArray(r)?r:[r],i=getMaxIndex(e),Line truncated
|
||||
|
||||
},{"1":1,"14":14,"46":46}],46:[function(require,module,exports){
|
||||
"use strict";var $TypeError=require(20),inspect=require(42),getSideChannelList=require(43),getSideChannelMap=require(44),getSideChannelWeakMap=require(45),makeChannel=getSideChannelWeakMap||getSideChannelMap||getSideChannelList;module.exports=function getSideChannel(){var e,n={assert:function(e){if(!n.has(e)){var t=e&&Object(e)===e?"the given object key":inspect(e);throw new $TypeError("Side channel does not contain "+t)}},delete:function(n){return!!e&&e.delete(n)},get:function(n){return e&&e.get(n)},has:function(n){return!!e&&e.has(n)},set:function(n,t){e||(e=makeChannel()),e.set(n,t)}};return n};
|
||||
@@ -24,12 +24,12 @@
|
||||
},{}],7:[function(require,module,exports){
|
||||
"use strict";var bind=require(24),$apply=require(8),$call=require(9),$reflectApply=require(11);module.exports=$reflectApply||bind.call($call,$apply);
|
||||
|
||||
},{"11":11,"24":24,"8":8,"9":9}],9:[function(require,module,exports){
|
||||
"use strict";module.exports=Function.prototype.call;
|
||||
|
||||
},{}],8:[function(require,module,exports){
|
||||
},{"11":11,"24":24,"8":8,"9":9}],8:[function(require,module,exports){
|
||||
"use strict";module.exports=Function.prototype.apply;
|
||||
|
||||
},{}],9:[function(require,module,exports){
|
||||
"use strict";module.exports=Function.prototype.call;
|
||||
|
||||
},{}],24:[function(require,module,exports){
|
||||
"use strict";var implementation=require(23);module.exports=Function.prototype.bind||implementation;
|
||||
|
||||
@@ -78,23 +78,23 @@
|
||||
},{}],23:[function(require,module,exports){
|
||||
"use strict";var ERROR_MESSAGE="Function.prototype.bind called on incompatible ",toStr=Object.prototype.toString,max=Math.max,funcType="[object Function]",concatty=function concatty(t,n){for(var r=[],o=0;o<t.length;o+=1)r[o]=t[o];for(var e=0;e<n.length;e+=1)r[e+t.length]=n[e];return r},slicy=function slicy(t,n){for(var r=[],o=n||0,e=0;o<t.length;o+=1,e+=1)r[e]=t[o];return r},joiny=function(t,n){for(var r="",o=0;o<t.length;o+=1)r+=t[o],o+1<t.length&&(r+=n);return r};module.exports=function bind(t){var n=this;if("function"!=typeof n||toStr.apply(n)!==funcType)throw new TypeError(ERROR_MESSAGE+n);for(var r,o=slicy(arguments,1),e=max(0,n.length-o.length),i=[],c=0;c<e;c++)i[c]="$"+c;if(r=Function("binder","return function ("+joiny(i,",")+"){ return binder.apply(this,arguments); }")(function(){if(this instanceof r){var e=n.apply(this,concatty(o,arguments));return Object(e)===e?e:this}return n.apply(t,concatty(o,arguments))}),n.prototype){var p=function Empty(){};p.prototype=n.prototype,r.prototype=new p,p.prototype=null}return r};
|
||||
|
||||
},{}],37:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.max;
|
||||
|
||||
},{}],40:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.round;
|
||||
},{}],35:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.floor;
|
||||
|
||||
},{}],34:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.abs;
|
||||
|
||||
},{}],38:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.min;
|
||||
},{}],37:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.max;
|
||||
|
||||
},{}],39:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.pow;
|
||||
|
||||
},{}],35:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.floor;
|
||||
},{}],40:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.round;
|
||||
|
||||
},{}],38:[function(require,module,exports){
|
||||
"use strict";module.exports=Math.min;
|
||||
|
||||
},{}],27:[function(require,module,exports){
|
||||
"use strict";module.exports="undefined"!=typeof Reflect&&Reflect.getPrototypeOf||null;
|
||||
@@ -102,13 +102,13 @@
|
||||
},{}],26:[function(require,module,exports){
|
||||
"use strict";var $Object=require(22);module.exports=$Object.getPrototypeOf||null;
|
||||
|
||||
},{"22":22}],33:[function(require,module,exports){
|
||||
"use strict";var call=Function.prototype.call,$hasOwn=Object.prototype.hasOwnProperty,bind=require(24);module.exports=bind.call(call,$hasOwn);
|
||||
|
||||
},{"24":24}],41:[function(require,module,exports){
|
||||
},{"22":22}],41:[function(require,module,exports){
|
||||
"use strict";var $isNaN=require(36);module.exports=function sign(i){return $isNaN(i)||0===i?i:i<0?-1:1};
|
||||
|
||||
},{"36":36}],31:[function(require,module,exports){
|
||||
},{"36":36}],33:[function(require,module,exports){
|
||||
"use strict";var call=Function.prototype.call,$hasOwn=Object.prototype.hasOwnProperty,bind=require(24);module.exports=bind.call(call,$hasOwn);
|
||||
|
||||
},{"24":24}],31:[function(require,module,exports){
|
||||
"use strict";var origSymbol="undefined"!=typeof Symbol&&Symbol,hasSymbolSham=require(32);module.exports=function hasNativeSymbols(){return"function"==typeof origSymbol&&"function"==typeof Symbol&&"symbol"==typeof origSymbol("foo")&&"symbol"==typeof Symbol("bar")&&hasSymbolSham()};
|
||||
|
||||
},{"32":32}],28:[function(require,module,exports){
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ export default [
|
||||
'error',
|
||||
{ max: 150 },
|
||||
],
|
||||
'max-params': ['error', 18],
|
||||
'max-params': ['error', 20],
|
||||
'max-statements': ['error', 100],
|
||||
'multiline-comment-style': 'off',
|
||||
'no-continue': 'warn',
|
||||
|
||||
+3
-4
@@ -36,9 +36,9 @@ var interpretNumericEntities = function (str) {
|
||||
});
|
||||
};
|
||||
|
||||
var parseArrayValue = function (val, options, currentArrayLength, isFlatArrayValue) {
|
||||
var parseArrayValue = function (val, options, currentArrayLength) {
|
||||
if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
|
||||
if (isFlatArrayValue && options.throwOnLimitExceeded) {
|
||||
if (options.throwOnLimitExceeded) {
|
||||
var commaCount = 0;
|
||||
var commaIndex = val.indexOf(',');
|
||||
while (commaIndex > -1) {
|
||||
@@ -125,8 +125,7 @@ var parseValues = function parseQueryStringValues(str, options) {
|
||||
parseArrayValue(
|
||||
part.slice(pos + 1),
|
||||
options,
|
||||
isArray(obj[key]) ? obj[key].length : 0,
|
||||
part.indexOf('[]=') === -1
|
||||
isArray(obj[key]) ? obj[key].length : 0
|
||||
),
|
||||
function (encodedVal) {
|
||||
return options.decoder(encodedVal, defaults.decoder, charset, 'value');
|
||||
|
||||
+23
-8
@@ -36,6 +36,7 @@ var defaults = {
|
||||
charsetSentinel: false,
|
||||
commaRoundTrip: false,
|
||||
delimiter: '&',
|
||||
depth: Infinity,
|
||||
encode: true,
|
||||
encodeDotInKeys: false,
|
||||
encoder: utils.encode,
|
||||
@@ -80,10 +81,16 @@ var stringify = function stringify(
|
||||
formatter,
|
||||
encodeValuesOnly,
|
||||
charset,
|
||||
sideChannel
|
||||
sideChannel,
|
||||
depth,
|
||||
currentDepth
|
||||
) {
|
||||
var obj = object;
|
||||
|
||||
if (currentDepth > depth) {
|
||||
throw new RangeError('Input depth exceeded depth option of ' + depth);
|
||||
}
|
||||
|
||||
var tmpSc = sideChannel;
|
||||
var step = 0;
|
||||
var findFlag = false;
|
||||
@@ -103,9 +110,9 @@ var stringify = function stringify(
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof filter === 'function') {
|
||||
obj = filter(prefix, obj);
|
||||
} else if (obj instanceof Date) {
|
||||
obj = typeof filter === 'function' ? filter(prefix, obj) : obj;
|
||||
|
||||
if (obj instanceof Date) {
|
||||
obj = serializeDate(obj);
|
||||
} else if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
||||
obj = utils.maybeMap(obj, function (value) {
|
||||
@@ -158,7 +165,7 @@ var stringify = function stringify(
|
||||
|
||||
var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + '[]' : encodedPrefix;
|
||||
|
||||
if (allowEmptyArrays && isArray(obj) && obj.length === 0) {
|
||||
if (allowEmptyArrays && isArray(obj) && obj.length === 0 && Object.keys(obj).length === 0) {
|
||||
return adjustedPrefix + '[]';
|
||||
}
|
||||
|
||||
@@ -198,7 +205,9 @@ var stringify = function stringify(
|
||||
formatter,
|
||||
encodeValuesOnly,
|
||||
charset,
|
||||
valueSideChannel
|
||||
valueSideChannel,
|
||||
depth,
|
||||
currentDepth + 1
|
||||
));
|
||||
}
|
||||
|
||||
@@ -265,6 +274,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
||||
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
||||
commaRoundTrip: !!opts.commaRoundTrip,
|
||||
delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
|
||||
depth: typeof opts.depth === 'number' ? opts.depth : defaults.depth,
|
||||
encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
|
||||
encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys,
|
||||
encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
|
||||
@@ -324,9 +334,12 @@ module.exports = function (object, opts) {
|
||||
if (options.skipNulls && value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var encodedKey = options.encodeDotInKeys ? String(key).replace(/\./g, '%2E') : String(key);
|
||||
|
||||
pushToArray(keys, stringify(
|
||||
value,
|
||||
key,
|
||||
encodedKey,
|
||||
generateArrayPrefix,
|
||||
commaRoundTrip,
|
||||
options.allowEmptyArrays,
|
||||
@@ -342,7 +355,9 @@ module.exports = function (object, opts) {
|
||||
options.formatter,
|
||||
options.encodeValuesOnly,
|
||||
options.charset,
|
||||
sideChannel
|
||||
sideChannel,
|
||||
options.depth,
|
||||
0
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -329,7 +329,7 @@ var isBuffer = function isBuffer(obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
|
||||
return !!(obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj));
|
||||
};
|
||||
|
||||
var combine = function combine(a, b, arrayLimit, plainObjects, throwOnLimitExceeded) {
|
||||
@@ -338,8 +338,15 @@ var combine = function combine(a, b, arrayLimit, plainObjects, throwOnLimitExcee
|
||||
if (throwOnLimitExceeded) {
|
||||
throw new RangeError('Array limit exceeded. Only ' + arrayLimit + ' element' + (arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
|
||||
}
|
||||
var newIndex = getMaxIndex(a) + 1;
|
||||
a[newIndex] = b;
|
||||
// spread `b` one level, matching the `[].concat(a, b)` used below, so a
|
||||
// collection appended to an already-overflowed object is flattened
|
||||
// rather than nested under a single index
|
||||
var bValues = isArray(b) ? b : [b];
|
||||
var newIndex = getMaxIndex(a);
|
||||
for (var i = 0; i < bValues.length; ++i) {
|
||||
newIndex += 1;
|
||||
a[newIndex] = bValues[i];
|
||||
}
|
||||
setMaxIndex(a, newIndex);
|
||||
return a;
|
||||
}
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@
|
||||
"name": "qs",
|
||||
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
||||
"homepage": "https://github.com/ljharb/qs",
|
||||
"version": "6.15.3",
|
||||
"version": "6.16.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ljharb/qs.git"
|
||||
@@ -37,14 +37,14 @@
|
||||
"devDependencies": {
|
||||
"@browserify/envify": "^6.0.0",
|
||||
"@browserify/uglifyify": "^6.0.0",
|
||||
"@ljharb/eslint-config": "^22.2.3",
|
||||
"@ljharb/eslint-config": "^22.2.4",
|
||||
"browserify": "^16.5.2",
|
||||
"bundle-collapser": "^1.4.0",
|
||||
"common-shakeify": "~1.0.0",
|
||||
"eclint": "^2.8.1",
|
||||
"es-value-fixtures": "^1.7.1",
|
||||
"eslint": "^10.5.0",
|
||||
"evalmd": "^0.0.19",
|
||||
"eslint": "^10.9.0",
|
||||
"evalmd": "^0.0.22",
|
||||
"for-each": "^0.3.5",
|
||||
"glob": "=10.3.7",
|
||||
"has-bigints": "^1.1.0",
|
||||
|
||||
+192
-3
@@ -1475,6 +1475,73 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('spreads a comma group appended to an already-overflowed object', function (sst) {
|
||||
var result = qs.parse('a=1,2,3,4,5,6&a=7,8', { comma: true, arrayLimit: 5 });
|
||||
sst.deepEqual(
|
||||
result,
|
||||
{ a: { 0: '1', 1: '2', 2: '3', 3: '4', 4: '5', 5: '6', 6: '7', 7: '8' } },
|
||||
'appended comma values are flattened, not nested'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('keeps a `[]=` comma group as one element when appended to an already-overflowed key', function (sst) {
|
||||
var result = qs.parse('a[]=1&a[]=2&a[]=3&a[]=4,5', { comma: true, arrayLimit: 2 });
|
||||
sst.deepEqual(
|
||||
result,
|
||||
{ a: { 0: '1', 1: '2', 2: '3', 3: ['4', '5'] } },
|
||||
'nested comma group stays a single element, not double-nested'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('spreads every later comma group appended to an already-overflowed object', function (sst) {
|
||||
var result = qs.parse('a=1,2,3,4,5,6&a=7,8&a=9,10', { comma: true, arrayLimit: 5 });
|
||||
sst.deepEqual(
|
||||
result,
|
||||
{ a: { 0: '1', 1: '2', 2: '3', 3: '4', 4: '5', 5: '6', 6: '7', 7: '8', 8: '9', 9: '10' } },
|
||||
'each appended group is flattened in order'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('spreads a comma group appended to an object overflowed under the default arrayLimit', function (sst) {
|
||||
var values = [];
|
||||
for (var i = 0; i <= 20; i += 1) {
|
||||
values[values.length] = String(i);
|
||||
}
|
||||
var expected = {};
|
||||
for (var j = 0; j < values.length; j += 1) {
|
||||
expected[j] = values[j];
|
||||
}
|
||||
expected[21] = 'x';
|
||||
expected[22] = 'y';
|
||||
|
||||
var result = qs.parse('a=' + values.join(',') + '&a=x,y', { comma: true });
|
||||
sst.deepEqual(result, { a: expected }, 'appended values land at indices 21 and 22');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('spreads a comma group appended to an already-overflowed object with plainObjects', function (sst) {
|
||||
var result = qs.parse('a=1,2,3,4,5,6&a=7,8', { comma: true, arrayLimit: 5, plainObjects: true });
|
||||
sst.deepEqual(
|
||||
result,
|
||||
{ __proto__: null, a: { __proto__: null, 0: '1', 1: '2', 2: '3', 3: '4', 4: '5', 5: '6', 6: '7', 7: '8' } },
|
||||
'appended comma values are flattened into the null object'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('still throws with throwOnLimitExceeded when a comma group is appended to an already-overflowed object', function (sst) {
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a=1,2,3,4,5,6&a=7,8', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true });
|
||||
},
|
||||
/Array limit exceeded/,
|
||||
'throws before spreading the appended group'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
st.test('does not throw for comma groups nested under bracket notation, counting each group as one element', function (sst) {
|
||||
var result = qs.parse('a[]=1,2,3&a[]=4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true });
|
||||
sst.deepEqual(result, { a: [['1', '2', '3'], ['4', '5', '6']] }, 'nested comma groups count as one element each');
|
||||
@@ -1522,9 +1589,131 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('does not throw for a bracketed comma group within arrayLimit', function (sst) {
|
||||
var result = qs.parse('a[]=1,2,3,4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true });
|
||||
sst.deepEqual(result, { a: [['1', '2', '3', '4', '5', '6']] }, 'a bracketed comma group is a single element');
|
||||
st.test('throws before splitting when a bracketed comma group exceeds arrayLimit', function (sst) {
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1,2,3,4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'),
|
||||
'the inner group is itself an array and is subject to arrayLimit'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('throws before splitting when a comma group under `[]=` exceeds arrayLimit', function (sst) {
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'a bracket-push comma group over the limit throws like the flat form'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1,2', { comma: true, arrayLimit: 1, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
|
||||
'singular message at arrayLimit 1'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[b][]=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'a nested bracket-push key throws'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[][]=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'a doubly bracket-pushed key throws'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=5&a[]=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'an oversized group appended after a scalar throws'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1,2,3,4&a[]=5', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'an oversized group throws even when a later part would fit'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1,2,3,4&a[]=5', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true, duplicates: 'first' });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'throws with duplicates: first'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=5&a[]=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true, duplicates: 'last' });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'throws with duplicates: last'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse({ a: '1,2,3,4' }, { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'an oversized comma value in object input throws'
|
||||
);
|
||||
|
||||
var big = 'a[]=' + new Array(1e5 + 1).join('1,') + '1';
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse(big, { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'a very long bracket-push comma group throws'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('does not throw for a comma group under `[]=` within arrayLimit', function (sst) {
|
||||
sst.deepEqual(
|
||||
qs.parse('a[]=1,2,3', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }),
|
||||
{ a: [['1', '2', '3']] },
|
||||
'an inner group exactly at the limit stays a single nested element'
|
||||
);
|
||||
sst.deepEqual(
|
||||
qs.parse('a[]=1,2,3&a[]=4,5,6&a[]=7', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }),
|
||||
{ a: [['1', '2', '3'], ['4', '5', '6'], '7'] },
|
||||
'each group counts as one element of the outer array'
|
||||
);
|
||||
sst.deepEqual(
|
||||
qs.parse('a[b][]=1,2,3', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }),
|
||||
{ a: { b: [['1', '2', '3']] } },
|
||||
'nested bracket-push key within the limit'
|
||||
);
|
||||
sst.deepEqual(
|
||||
qs.parse({ a: '1,2,3' }, { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }),
|
||||
{ a: ['1', '2', '3'] },
|
||||
'object input within the limit'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('keeps an oversized comma group under `[]=` as a nested array without throwOnLimitExceeded', function (sst) {
|
||||
sst.deepEqual(
|
||||
qs.parse('a[]=1,2,3,4', { comma: true, arrayLimit: 3 }),
|
||||
{ a: [['1', '2', '3', '4']] },
|
||||
'the inner group is not converted to an overflow object'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
|
||||
+317
@@ -136,6 +136,144 @@ test('stringify()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('encodes dot in key of object with a primitive value when encodeDotInKeys and allowDots is provided', function (st) {
|
||||
st.equal(
|
||||
qs.stringify(
|
||||
{ 'name.obj': 'John' },
|
||||
{ allowDots: true, encodeDotInKeys: true }
|
||||
),
|
||||
'name%252Eobj=John',
|
||||
'with allowDots true and encodeDotInKeys true'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify(
|
||||
{ 'name.obj': 'John' },
|
||||
{ allowDots: false, encodeDotInKeys: true }
|
||||
),
|
||||
'name%252Eobj=John',
|
||||
'with allowDots false and encodeDotInKeys true'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify(
|
||||
{ 'name.obj': 'John' },
|
||||
{ encodeDotInKeys: true, allowDots: true, encodeValuesOnly: true }
|
||||
),
|
||||
'name%2Eobj=John',
|
||||
'with encodeValuesOnly true'
|
||||
);
|
||||
|
||||
// With `encodeValuesOnly` the key encoder is skipped, so the dot is encoded once
|
||||
// (`%2E`) rather than twice. That single `%2E` decodes back to a structural dot, so
|
||||
// unlike the default output below this does not round-trip to the original dotted key
|
||||
// (a pre-existing `encodeValuesOnly` + `encodeDotInKeys` limitation, not new here).
|
||||
st.deepEqual(
|
||||
qs.parse(
|
||||
qs.stringify(
|
||||
{ 'name.obj': 'John' },
|
||||
{ encodeDotInKeys: true, allowDots: true, encodeValuesOnly: true }
|
||||
),
|
||||
{ allowDots: true, decodeDotInKeys: true }
|
||||
),
|
||||
{ name: { obj: 'John' } },
|
||||
'with encodeValuesOnly the single-encoded dot decodes structurally (does not round-trip)'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse(
|
||||
qs.stringify({ 'name.obj': 'John' }, { allowDots: true, encodeDotInKeys: true }),
|
||||
{ allowDots: true, decodeDotInKeys: true }
|
||||
),
|
||||
{ 'name.obj': 'John' },
|
||||
'round-trips a dotted key with a primitive value'
|
||||
);
|
||||
|
||||
st.equal(
|
||||
qs.stringify({ 'a.b': null }, { allowDots: true, encodeDotInKeys: true, strictNullHandling: true }),
|
||||
'a%252Eb',
|
||||
'encodes a dotted key with a null value'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ 'a.b': '1', 'c.d': '2' }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb=1&c%252Ed=2',
|
||||
'encodes dots in every top-level key, not just the first'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ 'a.b.c': 'x' }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb%252Ec=x',
|
||||
'encodes every dot in a key'
|
||||
);
|
||||
var primitiveKey = qs.stringify({ 'a.b': 'c' }, { allowDots: true, encodeDotInKeys: true }).split('=')[0];
|
||||
st.equal(
|
||||
qs.stringify({ 'a.b': { x: 'c' } }, { allowDots: true, encodeDotInKeys: true }).indexOf(primitiveKey + '.'),
|
||||
0,
|
||||
'a top-level dotted key encodes identically for primitive and object values'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
// Characterization of the CURRENT (buggy) behavior: with `allowDots` + `encodeDotInKeys`,
|
||||
// `stringify` percent-encodes the structural `.` separators that `allowDots` inserts between
|
||||
// nested keys, not just the literal dots inside a key, which breaks the stringify -> parse
|
||||
// round-trip. These assertions pin that behavior so it cannot change silently: the fix in
|
||||
// https://github.com/ljharb/qs/pull/564 changes every output below, so landing that fix MUST
|
||||
// update this test (that is the point — it forces the behavior change to be explicit).
|
||||
t.test('[characterization] encodeDotInKeys currently over-encodes structural separator dots (pre-#564)', function (st) {
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: { c: 'd' } } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb.c=d',
|
||||
'over-encodes the a->b separator (#564: should become a.b.c=d)'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb%252Ec.d=e',
|
||||
'clobbers every separator but the last (#564: should become a.b.c.d=e)'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ 'a.b': { c: { d: 'e' } } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb%252Ec.d=e',
|
||||
'top-level dotted key: deeper separators also get encoded (#564: should become a%252Eb.c.d=e)'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: { 'b.c': { d: 'e' } } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb%252Ec.d=e',
|
||||
'nested dotted key + object value: the separator around it is encoded (#564: should become a.b%252Ec.d=e)'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: { 'c.d': { e: 'f' } } } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb%252Ec%252Ed.e=f',
|
||||
'deeply nested dotted key: all separators encoded (#564: should become a.b.c%252Ed.e=f)'
|
||||
);
|
||||
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: [1, 2] } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb%5B0%5D=1&a%252Eb%5B1%5D=2',
|
||||
'array value under nested keys: separator encoded (#564: should become a.b%5B0%5D=1&a.b%5B1%5D=2)'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: { 'b.c': [1, 2] } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
'a%252Eb%252Ec%5B0%5D=1&a%252Eb%252Ec%5B1%5D=2',
|
||||
'array value under nested dotted key (#564: should become a.b%252Ec%5B0%5D=1&a.b%252Ec%5B1%5D=2)'
|
||||
);
|
||||
|
||||
st.equal(
|
||||
qs.stringify({ a: { 'b.c': { d: 'e' } } }, { allowDots: false, encodeDotInKeys: true }),
|
||||
'a%5Bb%252Ec%5D%5Bd%5D=e',
|
||||
'allowDots:false object value encodes the nested-key dot, unlike the primitive-value case (#564: should become a%5Bb.c%5D%5Bd%5D=e)'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse(
|
||||
qs.stringify({ a: { b: { c: 'd' } } }, { allowDots: true, encodeDotInKeys: true }),
|
||||
{ allowDots: true, decodeDotInKeys: true }
|
||||
),
|
||||
{ 'a.b': { c: 'd' } },
|
||||
'the over-encoding breaks the round-trip: {a:{b:{c}}} comes back as {"a.b":{c}} (#564 restores it)'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('should encode dot in key of object, and automatically set allowDots to `true` when encodeDotInKeys is true and allowDots in undefined', function (st) {
|
||||
st.equal(
|
||||
qs.stringify(
|
||||
@@ -328,6 +466,39 @@ test('stringify()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allowEmptyArrays only short-circuits arrays with no own keys', function (st) {
|
||||
st.equal(
|
||||
qs.stringify({ a: [] }, { allowEmptyArrays: true }),
|
||||
'a[]',
|
||||
'a genuinely empty array is still emitted as `[]`'
|
||||
);
|
||||
|
||||
var withKey = [];
|
||||
withKey.extra = 'x';
|
||||
st.equal(
|
||||
qs.stringify({ a: withKey }, { allowEmptyArrays: true }),
|
||||
'a%5Bextra%5D=x',
|
||||
'an own key on an empty array is serialized rather than dropped'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: withKey }, { allowEmptyArrays: true }),
|
||||
qs.stringify({ a: withKey }),
|
||||
'the allowEmptyArrays fast path matches the default path when the array has own keys'
|
||||
);
|
||||
|
||||
var container = {};
|
||||
var cyclic = [];
|
||||
cyclic.back = container;
|
||||
container.a = cyclic;
|
||||
st['throws'](
|
||||
function () { qs.stringify(container, { allowEmptyArrays: true }); },
|
||||
RangeError,
|
||||
'a cycle through an empty array with an own key is still detected'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('stringifies an array value with one item vs multiple items', function (st) {
|
||||
st.test('non-array item', function (s2t) {
|
||||
s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a=c');
|
||||
@@ -761,6 +932,33 @@ test('stringify()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('does not throw on a non-callable `constructor.isBuffer` key', function (st) {
|
||||
var input = { a: { constructor: { isBuffer: 'x' } } };
|
||||
st.doesNotThrow(function () { qs.stringify(input); });
|
||||
st.equal(qs.stringify(input), 'a%5Bconstructor%5D%5BisBuffer%5D=x');
|
||||
st.equal(qs.stringify({ a: { constructor: { isBuffer: { b: 'c' } } } }), 'a%5Bconstructor%5D%5BisBuffer%5D%5Bb%5D=c');
|
||||
st.equal(qs.stringify({ a: { constructor: { isBuffer: ['b'] } } }), 'a%5Bconstructor%5D%5BisBuffer%5D%5B0%5D=b');
|
||||
st.equal(qs.stringify({ a: { constructor: { isBuffer: true } } }), 'a%5Bconstructor%5D%5BisBuffer%5D=true');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('round-trips a parsed `constructor[isBuffer]` key', function (st) {
|
||||
var str = 'x%5Bconstructor%5D%5BisBuffer%5D=y';
|
||||
|
||||
var plain = qs.parse(str, { plainObjects: true });
|
||||
st.deepEqual(plain, { __proto__: null, x: { __proto__: null, constructor: { __proto__: null, isBuffer: 'y' } } }, 'plainObjects keeps the key');
|
||||
st.doesNotThrow(function () { qs.stringify(plain); });
|
||||
st.equal(qs.stringify(plain), str, 'plainObjects round-trips');
|
||||
|
||||
var proto = qs.parse(str, { allowPrototypes: true });
|
||||
st.deepEqual(proto, { x: { constructor: { isBuffer: 'y' } } }, 'allowPrototypes keeps the key');
|
||||
st.doesNotThrow(function () { qs.stringify(proto); });
|
||||
st.equal(qs.stringify(proto), str, 'allowPrototypes round-trips');
|
||||
|
||||
st.equal(qs.stringify(qs.parse(str)), '', 'default options drop the key');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('stringifies an object using an alternative delimiter', function (st) {
|
||||
st.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d');
|
||||
st.end();
|
||||
@@ -919,6 +1117,66 @@ test('stringify()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('serializes Date values unless filter transforms them', function (st) {
|
||||
var obj = {
|
||||
a: new Date(Date.UTC(2023, 2, 7, 9, 2, 41, 260)),
|
||||
b: [new Date(Date.UTC(2023, 2, 7, 9, 2, 41, 260))]
|
||||
};
|
||||
var iso = '2023-03-07T09%3A02%3A41.260Z';
|
||||
st.equal(
|
||||
qs.stringify(obj, { filter: function (prefix, value) { return value; } }),
|
||||
'a=' + iso + '&b%5B0%5D=' + iso,
|
||||
'Dates returned unchanged by a filter are serialized'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: new Date(0) }, { filter: function (prefix, value) { return value instanceof Date ? 'kept' : value; } }),
|
||||
'a=kept',
|
||||
'a filter that transforms a Date wins over default serialization'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('applies default Date handling to whatever a filter function returns', function (st) {
|
||||
var date = new Date(Date.UTC(2023, 2, 7, 9, 2, 41, 260));
|
||||
var iso = '2023-03-07T09%3A02%3A41.260Z';
|
||||
var identity = function (prefix, value) { return value; };
|
||||
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: date } }, { filter: identity }),
|
||||
'a%5Bb%5D=' + iso,
|
||||
'a nested Date is serialized through a filter'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify(
|
||||
{ a: date },
|
||||
{ filter: identity, serializeDate: function (d) { return String(d.getTime()); } }
|
||||
),
|
||||
'a=1678179761260',
|
||||
'`serializeDate` is honored after a filter'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: [date, 'x'] }, { filter: identity, arrayFormat: 'comma' }),
|
||||
'a=' + iso + '%2Cx',
|
||||
'Dates inside a comma array are serialized through a filter, not stringified as locale text'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: 'x' }, { filter: function (prefix, value) { return prefix === 'a' ? date : value; } }),
|
||||
'a=' + iso,
|
||||
'a Date produced by the filter is serialized'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: date, b: 1 }, { filter: ['a'] }),
|
||||
'a=' + iso,
|
||||
'an array filter still serializes Dates'
|
||||
);
|
||||
st['throws'](
|
||||
function () { qs.stringify({ a: new Date(NaN) }, { filter: identity }); },
|
||||
RangeError,
|
||||
'an invalid Date through a filter throws like the no-filter path'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('can disable uri encoding', function (st) {
|
||||
st.equal(qs.stringify({ a: 'b' }, { encode: false }), 'a=b');
|
||||
st.equal(qs.stringify({ a: { b: 'c' } }, { encode: false }), 'a[b]=c');
|
||||
@@ -1445,4 +1703,63 @@ test('stringifies empty keys', function (t) {
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('limits nesting depth with the `depth` option', function (st) {
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: { c: 'd' } } }),
|
||||
'a%5Bb%5D%5Bc%5D=d',
|
||||
'the default depth is unlimited and does not alter output'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: { c: 'd' } } }, { depth: 2 }),
|
||||
'a%5Bb%5D%5Bc%5D=d',
|
||||
'does not throw when nesting is within the depth limit'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: 'c' } }, { depth: Infinity }),
|
||||
'a%5Bb%5D=c',
|
||||
'an explicit Infinity depth is unlimited'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: { b: { c: { d: 'e' } } } }, { depth: null }),
|
||||
qs.stringify({ a: { b: { c: { d: 'e' } } } }),
|
||||
'a non-number depth is ignored and treated as unlimited'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: 'b' }, { depth: 0 }),
|
||||
'a=b',
|
||||
'a flat object serializes with a depth of 0'
|
||||
);
|
||||
|
||||
var deep = {};
|
||||
var cursor = deep;
|
||||
for (var i = 0; i < 250; i++) {
|
||||
cursor.a = {};
|
||||
cursor = cursor.a;
|
||||
}
|
||||
cursor.b = 'c';
|
||||
st.equal(typeof qs.stringify(deep), 'string', 'the default depth serializes deeply nested objects without throwing');
|
||||
|
||||
st['throws'](
|
||||
function () { qs.stringify({ a: { b: { c: { d: 'e' } } } }, { depth: 2 }); },
|
||||
RangeError,
|
||||
'throws a RangeError when nesting exceeds the depth limit'
|
||||
);
|
||||
st['throws'](
|
||||
function () { qs.stringify({ a: { b: 'c' } }, { depth: 0 }); },
|
||||
RangeError,
|
||||
'a depth of 0 throws for any nested object'
|
||||
);
|
||||
|
||||
var caught;
|
||||
try {
|
||||
qs.stringify({ a: { b: { c: { d: 'e' } } } }, { depth: 2 });
|
||||
} catch (e) {
|
||||
caught = e;
|
||||
}
|
||||
st.ok(caught instanceof RangeError, 'the thrown value is a RangeError');
|
||||
st.equal(caught.message, 'Input depth exceeded depth option of 2', 'the RangeError names the exceeded depth');
|
||||
|
||||
st.end();
|
||||
});
|
||||
});
|
||||
+12
@@ -604,6 +604,18 @@ test('isBuffer()', function (t) {
|
||||
var fakeBuffer = { constructor: Buffer };
|
||||
t.equal(utils.isBuffer(fakeBuffer), false, 'fake buffer is not a buffer');
|
||||
|
||||
forEach(['x', 1, true, {}, [], { isBuffer: true }], function (notCallable) {
|
||||
var obj = { constructor: { isBuffer: notCallable } };
|
||||
t.doesNotThrow(function () { utils.isBuffer(obj); }, 'non-callable `constructor.isBuffer` (' + inspect(notCallable) + ') does not throw');
|
||||
t.equal(utils.isBuffer(obj), false, 'non-callable `constructor.isBuffer` (' + inspect(notCallable) + ') is not a buffer');
|
||||
});
|
||||
|
||||
var nullObject = { __proto__: null, constructor: { __proto__: null, isBuffer: 'y' } };
|
||||
t.equal(utils.isBuffer(nullObject), false, 'null object with non-callable `constructor.isBuffer` is not a buffer');
|
||||
|
||||
var duckBuffer = { constructor: { isBuffer: function () { return true; } } };
|
||||
t.equal(utils.isBuffer(duckBuffer), true, 'callable `constructor.isBuffer` is still honored');
|
||||
|
||||
var saferBuffer = SaferBuffer.from('abc');
|
||||
t.equal(utils.isBuffer(saferBuffer), true, 'SaferBuffer instance is a buffer');
|
||||
|
||||
|
||||
Reference in new issue
Block a user