Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Also use the qs module for the simple parser #387

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 4 additions & 6 deletions README.md
Expand Up @@ -232,12 +232,10 @@ any of the following keys:

##### extended

The `extended` option allows to choose between parsing the URL-encoded data
with the `querystring` library (when `false`) or the `qs` library (when
`true`). The "extended" syntax allows for rich objects and arrays to be
encoded into the URL-encoded format, allowing for a JSON-like experience
with URL-encoded. For more information, please
[see the qs library](https://www.npmjs.org/package/qs#readme).
The "extended" syntax allows for rich objects and arrays to be encoded into the
URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
more information, please [see the qs
library](https://www.npmjs.org/package/qs#readme).

Defaults to `true`, but using the default has been deprecated. Please
research into the difference between `qs` and `querystring` and choose the
Expand Down
91 changes: 10 additions & 81 deletions lib/types/urlencoded.js
Expand Up @@ -19,19 +19,14 @@ var debug = require('debug')('body-parser:urlencoded')
var deprecate = require('depd')('body-parser')
var read = require('../read')
var typeis = require('type-is')
var qs = require('qs')

/**
* Module exports.
*/

module.exports = urlencoded

/**
* Cache of parser modules.
*/

var parsers = Object.create(null)

/**
* Create a middleware to parse urlencoded bodies.
*
Expand Down Expand Up @@ -61,9 +56,7 @@ function urlencoded (options) {
}

// create the appropriate query parser
var queryparse = extended
? extendedparser(opts)
: simpleparser(opts)
var queryparse = createQueryParser(opts, extended)

// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
Expand Down Expand Up @@ -129,11 +122,10 @@ function urlencoded (options) {
* @param {object} options
*/

function extendedparser (options) {
function createQueryParser (options, extended) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('qs')

if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
Expand All @@ -143,6 +135,8 @@ function extendedparser (options) {
parameterLimit = parameterLimit | 0
}

var depth = extended ? Infinity : 0

return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)

Expand All @@ -153,13 +147,14 @@ function extendedparser (options) {
})
}

var arrayLimit = Math.max(100, paramCount)
var arrayLimit = extended ? Math.max(100, paramCount) : 0

debug('parse ' + (extended ? 'extended ' : '') + 'urlencoding')

debug('parse extended urlencoding')
return parse(body, {
return qs.parse(body, {
allowPrototypes: true,
arrayLimit: arrayLimit,
depth: Infinity,
depth: depth,
parameterLimit: parameterLimit
})
}
Expand Down Expand Up @@ -204,72 +199,6 @@ function parameterCount (body, limit) {
return count
}

/**
* Get parser for module name dynamically.
*
* @param {string} name
* @return {function}
* @api private
*/

function parser (name) {
var mod = parsers[name]

if (mod !== undefined) {
return mod.parse
}

// this uses a switch for static require analysis
switch (name) {
case 'qs':
mod = require('qs')
break
case 'querystring':
mod = require('querystring')
break
}

// store to prevent invoking require()
parsers[name] = mod

return mod.parse
}

/**
* Get the simple query parser.
*
* @param {object} options
*/

function simpleparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('querystring')

if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}

if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}

return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)

if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters', {
type: 'parameters.too.many'
})
}

debug('parse urlencoding')
return parse(body, undefined, undefined, { maxKeys: parameterLimit })
}
}

/**
* Get the simple type checker.
*
Expand Down