Skip to content

Commit febb644

Browse files
committed
[Fix] parse: throw on arrayLimit exceeded with indexed notation when throwOnLimitExceeded is true
Fixes #529
1 parent f6a7abf commit febb644

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

lib/parse.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,17 +187,18 @@ var parseObject = function (chain, val, options, valuesParsed) {
187187
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
188188
var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, '.') : cleanRoot;
189189
var index = parseInt(decodedRoot, 10);
190-
if (!options.parseArrays && decodedRoot === '') {
191-
obj = { 0: leaf };
192-
} else if (
193-
!isNaN(index)
190+
var isValidArrayIndex = !isNaN(index)
194191
&& root !== decodedRoot
195192
&& String(index) === decodedRoot
196193
&& index >= 0
197-
&& (options.parseArrays && index <= options.arrayLimit)
198-
) {
194+
&& options.parseArrays;
195+
if (!options.parseArrays && decodedRoot === '') {
196+
obj = { 0: leaf };
197+
} else if (isValidArrayIndex && index <= options.arrayLimit) {
199198
obj = [];
200199
obj[index] = leaf;
200+
} else if (isValidArrayIndex && options.throwOnLimitExceeded) {
201+
throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
201202
} else if (decodedRoot !== '__proto__') {
202203
obj[decodedRoot] = leaf;
203204
}

test/parse.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,40 @@ test('parse()', function (t) {
11441144
sst.end();
11451145
});
11461146

1147+
st.test('throws error when indexed notation exceeds arrayLimit with throwOnLimitExceeded', function (sst) {
1148+
sst['throws'](
1149+
function () {
1150+
qs.parse('a[1001]=b', { arrayLimit: 1000, throwOnLimitExceeded: true });
1151+
},
1152+
new RangeError('Array limit exceeded. Only 1000 elements allowed in an array.'),
1153+
'throws error for a single index exceeding arrayLimit'
1154+
);
1155+
1156+
sst['throws'](
1157+
function () {
1158+
qs.parse('a[0]=1&a[1]=2&a[2]=3&a[10]=4', { arrayLimit: 6, throwOnLimitExceeded: true, allowSparse: true });
1159+
},
1160+
new RangeError('Array limit exceeded. Only 6 elements allowed in an array.'),
1161+
'throws error when a sparse index exceeds arrayLimit'
1162+
);
1163+
1164+
sst.end();
1165+
});
1166+
1167+
st.test('does not throw for indexed notation within arrayLimit with throwOnLimitExceeded', function (sst) {
1168+
var result = qs.parse('a[4]=b', { arrayLimit: 5, throwOnLimitExceeded: true, allowSparse: true });
1169+
sst.ok(Array.isArray(result.a), 'result is an array');
1170+
sst.equal(result.a.length, 5, 'array has correct length');
1171+
sst.equal(result.a[4], 'b', 'value at index 4 is correct');
1172+
sst.end();
1173+
});
1174+
1175+
st.test('silently converts to object for indexed notation exceeding arrayLimit without throwOnLimitExceeded', function (sst) {
1176+
var result = qs.parse('a[1001]=b', { arrayLimit: 1000 });
1177+
sst.deepEqual(result, { a: { 1001: 'b' } }, 'converts to object without throwing');
1178+
sst.end();
1179+
});
1180+
11471181
st.end();
11481182
});
11491183

0 commit comments

Comments
 (0)