Socket
Socket
Sign inDemoInstall

qs

Package Overview
Dependencies
0
Maintainers
2
Versions
110
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 6.2.3 to 6.2.4

.editorconfig

17

CHANGELOG.md

@@ -0,1 +1,18 @@

## **6.2.4**
- [Fix] `parse`: ignore `__proto__` keys (#428)
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source
- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
- [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
- [Refactor] use cached `Array.isArray`
- [Docs] Clarify the need for "arrayLimit" option
- [meta] fix README.md (#399)
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
- [meta] add FUNDING.yml
- [actions] backport actions from main
- [Tests] use `safer-buffer` instead of `Buffer` constructor
- [Tests] remove nonexistent tape option
- [Dev Deps] backport from main
## **6.2.3**

@@ -2,0 +19,0 @@ - [Fix] follow `allowPrototypes` option during merge (#201, #200)

157

dist/qs.js

@@ -1,2 +0,2 @@

(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 e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(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){
'use strict';

@@ -65,3 +65,3 @@

var obj;
if (root === '[]') {
if (root === '[]' && options.parseArrays) {
obj = [];

@@ -73,12 +73,14 @@ obj = obj.concat(parseObject(chain, val, options));

var index = parseInt(cleanRoot, 10);
if (
!isNaN(index) &&
root !== cleanRoot &&
String(index) === cleanRoot &&
index >= 0 &&
(options.parseArrays && index <= options.arrayLimit)
if (!options.parseArrays && cleanRoot === '') {
obj = { 0: val };
} else if (
!isNaN(index)
&& root !== cleanRoot
&& String(index) === cleanRoot
&& index >= 0
&& (options.parseArrays && index <= options.arrayLimit)
) {
obj = [];
obj[index] = parseObject(chain, val, options);
} else {
} else if (cleanRoot !== '__proto__') {
obj[cleanRoot] = parseObject(chain, val, options);

@@ -113,4 +115,3 @@ }

if (parent) {
// If we aren't using plain objects, optionally prefix keys
// that would overwrite object prototype properties
// If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
if (!options.plainObjects && has.call(Object.prototype, parent)) {

@@ -209,3 +210,14 @@ if (!options.allowPrototypes) {

var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
var isArray = Array.isArray;
var stringify = function stringify(
object,
prefix,
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
) {
var obj = object;

@@ -238,3 +250,3 @@ if (typeof filter === 'function') {

var objKeys;
if (Array.isArray(filter)) {
if (isArray(filter)) {
objKeys = filter;

@@ -253,6 +265,26 @@ } else {

if (Array.isArray(obj)) {
values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
if (isArray(obj)) {
values = values.concat(stringify(
obj[key],
generateArrayPrefix(prefix, key),
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
));
} else {
values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
values = values.concat(stringify(
obj[key],
prefix + (allowDots ? '.' + key : '[' + key + ']'),
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
));
}

@@ -271,3 +303,3 @@ }

var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
var encoder = encode ? typeof options.encoder === 'function' ? options.encoder : defaults.encoder : null;
var sort = typeof options.sort === 'function' ? options.sort : null;

@@ -278,3 +310,3 @@ var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;

if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
if (options.encoder !== null && typeof options.encoder !== 'undefined' && typeof options.encoder !== 'function') {
throw new TypeError('Encoder has to be a function.');

@@ -286,4 +318,5 @@ }

obj = filter('', obj);
} else if (Array.isArray(options.filter)) {
objKeys = filter = options.filter;
} else if (isArray(options.filter)) {
objKeys = options.filter;
filter = options.filter;
}

@@ -323,3 +356,13 @@

keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
keys = keys.concat(stringify(
obj[key],
key,
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
));
}

@@ -345,3 +388,3 @@

exports.arrayToObject = function (source, options) {
var obj = options.plainObjects ? Object.create(null) : {};
var obj = options && options.plainObjects ? Object.create(null) : {};
for (var i = 0; i < source.length; ++i) {

@@ -356,3 +399,17 @@ if (typeof source[i] !== 'undefined') {

exports.merge = function (target, source, options) {
var isArray = Array.isArray;
var arrayToObject = function arrayToObject(source, options) {
var obj = options && options.plainObjects ? Object.create(null) : {};
for (var i = 0; i < source.length; ++i) {
if (typeof source[i] !== 'undefined') {
obj[i] = source[i];
}
}
return obj;
};
exports.merge = function merge(target, source, options) {
/* eslint no-param-reassign: 0 */
if (!source) {

@@ -363,6 +420,6 @@ return target;

if (typeof source !== 'object') {
if (Array.isArray(target)) {
if (isArray(target)) {
target.push(source);
} else if (typeof target === 'object') {
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
} else if (target && typeof target === 'object') {
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
target[source] = true;

@@ -377,3 +434,3 @@ }

if (typeof target !== 'object') {
if (!target || typeof target !== 'object') {
return [target].concat(source);

@@ -383,6 +440,22 @@ }

var mergeTarget = target;
if (Array.isArray(target) && !Array.isArray(source)) {
mergeTarget = exports.arrayToObject(target, options);
if (isArray(target) && !isArray(source)) {
mergeTarget = arrayToObject(target, options);
}
if (isArray(target) && isArray(source)) {
source.forEach(function (item, i) {
if (has.call(target, i)) {
var targetItem = target[i];
if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
target[i] = merge(targetItem, item, options);
} else {
target.push(item);
}
} else {
target[i] = item;
}
});
return target;
}
return Object.keys(source).reduce(function (acc, key) {

@@ -392,3 +465,3 @@ var value = source[key];

if (has.call(acc, key)) {
acc[key] = exports.merge(acc[key], value, options);
acc[key] = merge(acc[key], value, options);
} else {

@@ -423,9 +496,9 @@ acc[key] = value;

if (
c === 0x2D || // -
c === 0x2E || // .
c === 0x5F || // _
c === 0x7E || // ~
(c >= 0x30 && c <= 0x39) || // 0-9
(c >= 0x41 && c <= 0x5A) || // a-z
(c >= 0x61 && c <= 0x7A) // A-Z
c === 0x2D // -
|| c === 0x2E // .
|| c === 0x5F // _
|| c === 0x7E // ~
|| (c >= 0x30 && c <= 0x39) // 0-9
|| (c >= 0x41 && c <= 0x5A) // a-z
|| (c >= 0x61 && c <= 0x7A) // A-Z
) {

@@ -453,3 +526,7 @@ out += string.charAt(i);

c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
/* eslint operator-linebreak: [2, "before"] */
out += hexTable[0xF0 | (c >> 18)]
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
+ hexTable[0x80 | (c & 0x3F)];
}

@@ -473,3 +550,3 @@

if (Array.isArray(obj)) {
if (isArray(obj)) {
var compacted = [];

@@ -510,2 +587,2 @@

},{}]},{},[1])(1)
});
});

@@ -53,3 +53,3 @@ 'use strict';

var obj;
if (root === '[]') {
if (root === '[]' && options.parseArrays) {
obj = [];

@@ -61,12 +61,14 @@ obj = obj.concat(parseObject(chain, val, options));

var index = parseInt(cleanRoot, 10);
if (
!isNaN(index) &&
root !== cleanRoot &&
String(index) === cleanRoot &&
index >= 0 &&
(options.parseArrays && index <= options.arrayLimit)
if (!options.parseArrays && cleanRoot === '') {
obj = { 0: val };
} else if (
!isNaN(index)
&& root !== cleanRoot
&& String(index) === cleanRoot
&& index >= 0
&& (options.parseArrays && index <= options.arrayLimit)
) {
obj = [];
obj[index] = parseObject(chain, val, options);
} else {
} else if (cleanRoot !== '__proto__') {
obj[cleanRoot] = parseObject(chain, val, options);

@@ -101,4 +103,3 @@ }

if (parent) {
// If we aren't using plain objects, optionally prefix keys
// that would overwrite object prototype properties
// If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
if (!options.plainObjects && has.call(Object.prototype, parent)) {

@@ -105,0 +106,0 @@ if (!options.allowPrototypes) {

@@ -25,3 +25,14 @@ 'use strict';

var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
var isArray = Array.isArray;
var stringify = function stringify(
object,
prefix,
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
) {
var obj = object;

@@ -54,3 +65,3 @@ if (typeof filter === 'function') {

var objKeys;
if (Array.isArray(filter)) {
if (isArray(filter)) {
objKeys = filter;

@@ -69,6 +80,26 @@ } else {

if (Array.isArray(obj)) {
values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
if (isArray(obj)) {
values = values.concat(stringify(
obj[key],
generateArrayPrefix(prefix, key),
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
));
} else {
values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
values = values.concat(stringify(
obj[key],
prefix + (allowDots ? '.' + key : '[' + key + ']'),
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
));
}

@@ -87,3 +118,3 @@ }

var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
var encoder = encode ? typeof options.encoder === 'function' ? options.encoder : defaults.encoder : null;
var sort = typeof options.sort === 'function' ? options.sort : null;

@@ -94,3 +125,3 @@ var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;

if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
if (options.encoder !== null && typeof options.encoder !== 'undefined' && typeof options.encoder !== 'function') {
throw new TypeError('Encoder has to be a function.');

@@ -102,4 +133,5 @@ }

obj = filter('', obj);
} else if (Array.isArray(options.filter)) {
objKeys = filter = options.filter;
} else if (isArray(options.filter)) {
objKeys = options.filter;
filter = options.filter;
}

@@ -139,3 +171,13 @@

keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
keys = keys.concat(stringify(
obj[key],
key,
generateArrayPrefix,
strictNullHandling,
skipNulls,
encoder,
filter,
sort,
allowDots
));
}

@@ -142,0 +184,0 @@

@@ -15,3 +15,3 @@ 'use strict';

exports.arrayToObject = function (source, options) {
var obj = options.plainObjects ? Object.create(null) : {};
var obj = options && options.plainObjects ? Object.create(null) : {};
for (var i = 0; i < source.length; ++i) {

@@ -26,3 +26,17 @@ if (typeof source[i] !== 'undefined') {

exports.merge = function (target, source, options) {
var isArray = Array.isArray;
var arrayToObject = function arrayToObject(source, options) {
var obj = options && options.plainObjects ? Object.create(null) : {};
for (var i = 0; i < source.length; ++i) {
if (typeof source[i] !== 'undefined') {
obj[i] = source[i];
}
}
return obj;
};
exports.merge = function merge(target, source, options) {
/* eslint no-param-reassign: 0 */
if (!source) {

@@ -33,6 +47,6 @@ return target;

if (typeof source !== 'object') {
if (Array.isArray(target)) {
if (isArray(target)) {
target.push(source);
} else if (typeof target === 'object') {
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
} else if (target && typeof target === 'object') {
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
target[source] = true;

@@ -47,3 +61,3 @@ }

if (typeof target !== 'object') {
if (!target || typeof target !== 'object') {
return [target].concat(source);

@@ -53,6 +67,22 @@ }

var mergeTarget = target;
if (Array.isArray(target) && !Array.isArray(source)) {
mergeTarget = exports.arrayToObject(target, options);
if (isArray(target) && !isArray(source)) {
mergeTarget = arrayToObject(target, options);
}
if (isArray(target) && isArray(source)) {
source.forEach(function (item, i) {
if (has.call(target, i)) {
var targetItem = target[i];
if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
target[i] = merge(targetItem, item, options);
} else {
target.push(item);
}
} else {
target[i] = item;
}
});
return target;
}
return Object.keys(source).reduce(function (acc, key) {

@@ -62,3 +92,3 @@ var value = source[key];

if (has.call(acc, key)) {
acc[key] = exports.merge(acc[key], value, options);
acc[key] = merge(acc[key], value, options);
} else {

@@ -93,9 +123,9 @@ acc[key] = value;

if (
c === 0x2D || // -
c === 0x2E || // .
c === 0x5F || // _
c === 0x7E || // ~
(c >= 0x30 && c <= 0x39) || // 0-9
(c >= 0x41 && c <= 0x5A) || // a-z
(c >= 0x61 && c <= 0x7A) // A-Z
c === 0x2D // -
|| c === 0x2E // .
|| c === 0x5F // _
|| c === 0x7E // ~
|| (c >= 0x30 && c <= 0x39) // 0-9
|| (c >= 0x41 && c <= 0x5A) // a-z
|| (c >= 0x61 && c <= 0x7A) // A-Z
) {

@@ -123,3 +153,7 @@ out += string.charAt(i);

c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
/* eslint operator-linebreak: [2, "before"] */
out += hexTable[0xF0 | (c >> 18)]
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
+ hexTable[0x80 | (c & 0x3F)];
}

@@ -143,3 +177,3 @@

if (Array.isArray(obj)) {
if (isArray(obj)) {
var compacted = [];

@@ -146,0 +180,0 @@

{
"name": "qs",
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
"homepage": "https://github.com/ljharb/qs",
"version": "6.2.3",
"repository": {
"type": "git",
"url": "https://github.com/ljharb/qs.git"
},
"main": "lib/index.js",
"contributors": [
{
"name": "Jordan Harband",
"email": "ljharb@gmail.com",
"url": "http://ljharb.codes"
}
],
"keywords": [
"querystring",
"qs"
],
"engines": {
"node": ">=0.6"
},
"dependencies": {},
"devDependencies": {
"browserify": "^13.0.1",
"tape": "^4.6.0",
"covert": "^1.1.0",
"mkdirp": "^0.5.1",
"eslint": "^3.1.0",
"@ljharb/eslint-config": "^6.0.0",
"parallelshell": "^2.0.0",
"iconv-lite": "^0.4.13",
"qs-iconv": "^1.0.3",
"evalmd": "^0.0.17"
},
"scripts": {
"pretest": "npm run --silent readme && npm run --silent lint",
"test": "npm run --silent coverage",
"tests-only": "node test",
"readme": "evalmd README.md",
"lint": "eslint lib/*.js text/*.js",
"coverage": "covert test",
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js",
"prepublish": "npm run dist"
},
"license": "BSD-3-Clause"
"name": "qs",
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
"homepage": "https://github.com/ljharb/qs",
"version": "6.2.4",
"repository": {
"type": "git",
"url": "https://github.com/ljharb/qs.git"
},
"main": "lib/index.js",
"contributors": [
{
"name": "Jordan Harband",
"email": "ljharb@gmail.com",
"url": "http://ljharb.codes"
}
],
"keywords": [
"querystring",
"qs"
],
"engines": {
"node": ">=0.6"
},
"devDependencies": {
"@ljharb/eslint-config": "^20.1.0",
"aud": "^1.1.5",
"browserify": "^16.5.2",
"eclint": "^2.8.1",
"eslint": "^8.6.0",
"evalmd": "^0.0.17",
"iconv-lite": "^0.4.24",
"in-publish": "^2.0.1",
"mkdirp": "^0.5.1",
"nyc": "^10.3.2",
"qs-iconv": "^1.0.4",
"safe-publish-latest": "^2.0.0",
"safer-buffer": "^2.1.2",
"tape": "^5.4.0"
},
"scripts": {
"prepublishOnly": "safe-publish-latest && npm run dist",
"prepublish": "not-in-publish || npm run prepublishOnly",
"pretest": "npm run --silent readme && npm run --silent lint",
"test": "npm run --silent tests-only",
"tests-only": "nyc tape 'test/**/*.js'",
"posttest": "aud --production",
"readme": "evalmd README.md",
"postlint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')",
"lint": "eslint --ext=js,mjs .",
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
},
"license": "BSD-3-Clause"
}

@@ -172,3 +172,3 @@ # qs

**qs** will also limit specifying indices in an array to a maximum index of `20`. Any array members with an index of greater than `20` will
instead be converted to an object with the index as the key:
instead be converted to an object with the index as the key. This is needed to handle cases when someone sent, for example, `a[999999999]` and it will take significant time to iterate over this huge array.

@@ -249,2 +249,26 @@ ```javascript

You can encode keys and values using different logic by using the type argument provided to the encoder:
```javascript
var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) {
if (type === 'key') {
return // Encoded key
} else if (type === 'value') {
return // Encoded value
}
}})
```
The type argument is also provided to the decoder:
```javascript
var decoded = qs.parse('x=z', { decoder: function (str, defaultDecoder, charset, type) {
if (type === 'key') {
return // Decoded key
} else if (type === 'value') {
return // Decoded value
}
}})
```
Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.

@@ -361,3 +385,3 @@

By default the encoding and decoding of characters is done in `utf-8`. If you
By default the encoding and decoding of characters is done in `utf-8`. If you
wish to encode querystrings to a different character set (i.e.

@@ -364,0 +388,0 @@ [Shift JIS](https://en.wikipedia.org/wiki/Shift_JIS)) you can use the

@@ -0,1 +1,3 @@

'use strict';
require('./parse');

@@ -2,0 +4,0 @@

@@ -6,6 +6,7 @@ 'use strict';

var iconv = require('iconv-lite');
var SaferBuffer = require('safer-buffer').Buffer;
test('parse()', function (t) {
t.test('parses a simple string', function (st) {
st.deepEqual(qs.parse('0=foo'), { '0': 'foo' });
st.deepEqual(qs.parse('0=foo'), { 0: 'foo' });
st.deepEqual(qs.parse('foo=c++'), { foo: 'c ' });

@@ -88,3 +89,3 @@ st.deepEqual(qs.parse('a[>=]=23'), { a: { '>=': '23' } });

st.deepEqual(qs.parse('a[20]=a'), { a: ['a'] });
st.deepEqual(qs.parse('a[21]=a'), { a: { '21': 'a' } });
st.deepEqual(qs.parse('a[21]=a'), { a: { 21: 'a' } });
st.end();

@@ -120,7 +121,7 @@ });

t.test('transforms arrays to objects', function (st) {
st.deepEqual(qs.parse('foo[0]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
st.deepEqual(qs.parse('foo[bad]=baz&foo[0]=bar'), { foo: { bad: 'baz', '0': 'bar' } });
st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar'), { foo: { bad: 'baz', '0': 'bar' } });
st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
st.deepEqual(qs.parse('foo[0]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } });
st.deepEqual(qs.parse('foo[bad]=baz&foo[0]=bar'), { foo: { bad: 'baz', 0: 'bar' } });
st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar'), { foo: { bad: 'baz', 0: 'bar' } });
st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } });
st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } });
st.deepEqual(qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb'), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });

@@ -141,6 +142,6 @@

st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15', '16'], bar: '2' }] });
st.deepEqual(qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar' } });
st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar' } });
st.deepEqual(qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true }), { foo: { '0': 'bar', bad: 'baz' } });
st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
st.deepEqual(qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } });
st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } });
st.deepEqual(qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true }), { foo: { 0: 'bar', bad: 'baz' } });
st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } });
st.deepEqual(qs.parse('foo[0].a=a&foo[0].b=b&foo[1].a=aa&foo[1].b=bb', { allowDots: true }), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });

@@ -151,3 +152,3 @@ st.end();

t.test('correctly prunes undefined values when converting an array to an object', function (st) {
st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { '2': 'b', '99999999': 'c' } });
st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { 2: 'b', 99999999: 'c' } });
st.end();

@@ -164,3 +165,3 @@ });

t.test('doesn\'t produce empty keys', function (st) {
st.deepEqual(qs.parse('_r=1&'), { '_r': '1' });
st.deepEqual(qs.parse('_r=1&'), { _r: '1' });
st.end();

@@ -230,3 +231,3 @@ });

t.test('parses buffers correctly', function (st) {
var b = new Buffer('test');
var b = SaferBuffer.from('test');
st.deepEqual(qs.parse({ a: b }), { a: b });

@@ -237,4 +238,4 @@ st.end();

t.test('continues parsing when no parent is found', function (st) {
st.deepEqual(qs.parse('[]=&a=b'), { '0': '', a: 'b' });
st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { '0': null, a: 'b' });
st.deepEqual(qs.parse('[]=&a=b'), { 0: '', a: 'b' });
st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { 0: null, a: 'b' });
st.deepEqual(qs.parse('[foo]=bar'), { foo: 'bar' });

@@ -255,3 +256,3 @@ st.end();

t.test('should not throw when a native prototype has an enumerable property', { parallel: false }, function (st) {
t.test('should not throw when a native prototype has an enumerable property', function (st) {
Object.prototype.crash = '';

@@ -294,5 +295,5 @@ Array.prototype.crash = '';

t.test('allows overriding array limit', function (st) {
st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { '0': 'b' } });
st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { 0: 'b' } });
st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: -1 }), { a: { '-1': 'b' } });
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { '0': 'b', '1': 'c' } });
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } });
st.end();

@@ -302,3 +303,10 @@ });

t.test('allows disabling array parsing', function (st) {
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { parseArrays: false }), { a: { '0': 'b', '1': 'c' } });
var indices = qs.parse('a[0]=b&a[1]=c', { parseArrays: false });
st.deepEqual(indices, { a: { 0: 'b', 1: 'c' } });
st.equal(Array.isArray(indices.a), false, 'parseArrays:false, indices case is not an array');
var emptyBrackets = qs.parse('a[]=b', { parseArrays: false });
st.deepEqual(emptyBrackets, { a: { 0: 'b' } });
st.equal(Array.isArray(emptyBrackets.a), false, 'parseArrays:false, empty brackets case is not an array');
st.end();

@@ -347,3 +355,3 @@ });

var input = {
'user[name]': { 'pop[bob]': { 'test': 3 } },
'user[name]': { 'pop[bob]': { test: 3 } },
'user[email]': null

@@ -354,3 +362,3 @@ };

user: {
name: { 'pop[bob]': { 'test': 3 } },
name: { 'pop[bob]': { test: 3 } },
email: null

@@ -477,3 +485,3 @@ }

qs.parse('a[b]=c&a=toString', { plainObjects: true }),
{ a: { b: 'c', toString: true } },
{ __proto__: null, a: { __proto__: null, b: 'c', toString: true } },
'can overwrite prototype with plainObjects true'

@@ -485,2 +493,62 @@ );

t.test('dunder proto is ignored', function (st) {
var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42';
var result = qs.parse(payload, { allowPrototypes: true });
st.deepEqual(
result,
{
categories: {
length: '42'
}
},
'silent [[Prototype]] payload'
);
var plainResult = qs.parse(payload, { allowPrototypes: true, plainObjects: true });
st.deepEqual(
plainResult,
{
__proto__: null,
categories: {
__proto__: null,
length: '42'
}
},
'silent [[Prototype]] payload: plain objects'
);
var query = qs.parse('categories[__proto__]=cats&categories[__proto__]=dogs&categories[some][json]=toInject', { allowPrototypes: true });
st.notOk(Array.isArray(query.categories), 'is not an array');
st.notOk(query.categories instanceof Array, 'is not instanceof an array');
st.deepEqual(query.categories, { some: { json: 'toInject' } });
st.equal(JSON.stringify(query.categories), '{"some":{"json":"toInject"}}', 'stringifies as a non-array');
st.deepEqual(
qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true }),
{
foo: {
bar: 'stuffs'
}
},
'hidden values'
);
st.deepEqual(
qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true, plainObjects: true }),
{
__proto__: null,
foo: {
__proto__: null,
bar: 'stuffs'
}
},
'hidden values: plain objects'
);
st.end();
});
t.test('can return null objects', { skip: !Object.create }, function (st) {

@@ -504,11 +572,11 @@ var expected = Object.create(null);

decoder: function (str) {
var reg = /\%([0-9A-F]{2})/ig;
var reg = /%([0-9A-F]{2})/ig;
var result = [];
var parts;
var last = 0;
while (parts = reg.exec(str)) {
// var last = 0;
while ((parts = reg.exec(str))) {
result.push(parseInt(parts[1], 16));
last = parts.index + parts[0].length;
// last = parts.index + parts[0].length;
}
return iconv.decode(new Buffer(result), 'shift_jis').toString();
return iconv.decode(SaferBuffer.from(result), 'shift_jis').toString();
}

@@ -520,6 +588,4 @@ }), { 県: '大阪府' });

t.test('throws error with wrong decoder', function (st) {
st.throws(function () {
qs.parse({}, {
decoder: 'string'
});
st['throws'](function () {
qs.parse({}, { decoder: 'string' });
}, new TypeError('Decoder has to be a function.'));

@@ -526,0 +592,0 @@ st.end();

@@ -6,2 +6,3 @@ 'use strict';

var iconv = require('iconv-lite');
var SaferBuffer = require('safer-buffer').Buffer;

@@ -43,3 +44,2 @@ test('stringify()', function (t) {

t.test('omits nested nulls when asked', function (st) {

@@ -199,4 +199,4 @@ st.equal(qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), 'a%5Bb%5D=c');

t.test('stringifies buffer values', function (st) {
st.equal(qs.stringify({ a: new Buffer('test') }), 'a=test');
st.equal(qs.stringify({ a: { b: new Buffer('test') } }), 'a%5Bb%5D=test');
st.equal(qs.stringify({ a: SaferBuffer.from('test') }), 'a=test');
st.equal(qs.stringify({ a: { b: SaferBuffer.from('test') } }), 'a%5Bb%5D=test');
st.end();

@@ -230,3 +230,3 @@ });

var filterFunc = function (prefix, value) {
calls++;
calls += 1;
if (calls === 1) {

@@ -265,4 +265,4 @@ st.equal(prefix, '', 'prefix is empty');

var sort = function (a, b) { return a.localeCompare(b); };
st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: sort, encode: false }), 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb');
st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: null, encode: false }), 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b');
st.equal(qs.stringify({ a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, { sort: sort, encode: false }), 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb');
st.equal(qs.stringify({ a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, { sort: null, encode: false }), 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b');
st.end();

@@ -272,3 +272,3 @@ });

t.test('can stringify with custom encoding', function (st) {
st.equal(qs.stringify({ 県: '大阪府', '': ''}, {
st.equal(qs.stringify({ 県: '大阪府', '': '' }, {
encoder: function (str) {

@@ -280,3 +280,3 @@ if (str.length === 0) {

var result = [];
for (var i=0; i < buf.length; ++i) {
for (var i = 0; i < buf.length; ++i) {
result.push(buf.readUInt8(i).toString(16));

@@ -291,3 +291,3 @@ }

t.test('throws error with wrong encoder', function (st) {
st.throws(function () {
st['throws'](function () {
qs.stringify({}, {

@@ -300,6 +300,4 @@ encoder: 'string'

t.test('can use custom encoder for a buffer object', {
skip: typeof Buffer === 'undefined'
}, function (st) {
st.equal(qs.stringify({ a: new Buffer([1]) }, {
t.test('can use custom encoder for a buffer object', { skip: typeof Buffer === 'undefined' }, function (st) {
st.equal(qs.stringify({ a: SaferBuffer.from([1]) }, {
encoder: function (buffer) {

@@ -306,0 +304,0 @@ if (typeof buffer === 'string') {

@@ -7,4 +7,24 @@ 'use strict';

test('merge()', function (t) {
t.deepEqual(utils.merge(null, true), [null, true], 'merges true into null');
t.deepEqual(utils.merge(null, [42]), [null, 42], 'merges null into an array');
t.deepEqual(utils.merge({ a: 'b' }, { a: 'c' }), { a: ['b', 'c'] }, 'merges two objects with the same key');
var oneMerged = utils.merge({ foo: 'bar' }, { foo: { first: '123' } });
t.deepEqual(oneMerged, { foo: ['bar', { first: '123' }] }, 'merges a standalone and an object into an array');
var twoMerged = utils.merge({ foo: ['bar', { first: '123' }] }, { foo: { second: '456' } });
t.deepEqual(twoMerged, { foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }, 'merges a standalone and two objects into an array');
var sandwiched = utils.merge({ foo: ['bar', { first: '123', second: '456' }] }, { foo: 'baz' });
t.deepEqual(sandwiched, { foo: ['bar', { first: '123', second: '456' }, 'baz'] }, 'merges an object sandwiched by two standalones into an array');
var nestedArrays = utils.merge({ foo: ['baz'] }, { foo: ['bar', 'xyzzy'] });
t.deepEqual(nestedArrays, { foo: ['baz', 'bar', 'xyzzy'] });
var noOptionsNonObjectSource = utils.merge({ foo: 'baz' }, 'bar');
t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true });
t.end();
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc