From 6b599267eebdebf880e38c58a9a30ce51a2402d6 Mon Sep 17 00:00:00 2001 From: Ivan Tymoshenko Date: Fri, 7 Oct 2022 17:25:14 +0300 Subject: [PATCH] fix: escape double colon in multi-parametrical node (#307) --- index.js | 11 ++++++++--- test/issue-17.test.js | 21 +++++++++++++++++++++ test/issue-206.test.js | 15 +++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index d60d6480..43ee03b8 100644 --- a/index.js +++ b/index.js @@ -223,13 +223,18 @@ Router.prototype._on = function _on (method, path, opts, handler, store) { let lastParamEndIndex = j for (; lastParamEndIndex < path.length; lastParamEndIndex++) { const charCode = path.charCodeAt(lastParamEndIndex) - if (charCode === 58 || charCode === 47) { - break + const nextCharCode = path.charCodeAt(lastParamEndIndex + 1) + if (charCode === 58 && nextCharCode === 58) { + lastParamEndIndex++ + continue } + if (charCode === 58 || charCode === 47) break } - const staticPart = path.slice(j, lastParamEndIndex) + let staticPart = path.slice(j, lastParamEndIndex) if (staticPart) { + staticPart = staticPart.split('::').join(':') + staticPart = staticPart.split('%').join('%25') regexps.push(escapeRegExp(staticPart)) } diff --git a/test/issue-17.test.js b/test/issue-17.test.js index 7b92bc5d..7fbd3fbe 100644 --- a/test/issue-17.test.js +++ b/test/issue-17.test.js @@ -203,6 +203,27 @@ test('Multi parametric route with regexp / 1', t => { findMyWay.lookup({ method: 'GET', url: '/at/0h42m', headers: {} }, null) }) +test('Multi parametric route with colon separator', t => { + t.plan(3) + const findMyWay = FindMyWay({ + defaultRoute: (req, res) => { + t.fail('Should not be defaultRoute') + } + }) + + findMyWay.on('GET', '/:param(.*)::suffix', (req, res, params) => { + t.equal(params.param, 'foo') + }) + + findMyWay.on('GET', '/:param1(.*)::suffix1-:param2(.*)::suffix2/static', (req, res, params) => { + t.equal(params.param1, 'foo') + t.equal(params.param2, 'bar') + }) + + findMyWay.lookup({ method: 'GET', url: '/foo:suffix', headers: {} }, null) + findMyWay.lookup({ method: 'GET', url: '/foo:suffix1-bar:suffix2/static', headers: {} }, null) +}) + test('Multi parametric route with regexp / 2', t => { t.plan(8) const findMyWay = FindMyWay({ diff --git a/test/issue-206.test.js b/test/issue-206.test.js index 76ebef57..5d245751 100644 --- a/test/issue-206.test.js +++ b/test/issue-206.test.js @@ -97,6 +97,21 @@ test('Special chars on path parameter', t => { findMyWay.lookup(get('/reg/123%20.png'), null, { expect: { regExeParam: '123' }, handler: regexPathParam }) }) +test('Multi parametric route with encoded colon separator', t => { + t.plan(1) + const findMyWay = FindMyWay({ + defaultRoute: (req, res) => { + t.fail('Should not be defaultRoute') + } + }) + + findMyWay.on('GET', '/:param(.*)::suffix', (req, res, params) => { + t.equal(params.param, 'foo-bar') + }) + + findMyWay.lookup({ method: 'GET', url: '/foo-bar%3Asuffix', headers: {} }, null) +}) + function get (url) { return { method: 'GET', url, headers: {} } }