Skip to content

Commit

Permalink
Also use the qs module for the simple parser (expressjs#387)
Browse files Browse the repository at this point in the history
* Always use the qs module, even in simple mode

expressjs#326 (comment)

* Create the simple and extended parser with the same function, reducing duplication

* Don't mention the querystring module in the README

* Fix lint
  • Loading branch information
papandreou authored Jul 24, 2024
1 parent ddf9b75 commit 7eb00cd
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 87 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,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 `false`.

Expand Down
91 changes: 10 additions & 81 deletions lib/types/urlencoded.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,14 @@ var debug = require('debug')('body-parser:urlencoded')
var isFinished = require('on-finished').isFinished
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 All @@ -56,9 +51,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 @@ -126,11 +119,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 @@ -140,6 +132,8 @@ function extendedparser (options) {
parameterLimit = parameterLimit | 0
}

var depth = extended ? Infinity : 0

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

Expand All @@ -150,13 +144,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 @@ -201,72 +196,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

0 comments on commit 7eb00cd

Please sign in to comment.