diff --git a/lib/types/json.js b/lib/types/json.js index 15c54bb4..c76494f9 100644 --- a/lib/types/json.js +++ b/lib/types/json.js @@ -50,23 +50,61 @@ var JSON_SYNTAX_REGEXP = /#+/g function json (options) { const normalizedOptions = normalizeOptions(options, 'application/json') - var reviver = options?.reviver - var strict = options?.strict !== false + const parse = createJsonParser(options) - function parse (body) { - if (body.length === 0) { - // special-case empty json body, as it's a common client-side mistake - // TODO: maybe make this configurable or part of "strict" option - return {} - } + const readOptions = { + ...normalizedOptions, + // assert charset per RFC 7159 sec 8.1 + isValidCharset: (charset) => charset.slice(0, 4) === 'utf-' + } - if (strict) { - var first = firstchar(body) + return function jsonParser (req, res, next) { + read(req, res, next, parse, debug, readOptions) + } +} + +/** + * Create a JSON parse function + * + * @param {object} [options] + * @return {function} + * @private + */ +function createJsonParser (options) { + const reviver = options?.reviver + const strict = options?.strict !== false + + if (strict) { + return function parse (body) { + if (body.length === 0) { + // special-case empty json body, as it's a common client-side mistake + // TODO: maybe make this configurable or part of "strict" option + return {} + } + const first = firstchar(body) if (first !== '{' && first !== '[') { debug('strict violation') throw createStrictSyntaxError(body, first) } + + try { + debug('parse json') + return JSON.parse(body, reviver) + } catch (e) { + throw normalizeJsonSyntaxError(e, { + message: e.message, + stack: e.stack + }) + } + } + } + + return function parse (body) { + if (body.length === 0) { + // special-case empty json body, as it's a common client-side mistake + // TODO: maybe make this configurable or part of "strict" option + return {} } try { @@ -79,16 +117,6 @@ function json (options) { }) } } - - const readOptions = { - ...normalizedOptions, - // assert charset per RFC 7159 sec 8.1 - isValidCharset: (charset) => charset.slice(0, 4) === 'utf-' - } - - return function jsonParser (req, res, next) { - read(req, res, next, parse, debug, readOptions) - } } /** @@ -128,7 +156,7 @@ function createStrictSyntaxError (str, char) { * Get the first non-whitespace character in a string. * * @param {string} str - * @return {function} + * @return {string | undefined} * @private */