Socket
Socket
Sign inDemoInstall

qs

Package Overview
Dependencies
14
Maintainers
2
Versions
110
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 6.10.1 to 6.10.2

10

CHANGELOG.md

@@ -0,1 +1,11 @@

## **6.10.2**
- [Fix] `stringify`: actually fix cyclic references (#426)
- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
- [readme] remove travis badge; add github actions/codecov badges; update URLs
- [Docs] add note and links for coercing primitive values (#408)
- [actions] update codecov uploader
- [actions] update workflows
- [Tests] clean up stringify tests slightly
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `object-inspect`, `safe-publish-latest`, `tape`
## **6.10.1**

@@ -2,0 +12,0 @@ - [Fix] `stringify`: avoid exception on repeated object values (#402)

37

lib/stringify.js

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

var isArray = Array.isArray;
var split = String.prototype.split;
var push = Array.prototype.push;

@@ -59,2 +60,4 @@ var pushToArray = function (arr, valueOrArray) {

var sentinel = {};
var stringify = function stringify(

@@ -79,4 +82,19 @@ object,

if (sideChannel.has(object)) {
throw new RangeError('Cyclic object value');
var tmpSc = sideChannel;
var step = 0;
var findFlag = false;
while ((tmpSc = tmpSc.get(sentinel)) !== undefined && !findFlag) {
// Where object last appeared in the ref tree
var pos = tmpSc.get(object);
step += 1;
if (typeof pos !== 'undefined') {
if (pos === step) {
throw new RangeError('Cyclic object value');
} else {
findFlag = true; // Break while
}
}
if (typeof tmpSc.get(sentinel) === 'undefined') {
step = 0;
}
}

@@ -108,2 +126,10 @@

var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
if (generateArrayPrefix === 'comma' && encodeValuesOnly) {
var valuesArray = split.call(String(obj), ',');
var valuesJoined = '';
for (var i = 0; i < valuesArray.length; ++i) {
valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
}
return [formatter(keyValue) + '=' + valuesJoined];
}
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];

@@ -131,4 +157,4 @@ }

for (var i = 0; i < objKeys.length; ++i) {
var key = objKeys[i];
for (var j = 0; j < objKeys.length; ++j) {
var key = objKeys[j];
var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];

@@ -144,4 +170,5 @@

sideChannel.set(object, true);
sideChannel.set(object, step);
var valueSideChannel = getSideChannel();
valueSideChannel.set(sentinel, sideChannel);
pushToArray(values, stringify(

@@ -148,0 +175,0 @@ value,

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

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

@@ -182,0 +183,0 @@ + hexTable[0x80 | ((c >> 12) & 0x3F)]

19

package.json

@@ -5,3 +5,3 @@ {

"homepage": "https://github.com/ljharb/qs",
"version": "6.10.1",
"version": "6.10.2",
"repository": {

@@ -37,7 +37,7 @@ "type": "git",

"devDependencies": {
"@ljharb/eslint-config": "^17.5.1",
"aud": "^1.1.4",
"@ljharb/eslint-config": "^20.0.0",
"aud": "^1.1.5",
"browserify": "^16.5.2",
"eclint": "^2.8.1",
"eslint": "^7.22.0",
"eslint": "^8.4.0",
"evalmd": "^0.0.19",

@@ -50,10 +50,11 @@ "for-each": "^0.3.3",

"nyc": "^10.3.2",
"object-inspect": "^1.9.0",
"object-inspect": "^1.11.0",
"qs-iconv": "^1.0.4",
"safe-publish-latest": "^1.1.4",
"safe-publish-latest": "^2.0.0",
"safer-buffer": "^2.1.2",
"tape": "^5.2.2"
"tape": "^5.3.2"
},
"scripts": {
"prepublish": "safe-publish-latest && (not-in-publish || npm run dist)",
"prepublishOnly": "safe-publish-latest && npm run dist",
"prepublish": "not-in-publish || npm run prepublishOnly",
"pretest": "npm run --silent readme && npm run --silent lint",

@@ -65,3 +66,3 @@ "test": "npm run tests-only",

"postlint": "eclint check * lib/* test/* !dist/*",
"lint": "eslint lib/*.js test/*.js",
"lint": "eslint .",
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"

@@ -68,0 +69,0 @@ },

# qs <sup>[![Version Badge][2]][1]</sup>
[![Build Status][3]][4]
[![dependency status][5]][6]
[![dev dependency status][7]][8]
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][11]][1]
[![npm badge][npm-badge-png]][package-url]

@@ -290,2 +291,13 @@ A querystring parsing and stringifying library with some added security.

### Parsing primitive/scalar values (numbers, booleans, null, etc)
By default, all values are parsed as strings. This behavior will not change and is explained in [issue #91](https://github.com/ljharb/qs/issues/91).
```javascript
var primitiveValues = qs.parse('a=15&b=true&c=null');
assert.deepEqual(primitiveValues, { a: '15', b: 'true', c: 'null' });
```
If you wish to auto-convert values which look like numbers, booleans, and other values into their primitive counterparts, you can use the [query-types Express JS middleware](https://github.com/xpepermint/query-types) which will auto-convert all request query parameters.
### Stringifying

@@ -598,16 +610,16 @@

[1]: https://npmjs.org/package/qs
[2]: http://versionbadg.es/ljharb/qs.svg
[3]: https://api.travis-ci.org/ljharb/qs.svg
[4]: https://travis-ci.org/ljharb/qs
[5]: https://david-dm.org/ljharb/qs.svg
[6]: https://david-dm.org/ljharb/qs
[7]: https://david-dm.org/ljharb/qs/dev-status.svg
[8]: https://david-dm.org/ljharb/qs?type=dev
[9]: https://ci.testling.com/ljharb/qs.png
[10]: https://ci.testling.com/ljharb/qs
[11]: https://nodei.co/npm/qs.png?downloads=true&stars=true
[license-image]: http://img.shields.io/npm/l/qs.svg
[package-url]: https://npmjs.org/package/qs
[npm-version-svg]: https://versionbadg.es/ljharb/qs.svg
[deps-svg]: https://david-dm.org/ljharb/qs.svg
[deps-url]: https://david-dm.org/ljharb/qs
[dev-deps-svg]: https://david-dm.org/ljharb/qs/dev-status.svg
[dev-deps-url]: https://david-dm.org/ljharb/qs#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/qs.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/qs.svg
[license-url]: LICENSE
[downloads-image]: http://img.shields.io/npm/dm/qs.svg
[downloads-url]: http://npm-stat.com/charts.html?package=qs
[downloads-image]: https://img.shields.io/npm/dm/qs.svg
[downloads-url]: https://npm-stat.com/charts.html?package=qs
[codecov-image]: https://codecov.io/gh/ljharb/qs/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/ljharb/qs/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/qs
[actions-url]: https://github.com/ljharb/qs/actions

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

t.test('stringifies a nested array value', function (st) {
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a%5Bb%5D%5B%5D=c&a%5Bb%5D%5B%5D=d');
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'comma' }), 'a%5Bb%5D=c%2Cd'); // a[b]=c,d
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[b][0]=c&a[b][1]=d');
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[b][]=c&a[b][]=d');
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[b]=c,d');
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true }), 'a[b][0]=c&a[b][1]=d');
st.end();

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

{ a: { b: ['c', 'd'] } },
{ allowDots: true, encode: false, arrayFormat: 'indices' }
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'indices' }
),

@@ -156,3 +156,3 @@ 'a.b[0]=c&a.b[1]=d',

{ a: { b: ['c', 'd'] } },
{ allowDots: true, encode: false, arrayFormat: 'brackets' }
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'brackets' }
),

@@ -165,3 +165,3 @@ 'a.b[]=c&a.b[]=d',

{ a: { b: ['c', 'd'] } },
{ allowDots: true, encode: false, arrayFormat: 'comma' }
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' }
),

