diff --git a/HISTORY.md b/HISTORY.md index b93c488..8cf7f5a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix using special characters in format * deps: depd@~1.1.2 - perf: remove argument reassignment diff --git a/index.js b/index.js index c6d61e3..703e192 100644 --- a/index.js +++ b/index.js @@ -375,8 +375,8 @@ function compile (format) { throw new TypeError('argument format must be a string') } - var fmt = format.replace(/"/g, '\\"') - var js = ' "use strict"\n return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function (_, name, arg) { + var fmt = String(JSON.stringify(format)) + var js = ' "use strict"\n return ' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function (_, name, arg) { var tokenArguments = 'req, res' var tokenFunction = 'tokens[' + String(JSON.stringify(name)) + ']' @@ -385,7 +385,7 @@ function compile (format) { } return '" +\n (' + tokenFunction + '(' + tokenArguments + ') || "-") + "' - }) + '"' + }) // eslint-disable-next-line no-new-func return new Function('tokens, req, res', js) diff --git a/test/morgan.js b/test/morgan.js index 853b95d..ff50b49 100644 --- a/test/morgan.js +++ b/test/morgan.js @@ -925,6 +925,57 @@ describe('morgan()', function () { }) }) + describe('a string', function () { + it('should accept format as format string of tokens', function (done) { + var cb = after(2, function (err, res, line) { + if (err) return done(err) + assert.strictEqual(line, 'GET /') + done() + }) + + var stream = createLineStream(function (line) { + cb(null, null, line) + }) + + request(createServer(':method :url', { stream: stream })) + .get('/') + .expect(200, cb) + }) + + it('should accept text mixed with tokens', function (done) { + var cb = after(2, function (err, res, line) { + if (err) return done(err) + assert.strictEqual(line, 'method=GET url=/') + done() + }) + + var stream = createLineStream(function (line) { + cb(null, null, line) + }) + + request(createServer('method=:method url=:url', { stream: stream })) + .get('/') + .expect(200, cb) + }) + + it('should accept special characters', function (done) { + var cb = after(2, function (err, res, line) { + if (err) return done(err) + assert.strictEqual(line, 'LOCAL\\tobi "GET /" 200') + done() + }) + + var stream = createLineStream(function (line) { + cb(null, null, line) + }) + + request(createServer('LOCAL\\:remote-user ":method :url" :status', { stream: stream })) + .get('/') + .set('Authorization', 'Basic dG9iaTpsb2tp') + .expect(200, cb) + }) + }) + describe('combined', function () { it('should match expectations', function (done) { var cb = after(2, function (err, res, line) {