From 2e7ecd87e5568c6e59a408e812535f088498e437 Mon Sep 17 00:00:00 2001 From: Tobias Deekens Date: Wed, 15 Dec 2021 00:42:54 +0100 Subject: [PATCH] Fixes escaping port number in absolute urls (#1028) * fix(coercePath): escape the port number * fix(coercePath): remove the "g" modifier from port/protocol regexp Co-authored-by: Artem Zakharchenko --- src/utils/matching/matchRequestUrl.test.ts | 35 +++++++++++++++------- src/utils/matching/matchRequestUrl.ts | 7 ++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/utils/matching/matchRequestUrl.test.ts b/src/utils/matching/matchRequestUrl.test.ts index 5ffdcfc92..0c99a0eff 100644 --- a/src/utils/matching/matchRequestUrl.test.ts +++ b/src/utils/matching/matchRequestUrl.test.ts @@ -64,6 +64,31 @@ describe('matchRequestUrl', () => { }) describe('coercePath', () => { + test('escapes the colon in protocol', () => { + expect(coercePath('https://example.com')).toEqual('https\\://example.com') + expect(coercePath('https://example.com/:userId')).toEqual( + 'https\\://example.com/:userId', + ) + expect(coercePath('http://localhost:3000')).toEqual( + 'http\\://localhost\\:3000', + ) + }) + + test('escapes the colon before the port number', () => { + expect(coercePath('localhost:8080')).toEqual('localhost\\:8080') + expect(coercePath('http://127.0.0.1:8080')).toEqual( + 'http\\://127.0.0.1\\:8080', + ) + expect(coercePath('https://example.com:1234')).toEqual( + 'https\\://example.com\\:1234', + ) + + expect(coercePath('localhost:8080/:5678')).toEqual('localhost\\:8080/:5678') + expect(coercePath('https://example.com:8080/:5678')).toEqual( + 'https\\://example.com\\:8080/:5678', + ) + }) + test('replaces wildcard with an unnnamed capturing group', () => { expect(coercePath('*')).toEqual('(.*)') expect(coercePath('**')).toEqual('(.*)') @@ -86,14 +111,4 @@ describe('coercePath', () => { '/foo/:first/bar/:second*/(.*)', ) }) - - test('escapes the semicolon in protocol', () => { - expect(coercePath('https://example.com')).toEqual('https\\://example.com') - expect(coercePath('https://example.com/:userId')).toEqual( - 'https\\://example.com/:userId', - ) - expect(coercePath('http://localhost:3000')).toEqual( - 'http\\://localhost:3000', - ) - }) }) diff --git a/src/utils/matching/matchRequestUrl.ts b/src/utils/matching/matchRequestUrl.ts index 61618e440..8f9c29ae0 100644 --- a/src/utils/matching/matchRequestUrl.ts +++ b/src/utils/matching/matchRequestUrl.ts @@ -36,12 +36,17 @@ export function coercePath(path: string): string { : `${parameterName}${expression}` }, ) + /** + * Escape the port so that "path-to-regexp" can match + * absolute URLs including port numbers. + */ + .replace(/([^\/])(:)(?=\d+)/, '$1\\$2') /** * Escape the protocol so that "path-to-regexp" could match * absolute URL. * @see https://github.com/pillarjs/path-to-regexp/issues/259 */ - .replace(/^([^\/]+)(:)(?=\/\/)/g, '$1\\$2') + .replace(/^([^\/]+)(:)(?=\/\/)/, '$1\\$2') ) }