From ed013a90c36cd39189b1292d58fbb162b75de513 Mon Sep 17 00:00:00 2001
From: Thomas McNiven <hello@trmcnvn.dev>
Date: Sat, 20 Aug 2022 22:58:03 +1000
Subject: [PATCH] Fix pattern matching for `@` encoded routes (#6110)

changeset
---
 .changeset/rich-walls-doubt.md         |  5 +++++
 packages/kit/src/utils/routing.js      |  9 +++++----
 packages/kit/src/utils/routing.spec.js | 10 ++++++++++
 3 files changed, 20 insertions(+), 4 deletions(-)
 create mode 100644 .changeset/rich-walls-doubt.md

diff --git a/.changeset/rich-walls-doubt.md b/.changeset/rich-walls-doubt.md
new file mode 100644
index 000000000000..c56fd899fea4
--- /dev/null
+++ b/.changeset/rich-walls-doubt.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+Fix pattern matching for routes starting with an encoded `@` symbol
diff --git a/packages/kit/src/utils/routing.js b/packages/kit/src/utils/routing.js
index fb6d219ad4fb..826c75a4d602 100644
--- a/packages/kit/src/utils/routing.js
+++ b/packages/kit/src/utils/routing.js
@@ -16,11 +16,12 @@ export function parse_route_id(id) {
 		id === ''
 			? /^\/$/
 			: new RegExp(
-					`^${decodeURIComponent(id)
+					`^${id
 						.split(/(?:@[a-zA-Z0-9_-]+)?(?:\/|$)/)
 						.map((segment, i, segments) => {
+							const decoded_segment = decodeURIComponent(segment);
 							// special case — /[...rest]/ could contain zero segments
-							const match = /^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(segment);
+							const match = /^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(decoded_segment);
 							if (match) {
 								names.push(match[1]);
 								types.push(match[2]);
@@ -30,9 +31,9 @@ export function parse_route_id(id) {
 							const is_last = i === segments.length - 1;
 
 							return (
-								segment &&
+								decoded_segment &&
 								'/' +
-									segment
+									decoded_segment
 										.split(/\[(.+?)\]/)
 										.map((content, i) => {
 											if (i % 2) {
diff --git a/packages/kit/src/utils/routing.spec.js b/packages/kit/src/utils/routing.spec.js
index dd14241c0e23..3c14ce927936 100644
--- a/packages/kit/src/utils/routing.spec.js
+++ b/packages/kit/src/utils/routing.spec.js
@@ -42,6 +42,16 @@ const tests = {
 		pattern: /^\/matched\/([^/]+?)\/?$/,
 		names: ['id'],
 		types: ['uuid']
+	},
+	'%23hash-encoded': {
+		pattern: /^\/%23hash-encoded\/?$/,
+		names: [],
+		types: []
+	},
+	'%40at-encoded/[id]': {
+		pattern: /^\/@at-encoded\/([^/]+?)\/?$/,
+		names: ['id'],
+		types: [undefined]
 	}
 };