From 153ce84948845330d90178cbad982fc7371df538 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 15 Feb 2017 20:37:50 -0800 Subject: [PATCH] v6.3.1 --- CHANGELOG.md | 12 ++++++++++++ component.json | 2 +- dist/qs.js | 51 +++++++++++++++++++++++++++++++------------------- package.json | 2 +- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 351edd4e..fd50ed8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## **6.3.1** +- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties (thanks, @snyk!) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `iconv-lite`, `qs-iconv`, `tape` +- [Tests] on all node minors; improve test matrix +- [Docs] document stringify option `allowDots` (#195) +- [Docs] add empty object and array values example (#195) +- [Docs] Fix minor inconsistency/typo (#192) +- [Docs] document stringify option `sort` (#191) +- [Refactor] `stringify`: throw faster with an invalid encoder +- [Refactor] remove unnecessary escapes (#184) +- Remove contributing.md, since `qs` is no longer part of `hapi` (#183) + ## **6.3.0** - [New] Add support for RFC 1738 (#174, #173) - [New] `stringify`: Add `serializeDate` option to customize Date serialization (#159) diff --git a/component.json b/component.json index 06f433c4..dabd1d48 100644 --- a/component.json +++ b/component.json @@ -2,7 +2,7 @@ "name": "qs", "repository": "hapijs/qs", "description": "query-string parser / stringifier with nesting support", - "version": "6.3.0", + "version": "6.3.1", "keywords": ["querystring", "query", "parser"], "main": "lib/index.js", "scripts": [ diff --git a/dist/qs.js b/dist/qs.js index 1a80d2d8..3d2c211f 100644 --- a/dist/qs.js +++ b/dist/qs.js @@ -50,7 +50,7 @@ var defaults = { strictNullHandling: false }; -var parseValues = function parseValues(str, options) { +var parseValues = function parseQueryStringValues(str, options) { var obj = {}; var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); @@ -76,7 +76,7 @@ var parseValues = function parseValues(str, options) { return obj; }; -var parseObject = function parseObject(chain, val, options) { +var parseObject = function parseObjectRecursive(chain, val, options) { if (!chain.length) { return val; } @@ -89,7 +89,7 @@ var parseObject = function parseObject(chain, val, options) { obj = obj.concat(parseObject(chain, val, options)); } else { obj = options.plainObjects ? Object.create(null) : {}; - var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; var index = parseInt(cleanRoot, 10); if ( !isNaN(index) && @@ -108,18 +108,18 @@ var parseObject = function parseObject(chain, val, options) { return obj; }; -var parseKeys = function parseKeys(givenKey, val, options) { +var parseKeys = function parseQueryStringKeys(givenKey, val, options) { if (!givenKey) { return; } // Transform dot notation to bracket notation - var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey; + var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; // The regex chunks - var parent = /^([^\[\]]*)/; - var child = /(\[[^\[\]]*\])/g; + var parent = /^([^[]*)/; + var child = /(\[[^[\]]*])/g; // Get the parent @@ -145,9 +145,9 @@ var parseKeys = function parseKeys(givenKey, val, options) { var i = 0; while ((segment = child.exec(key)) !== null && i < options.depth) { i += 1; - if (!options.plainObjects && has.call(Object.prototype, segment[1].replace(/\[|\]/g, ''))) { + if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) { if (!options.allowPrototypes) { - continue; + return; } } keys.push(segment[1]); @@ -206,13 +206,13 @@ var utils = require('./utils'); var formats = require('./formats'); var arrayPrefixGenerators = { - brackets: function brackets(prefix) { + brackets: function brackets(prefix) { // eslint-disable-line func-name-matching return prefix + '[]'; }, - indices: function indices(prefix, key) { + indices: function indices(prefix, key) { // eslint-disable-line func-name-matching return prefix + '[' + key + ']'; }, - repeat: function repeat(prefix) { + repeat: function repeat(prefix) { // eslint-disable-line func-name-matching return prefix; } }; @@ -223,14 +223,26 @@ var defaults = { delimiter: '&', encode: true, encoder: utils.encode, - serializeDate: function serializeDate(date) { + serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching return toISO.call(date); }, skipNulls: false, strictNullHandling: false }; -var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots, serializeDate, formatter) { +var stringify = function stringify( // eslint-disable-line func-name-matching + object, + prefix, + generateArrayPrefix, + strictNullHandling, + skipNulls, + encoder, + filter, + sort, + allowDots, + serializeDate, + formatter +) { var obj = object; if (typeof filter === 'function') { obj = filter(prefix, obj); @@ -309,6 +321,11 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu module.exports = function (object, opts) { var obj = object; var options = opts || {}; + + if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; @@ -326,10 +343,6 @@ module.exports = function (object, opts) { var objKeys; var filter; - if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { - throw new TypeError('Encoder has to be a function.'); - } - if (typeof options.filter === 'function') { filter = options.filter; obj = filter('', obj); @@ -517,7 +530,7 @@ exports.encode = function (str) { i += 1; 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)]; + out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; // eslint-disable-line max-len } return out; diff --git a/package.json b/package.json index c5762971..9aa9f370 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "qs", "description": "A querystring parser that supports nesting and arrays, with a depth limit", "homepage": "https://github.com/ljharb/qs", - "version": "6.3.0", + "version": "6.3.1", "repository": { "type": "git", "url": "https://github.com/ljharb/qs.git"