From 770c19b6b0b3c36a75290bfeca81b14790f67e31 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 4 Aug 2025 16:55:06 -0400 Subject: [PATCH 1/5] match newlines in regexes for rest params --- packages/kit/src/utils/routing.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kit/src/utils/routing.js b/packages/kit/src/utils/routing.js index 15f3582bc136..ee129976b6e4 100644 --- a/packages/kit/src/utils/routing.js +++ b/packages/kit/src/utils/routing.js @@ -26,7 +26,7 @@ export function parse_route_id(id) { rest: true, chained: true }); - return '(?:/(.*))?'; + return '(?:/([^]*))?'; } // special case — /[[optional]]/ could contain zero segments const optional_match = /^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(segment); @@ -86,7 +86,7 @@ export function parse_route_id(id) { rest: !!is_rest, chained: is_rest ? i === 1 && parts[0] === '' : false }); - return is_rest ? '(.*?)' : is_optional ? '([^/]*)?' : '([^/]+?)'; + return is_rest ? '([^]*?)' : is_optional ? '([^/]*)?' : '([^/]+?)'; } return escape(content); From a62506330534fce8c854558d3d790e6f1b1819dc Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 4 Aug 2025 16:55:36 -0400 Subject: [PATCH 2/5] update existing tests --- .../src/core/sync/create_manifest_data/index.spec.js | 10 +++++----- packages/kit/src/utils/routing.spec.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/kit/src/core/sync/create_manifest_data/index.spec.js b/packages/kit/src/core/sync/create_manifest_data/index.spec.js index 2642e0c3cce0..c681184446a6 100644 --- a/packages/kit/src/core/sync/create_manifest_data/index.spec.js +++ b/packages/kit/src/core/sync/create_manifest_data/index.spec.js @@ -268,7 +268,7 @@ test('sorts routes with rest correctly', () => { }, { id: '/a/[...rest]', - pattern: '/^/a(?:/(.*))?/?$/', + pattern: '/^/a(?:/([^]*))?/?$/', page: { layouts: [0], errors: [1], leaf: 2 } }, { @@ -277,7 +277,7 @@ test('sorts routes with rest correctly', () => { }, { id: '/b/[...rest]', - pattern: '/^/b(?:/(.*))?/?$/', + pattern: '/^/b(?:/([^]*))?/?$/', page: { layouts: [0], errors: [1], leaf: 3 } } ]); @@ -301,12 +301,12 @@ test('allows rest parameters inside segments', () => { }, { id: '/prefix-[...rest]', - pattern: '/^/prefix-(.*?)/?$/', + pattern: '/^/prefix-([^]*?)/?$/', page: { layouts: [0], errors: [1], leaf: 2 } }, { id: '/[...rest].json', - pattern: '/^/(.*?).json/?$/', + pattern: '/^/([^]*?).json/?$/', endpoint: { file: 'samples/rest-prefix-suffix/[...rest].json/+server.js' } @@ -714,7 +714,7 @@ test('handles pages without .svelte file', () => { }, { id: '/error/[...path]', - pattern: '/^/error(?:/(.*))?/?$/', + pattern: '/^/error(?:/([^]*))?/?$/', page: { layouts: [0, undefined], errors: [1, 2], leaf: 6 } }, { diff --git a/packages/kit/src/utils/routing.spec.js b/packages/kit/src/utils/routing.spec.js index de7fef129daa..7e6dcc584c74 100644 --- a/packages/kit/src/utils/routing.spec.js +++ b/packages/kit/src/utils/routing.spec.js @@ -36,11 +36,11 @@ describe('parse_route_id', () => { params: [{ name: 'slug', matcher: undefined, optional: true, rest: false, chained: false }] }, '/[...catchall]': { - pattern: /^(?:\/(.*))?\/?$/, + pattern: /^(?:\/([^]*))?\/?$/, params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }] }, '/foo/[...catchall]/bar': { - pattern: /^\/foo(?:\/(.*))?\/bar\/?$/, + pattern: /^\/foo(?:\/([^]*))?\/bar\/?$/, params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }] }, '/matched/[id=uuid]': { From 70d5e904efd23949650ebed5199c000ba798f63e Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 4 Aug 2025 16:55:49 -0400 Subject: [PATCH 3/5] add new test --- packages/kit/src/utils/routing.spec.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/kit/src/utils/routing.spec.js b/packages/kit/src/utils/routing.spec.js index 7e6dcc584c74..03ab03af3c78 100644 --- a/packages/kit/src/utils/routing.spec.js +++ b/packages/kit/src/utils/routing.spec.js @@ -244,6 +244,16 @@ describe('exec', () => { route: '/[[slug1=doesntmatch]]/[...slug2=doesntmatch]', path: '/a/b/c', expected: undefined + }, + { + route: '/[...catchall]', + path: '/\n', + expected: { catchall: '\n' } + }, + { + route: '/[[...catchall]]', + path: '/\n', + expected: { catchall: '\n' } } ]; From 8332eb1f3ab375e18eafcfcab91d32f512094423 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 4 Aug 2025 16:56:57 -0400 Subject: [PATCH 4/5] add changeset --- .changeset/dark-heads-greet.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/dark-heads-greet.md diff --git a/.changeset/dark-heads-greet.md b/.changeset/dark-heads-greet.md new file mode 100644 index 000000000000..de769b6e8c7e --- /dev/null +++ b/.changeset/dark-heads-greet.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: match URL-encoded newlines in rest route params From 45980eb8ec6dca68e8cadb1b84e1388a72f6e2fb Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 4 Aug 2025 17:21:38 -0400 Subject: [PATCH 5/5] more test adjustments --- packages/adapter-vercel/test/utils.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/adapter-vercel/test/utils.spec.js b/packages/adapter-vercel/test/utils.spec.js index 866523a99351..34286d7c2ff1 100644 --- a/packages/adapter-vercel/test/utils.spec.js +++ b/packages/adapter-vercel/test/utils.spec.js @@ -124,9 +124,9 @@ test('pattern_to_src for route with optional parameter in the middle', () => { }); test('pattern_to_src for route with rest parameter', () => { - run_pattern_to_src_test('/foo/[...bar]', '^/foo(/.*)?/?'); + run_pattern_to_src_test('/foo/[...bar]', '^/foo(/[^]*)?/?'); }); test('pattern_to_src for route with rest parameter in the middle', () => { - run_pattern_to_src_test('/foo/[...bar]/baz', '^/foo(/.*)?/baz/?'); + run_pattern_to_src_test('/foo/[...bar]/baz', '^/foo(/[^]*)?/baz/?'); });