Comparing version 6.12.3 to 6.13.0
@@ -0,1 +1,5 @@ | ||
## **6.13.0** | ||
- [New] `parse`: add `strictDepth` option (#511) | ||
- [Tests] use `npm audit` instead of `aud` | ||
## **6.12.3** | ||
@@ -2,0 +6,0 @@ - [Fix] `parse`: properly account for `strictNullHandling` when `allowEmptyArrays` |
@@ -8,3 +8,3 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Qs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||
},{"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,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("]="),y=-1===u?d.indexOf("="):u+1;-1===y?(p=t.decoder(d,defaults.decoder,n,"key"),c=t.strictNullHandling?null:""):(p=t.decoder(d.slice(0,y),defaults.decoder,n,"key"),c=utils.maybeMap(parseArrayValue(d.slice(y+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 f=has.call(r,p);f&&"combine"===t.duplicates?r[p]=utils.combine(r[p],c):f&&"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])}return l&&n.push("["+i.slice(l.index)+"]"),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,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)}; | ||
"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)}; | ||
@@ -11,0 +11,0 @@ },{"5":5}],4:[function(require,module,exports){ |
@@ -27,2 +27,3 @@ 'use strict'; | ||
plainObjects: false, | ||
strictDepth: false, | ||
strictNullHandling: false | ||
@@ -205,5 +206,8 @@ }; | ||
// If there's a remainder, just add whatever is left | ||
// If there's a remainder, check strictDepth option for throw, else just add whatever is left | ||
if (segment) { | ||
if (options.strictDepth === true) { | ||
throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true'); | ||
} | ||
keys.push('[' + key.slice(segment.index) + ']'); | ||
@@ -265,2 +269,3 @@ } | ||
plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects, | ||
strictDepth: typeof opts.strictDepth === 'boolean' ? !!opts.strictDepth : defaults.strictDepth, | ||
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling | ||
@@ -267,0 +272,0 @@ }; |
@@ -5,3 +5,3 @@ { | ||
"homepage": "https://github.com/ljharb/qs", | ||
"version": "6.12.3", | ||
"version": "6.13.0", | ||
"repository": { | ||
@@ -41,3 +41,2 @@ "type": "git", | ||
"@ljharb/eslint-config": "^21.1.1", | ||
"aud": "^2.0.4", | ||
"browserify": "^16.5.2", | ||
@@ -77,3 +76,3 @@ "bundle-collapser": "^1.4.0", | ||
"tests-only": "nyc tape 'test/**/*.js'", | ||
"posttest": "aud --production", | ||
"posttest": "npx npm@'>=10.2' audit --production", | ||
"readme": "evalmd README.md", | ||
@@ -80,0 +79,0 @@ "postlint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)", |
@@ -118,4 +118,15 @@ <p align="center"> | ||
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. | ||
You can configure **qs** to throw an error when parsing nested input beyond this depth using the `strictDepth` option (defaulted to false): | ||
```javascript | ||
try { | ||
qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true }); | ||
} catch (err) { | ||
assert(err instanceof RangeError); | ||
assert.strictEqual(err.message, 'Input depth exceeded depth option of 1 and strictDepth is true'); | ||
} | ||
``` | ||
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. | ||
For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option: | ||
@@ -122,0 +133,0 @@ |
@@ -1071,1 +1071,101 @@ 'use strict'; | ||
}); | ||
test('qs strictDepth option - throw cases', function (t) { | ||
t.test('throws an exception when depth exceeds the limit with strictDepth: true', function (st) { | ||
st['throws']( | ||
function () { | ||
qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true }); | ||
}, | ||
RangeError, | ||
'Should throw RangeError' | ||
); | ||
st.end(); | ||
}); | ||
t.test('throws an exception for multiple nested arrays with strictDepth: true', function (st) { | ||
st['throws']( | ||
function () { | ||
qs.parse('a[0][1][2][3][4]=b', { depth: 3, strictDepth: true }); | ||
}, | ||
RangeError, | ||
'Should throw RangeError' | ||
); | ||
st.end(); | ||
}); | ||
t.test('throws an exception for nested objects and arrays with strictDepth: true', function (st) { | ||
st['throws']( | ||
function () { | ||
qs.parse('a[b][c][0][d][e]=f', { depth: 3, strictDepth: true }); | ||
}, | ||
RangeError, | ||
'Should throw RangeError' | ||
); | ||
st.end(); | ||
}); | ||
t.test('throws an exception for different types of values with strictDepth: true', function (st) { | ||
st['throws']( | ||
function () { | ||
qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 3, strictDepth: true }); | ||
}, | ||
RangeError, | ||
'Should throw RangeError' | ||
); | ||
st.end(); | ||
}); | ||
}); | ||
test('qs strictDepth option - non-throw cases', function (t) { | ||
t.test('when depth is 0 and strictDepth true, do not throw', function (st) { | ||
st.doesNotThrow( | ||
function () { | ||
qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 0, strictDepth: true }); | ||
}, | ||
RangeError, | ||
'Should not throw RangeError' | ||
); | ||
st.end(); | ||
}); | ||
t.test('parses successfully when depth is within the limit with strictDepth: true', function (st) { | ||
st.doesNotThrow( | ||
function () { | ||
var result = qs.parse('a[b]=c', { depth: 1, strictDepth: true }); | ||
st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly'); | ||
} | ||
); | ||
st.end(); | ||
}); | ||
t.test('does not throw an exception when depth exceeds the limit with strictDepth: false', function (st) { | ||
st.doesNotThrow( | ||
function () { | ||
var result = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 }); | ||
st.deepEqual(result, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }, 'Should parse with depth limit'); | ||
} | ||
); | ||
st.end(); | ||
}); | ||
t.test('parses successfully when depth is within the limit with strictDepth: false', function (st) { | ||
st.doesNotThrow( | ||
function () { | ||
var result = qs.parse('a[b]=c', { depth: 1 }); | ||
st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly'); | ||
} | ||
); | ||
st.end(); | ||
}); | ||
t.test('does not throw when depth is exactly at the limit with strictDepth: true', function (st) { | ||
st.doesNotThrow( | ||
function () { | ||
var result = qs.parse('a[b][c]=d', { depth: 2, strictDepth: true }); | ||
st.deepEqual(result, { a: { b: { c: 'd' } } }, 'Should parse correctly'); | ||
} | ||
); | ||
st.end(); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
253581
29
3486
710