Skip to content

Commit ff235b4

Browse files
committed
v6.3.3
1 parent 4310742 commit ff235b4

File tree

4 files changed

+63
-33
lines changed

4 files changed

+63
-33
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
## **6.3.3**
2+
- [Fix] `parse`: ignore `__proto__` keys (#428)
3+
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
4+
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
5+
- [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
6+
- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279)
7+
- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
8+
- [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
9+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
10+
- [Refactor] use cached `Array.isArray`
11+
- [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269)
12+
- [Docs] Clarify the need for "arrayLimit" option
13+
- [meta] fix README.md (#399)
14+
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
15+
- [meta] add FUNDING.yml
16+
- [actions] backport actions from main
17+
- [Tests] use `safer-buffer` instead of `Buffer` constructor
18+
- [Tests] remove nonexistent tape option
19+
- [Dev Deps] backport from main
20+
121
## **6.3.2**
222
- [Fix] follow `allowPrototypes` option during merge (#201, #200)
323
- [Dev Deps] update `eslint`

component.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "qs",
33
"repository": "hapijs/qs",
44
"description": "query-string parser / stringifier with nesting support",
5-
"version": "6.3.2",
5+
"version": "6.3.3",
66
"keywords": ["querystring", "query", "parser"],
77
"main": "lib/index.js",
88
"scripts": [

dist/qs.js

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module.exports = {
1111
return replace.call(value, percentTwenties, '+');
1212
},
1313
RFC3986: function (value) {
14-
return value;
14+
return String(value);
1515
}
1616
},
1717
RFC1738: 'RFC1738',
@@ -102,7 +102,7 @@ var parseObject = function parseObjectRecursive(chain, val, options) {
102102
) {
103103
obj = [];
104104
obj[index] = parseObject(chain, val, options);
105-
} else {
105+
} else if (cleanRoot !== '__proto__') {
106106
obj[cleanRoot] = parseObject(chain, val, options);
107107
}
108108
}
@@ -132,8 +132,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
132132

133133
var keys = [];
134134
if (parent) {
135-
// If we aren't using plain objects, optionally prefix keys
136-
// that would overwrite object prototype properties
135+
// If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
137136
if (!options.plainObjects && has.call(Object.prototype, parent)) {
138137
if (!options.allowPrototypes) {
139138
return;
@@ -209,31 +208,37 @@ var utils = require('./utils');
209208
var formats = require('./formats');
210209

211210
var arrayPrefixGenerators = {
212-
brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
211+
brackets: function brackets(prefix) {
213212
return prefix + '[]';
214213
},
215-
indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
214+
indices: function indices(prefix, key) {
216215
return prefix + '[' + key + ']';
217216
},
218-
repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
217+
repeat: function repeat(prefix) {
219218
return prefix;
220219
}
221220
};
222221

222+
var isArray = Array.isArray;
223+
var push = Array.prototype.push;
224+
var pushToArray = function (arr, valueOrArray) {
225+
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
226+
};
227+
223228
var toISO = Date.prototype.toISOString;
224229

225230
var defaults = {
226231
delimiter: '&',
227232
encode: true,
228233
encoder: utils.encode,
229-
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
234+
serializeDate: function serializeDate(date) {
230235
return toISO.call(date);
231236
},
232237
skipNulls: false,
233238
strictNullHandling: false
234239
};
235240

236-
var stringify = function stringify( // eslint-disable-line func-name-matching
241+
var stringify = function stringify(
237242
object,
238243
prefix,
239244
generateArrayPrefix,
@@ -251,7 +256,9 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
251256
obj = filter(prefix, obj);
252257
} else if (obj instanceof Date) {
253258
obj = serializeDate(obj);
254-
} else if (obj === null) {
259+
}
260+
261+
if (obj === null) {
255262
if (strictNullHandling) {
256263
return encoder ? encoder(prefix) : prefix;
257264
}
@@ -273,7 +280,7 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
273280
}
274281

275282
var objKeys;
276-
if (Array.isArray(filter)) {
283+
if (isArray(filter)) {
277284
objKeys = filter;
278285
} else {
279286
var keys = Object.keys(obj);
@@ -287,8 +294,8 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
287294
continue;
288295
}
289296

290-
if (Array.isArray(obj)) {
291-
values = values.concat(stringify(
297+
if (isArray(obj)) {
298+
pushToArray(values, stringify(
292299
obj[key],
293300
generateArrayPrefix(prefix, key),
294301
generateArrayPrefix,
@@ -302,7 +309,7 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
302309
formatter
303310
));
304311
} else {
305-
values = values.concat(stringify(
312+
pushToArray(values, stringify(
306313
obj[key],
307314
prefix + (allowDots ? '.' + key : '[' + key + ']'),
308315
generateArrayPrefix,
@@ -325,20 +332,20 @@ module.exports = function (object, opts) {
325332
var obj = object;
326333
var options = opts || {};
327334

328-
if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
335+
if (options.encoder !== null && typeof options.encoder !== 'undefined' && typeof options.encoder !== 'function') {
329336
throw new TypeError('Encoder has to be a function.');
330337
}
331338

332339
var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
333340
var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
334341
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
335342
var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
336-
var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
343+
var encoder = encode ? typeof options.encoder === 'function' ? options.encoder : defaults.encoder : null;
337344
var sort = typeof options.sort === 'function' ? options.sort : null;
338345
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
339346
var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
340347
if (typeof options.format === 'undefined') {
341-
options.format = formats.default;
348+
options.format = formats['default'];
342349
} else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
343350
throw new TypeError('Unknown format option provided.');
344351
}
@@ -349,7 +356,7 @@ module.exports = function (object, opts) {
349356
if (typeof options.filter === 'function') {
350357
filter = options.filter;
351358
obj = filter('', obj);
352-
} else if (Array.isArray(options.filter)) {
359+
} else if (isArray(options.filter)) {
353360
filter = options.filter;
354361
objKeys = filter;
355362
}
@@ -385,8 +392,7 @@ module.exports = function (object, opts) {
385392
if (skipNulls && obj[key] === null) {
386393
continue;
387394
}
388-
389-
keys = keys.concat(stringify(
395+
pushToArray(keys, stringify(
390396
obj[key],
391397
key,
392398
generateArrayPrefix,
@@ -437,8 +443,8 @@ exports.merge = function (target, source, options) {
437443
if (typeof source !== 'object') {
438444
if (Array.isArray(target)) {
439445
target.push(source);
440-
} else if (typeof target === 'object') {
441-
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
446+
} else if (target && typeof target === 'object') {
447+
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
442448
target[source] = true;
443449
}
444450
} else {
@@ -448,7 +454,7 @@ exports.merge = function (target, source, options) {
448454
return target;
449455
}
450456

451-
if (typeof target !== 'object') {
457+
if (!target || typeof target !== 'object') {
452458
return [target].concat(source);
453459
}
454460

@@ -506,13 +512,13 @@ exports.encode = function (str) {
506512
var c = string.charCodeAt(i);
507513

508514
if (
509-
c === 0x2D || // -
510-
c === 0x2E || // .
511-
c === 0x5F || // _
512-
c === 0x7E || // ~
513-
(c >= 0x30 && c <= 0x39) || // 0-9
514-
(c >= 0x41 && c <= 0x5A) || // a-z
515-
(c >= 0x61 && c <= 0x7A) // A-Z
515+
c === 0x2D // -
516+
|| c === 0x2E // .
517+
|| c === 0x5F // _
518+
|| c === 0x7E // ~
519+
|| (c >= 0x30 && c <= 0x39) // 0-9
520+
|| (c >= 0x41 && c <= 0x5A) // a-z
521+
|| (c >= 0x61 && c <= 0x7A) // A-Z
516522
) {
517523
out += string.charAt(i);
518524
continue;
@@ -535,7 +541,11 @@ exports.encode = function (str) {
535541

536542
i += 1;
537543
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
538-
out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; // eslint-disable-line max-len
544+
/* eslint operator-linebreak: [2, "before"] */
545+
out += hexTable[0xF0 | (c >> 18)]
546+
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
547+
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
548+
+ hexTable[0x80 | (c & 0x3F)];
539549
}
540550

541551
return out;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "qs",
33
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
44
"homepage": "https://github.com/ljharb/qs",
5-
"version": "6.3.2",
5+
"version": "6.3.3",
66
"repository": {
77
"type": "git",
88
"url": "https://github.com/ljharb/qs.git"

0 commit comments

Comments
 (0)