Skip to content

Commit c345382

Browse files
authored
fix: match URL-encoded newlines in rest route params (#14102)
* match newlines in regexes for rest params * update existing tests * add new test * add changeset * more test adjustments
1 parent fba2d80 commit c345382

File tree

5 files changed

+26
-11
lines changed

5 files changed

+26
-11
lines changed

.changeset/dark-heads-greet.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: match URL-encoded newlines in rest route params

packages/adapter-vercel/test/utils.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ test('pattern_to_src for route with optional parameter in the middle', () => {
124124
});
125125

126126
test('pattern_to_src for route with rest parameter', () => {
127-
run_pattern_to_src_test('/foo/[...bar]', '^/foo(/.*)?/?');
127+
run_pattern_to_src_test('/foo/[...bar]', '^/foo(/[^]*)?/?');
128128
});
129129

130130
test('pattern_to_src for route with rest parameter in the middle', () => {
131-
run_pattern_to_src_test('/foo/[...bar]/baz', '^/foo(/.*)?/baz/?');
131+
run_pattern_to_src_test('/foo/[...bar]/baz', '^/foo(/[^]*)?/baz/?');
132132
});

packages/kit/src/core/sync/create_manifest_data/index.spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ test('sorts routes with rest correctly', () => {
268268
},
269269
{
270270
id: '/a/[...rest]',
271-
pattern: '/^/a(?:/(.*))?/?$/',
271+
pattern: '/^/a(?:/([^]*))?/?$/',
272272
page: { layouts: [0], errors: [1], leaf: 2 }
273273
},
274274
{
@@ -277,7 +277,7 @@ test('sorts routes with rest correctly', () => {
277277
},
278278
{
279279
id: '/b/[...rest]',
280-
pattern: '/^/b(?:/(.*))?/?$/',
280+
pattern: '/^/b(?:/([^]*))?/?$/',
281281
page: { layouts: [0], errors: [1], leaf: 3 }
282282
}
283283
]);
@@ -301,12 +301,12 @@ test('allows rest parameters inside segments', () => {
301301
},
302302
{
303303
id: '/prefix-[...rest]',
304-
pattern: '/^/prefix-(.*?)/?$/',
304+
pattern: '/^/prefix-([^]*?)/?$/',
305305
page: { layouts: [0], errors: [1], leaf: 2 }
306306
},
307307
{
308308
id: '/[...rest].json',
309-
pattern: '/^/(.*?).json/?$/',
309+
pattern: '/^/([^]*?).json/?$/',
310310
endpoint: {
311311
file: 'samples/rest-prefix-suffix/[...rest].json/+server.js'
312312
}
@@ -714,7 +714,7 @@ test('handles pages without .svelte file', () => {
714714
},
715715
{
716716
id: '/error/[...path]',
717-
pattern: '/^/error(?:/(.*))?/?$/',
717+
pattern: '/^/error(?:/([^]*))?/?$/',
718718
page: { layouts: [0, undefined], errors: [1, 2], leaf: 6 }
719719
},
720720
{

packages/kit/src/utils/routing.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function parse_route_id(id) {
2626
rest: true,
2727
chained: true
2828
});
29-
return '(?:/(.*))?';
29+
return '(?:/([^]*))?';
3030
}
3131
// special case — /[[optional]]/ could contain zero segments
3232
const optional_match = /^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(segment);
@@ -86,7 +86,7 @@ export function parse_route_id(id) {
8686
rest: !!is_rest,
8787
chained: is_rest ? i === 1 && parts[0] === '' : false
8888
});
89-
return is_rest ? '(.*?)' : is_optional ? '([^/]*)?' : '([^/]+?)';
89+
return is_rest ? '([^]*?)' : is_optional ? '([^/]*)?' : '([^/]+?)';
9090
}
9191
9292
return escape(content);

packages/kit/src/utils/routing.spec.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ describe('parse_route_id', () => {
3636
params: [{ name: 'slug', matcher: undefined, optional: true, rest: false, chained: false }]
3737
},
3838
'/[...catchall]': {
39-
pattern: /^(?:\/(.*))?\/?$/,
39+
pattern: /^(?:\/([^]*))?\/?$/,
4040
params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }]
4141
},
4242
'/foo/[...catchall]/bar': {
43-
pattern: /^\/foo(?:\/(.*))?\/bar\/?$/,
43+
pattern: /^\/foo(?:\/([^]*))?\/bar\/?$/,
4444
params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }]
4545
},
4646
'/matched/[id=uuid]': {
@@ -244,6 +244,16 @@ describe('exec', () => {
244244
route: '/[[slug1=doesntmatch]]/[...slug2=doesntmatch]',
245245
path: '/a/b/c',
246246
expected: undefined
247+
},
248+
{
249+
route: '/[...catchall]',
250+
path: '/\n',
251+
expected: { catchall: '\n' }
252+
},
253+
{
254+
route: '/[[...catchall]]',
255+
path: '/\n',
256+
expected: { catchall: '\n' }
247257
}
248258
];
249259

0 commit comments

Comments
 (0)