@@ -174,3 +174,3 @@ 'a.b=c,d',

{ a: { b: ['c', 'd'] } },
{ allowDots: true, encode: false }
{ allowDots: true, encodeValuesOnly: true }
),

@@ -223,3 +223,3 @@ 'a.b[0]=c&a.b[1]=d',

st.equal(
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'indices' }),
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'indices' }),
'a[0][b]=1&a[1]=2&a[2]=3',

@@ -229,3 +229,3 @@ 'indices => indices'

st.equal(
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'brackets' }),
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }),
'a[][b]=1&a[]=2&a[]=3',

@@ -235,3 +235,9 @@ 'brackets => brackets'

st.equal(
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false }),
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'comma' }),
'???',
'brackets => brackets',
{ skip: 'TODO: figure out what this should do' }
);
st.equal(
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true }),
'a[0][b]=1&a[1]=2&a[2]=3',

@@ -459,3 +465,3 @@ 'default => indices'

function () { qs.stringify({ 'foo[bar]': 'baz', 'foo[baz]': a }); },
RangeError,
/RangeError: Cyclic object value/,
'cyclic values throw'

@@ -470,6 +476,12 @@ );

function () { qs.stringify(circular); },
RangeError,
/RangeError: Cyclic object value/,
'cyclic values throw'
);
var arr = ['a'];
st.doesNotThrow(
function () { qs.stringify({ x: arr, y: arr }); },
'non-cyclic values do not throw'
);
st.end();

@@ -842,3 +854,8 @@ });

st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'indices' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, indices');
st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'comma' }), '???', 'array, comma (pending issue #378)', { skip: true });
st.equal(
qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }),
'???',
'array, comma',
{ skip: 'TODO: figure out what this should do' }
);

@@ -845,0 +862,0 @@ st.end();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

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