diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 952f1252..4304a344 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: - Node.js 16.x - Node.js 17.x - Node.js 18.x + - Node.js 19.x include: - name: Node.js 0.8 @@ -113,6 +114,9 @@ jobs: - name: Node.js 18.x node-version: "18.14" + - name: Node.js 19.x + node-version: "19.7" + steps: - uses: actions/checkout@v3 diff --git a/HISTORY.md b/HISTORY.md index e7ac6f56..cb375d3a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix strict json error message on Node.js 19+ * deps: content-type@~1.0.5 - perf: skip value escaping when unnecessary * deps: raw-body@2.5.2 diff --git a/lib/types/json.js b/lib/types/json.js index c2745be3..59f3f7e2 100644 --- a/lib/types/json.js +++ b/lib/types/json.js @@ -39,6 +39,9 @@ module.exports = json var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex +var JSON_SYNTAX_CHAR = '#' +var JSON_SYNTAX_REGEXP = /#+/g + /** * Create a middleware to parse JSON bodies. * @@ -152,15 +155,23 @@ function json (options) { function createStrictSyntaxError (str, char) { var index = str.indexOf(char) - var partial = index !== -1 - ? str.substring(0, index) + '#' - : '' + var partial = '' + + if (index !== -1) { + partial = str.substring(0, index) + JSON_SYNTAX_CHAR + + for (var i = index + 1; i < str.length; i++) { + partial += JSON_SYNTAX_CHAR + } + } try { JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation') } catch (e) { return normalizeJsonSyntaxError(e, { - message: e.message.replace('#', char), + message: e.message.replace(JSON_SYNTAX_REGEXP, function (placeholder) { + return str.substring(index, index + placeholder.length) + }), stack: e.stack }) } diff --git a/test/json.js b/test/json.js index 4d686763..c76ea138 100644 --- a/test/json.js +++ b/test/json.js @@ -245,7 +245,7 @@ describe('bodyParser.json()', function () { .post('/') .set('Content-Type', 'application/json') .send('true') - .expect(400, '[entity.parse.failed] ' + parseError('#rue').replace('#', 't'), done) + .expect(400, '[entity.parse.failed] ' + parseError('#rue').replace(/#/g, 't'), done) }) }) @@ -273,7 +273,7 @@ describe('bodyParser.json()', function () { .post('/') .set('Content-Type', 'application/json') .send('true') - .expect(400, '[entity.parse.failed] ' + parseError('#rue').replace('#', 't'), done) + .expect(400, '[entity.parse.failed] ' + parseError('#rue').replace(/#/g, 't'), done) }) it('should not parse primitives with leading whitespaces', function (done) { @@ -281,7 +281,7 @@ describe('bodyParser.json()', function () { .post('/') .set('Content-Type', 'application/json') .send(' true') - .expect(400, '[entity.parse.failed] ' + parseError(' #rue').replace('#', 't'), done) + .expect(400, '[entity.parse.failed] ' + parseError(' #rue').replace(/#/g, 't'), done) }) it('should allow leading whitespaces in JSON', function (done) { @@ -299,7 +299,7 @@ describe('bodyParser.json()', function () { .set('X-Error-Property', 'stack') .send('true') .expect(400) - .expect(shouldContainInBody(parseError('#rue').replace('#', 't'))) + .expect(shouldContainInBody(parseError('#rue').replace(/#/g, 't'))) .end(done) }) })