From c43fd92091a31675a376f0ef5e22dd3b502afef6 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Fri, 17 Jan 2025 17:40:37 +0800 Subject: [PATCH] fix: only decode URL hash instead of entire URL (#13332) followup to #13321 / #13316 This PR ensures only the hash of the URL is decoded so that any encoded hash character in the query parameters remains encoded. --- packages/kit/src/runtime/client/client.js | 17 +++++++++++++++-- .../test/apps/hash-based-routing/test/test.js | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index 190a00a13aac..573a9d2d381b 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -306,7 +306,9 @@ export async function start(_app, _target, hydrate) { if (hydrate) { await _hydrate(target, hydrate); } else { - goto(app.hash ? decodeURIComponent(location.href) : location.href, { replaceState: true }); + goto(app.hash ? decode_hash(new URL(location.href)) : location.href, { + replaceState: true + }); } _start_router(); @@ -2432,7 +2434,7 @@ function _start_router() { // (surprisingly!) mutates `current.url`, allowing us to // detect it and trigger a navigation if (current.url.hash === location.hash) { - navigate({ type: 'goto', url: new URL(decodeURIComponent(current.url.href)) }); + navigate({ type: 'goto', url: decode_hash(current.url) }); } } }); @@ -2826,6 +2828,17 @@ function clone_page(page) { }; } +/** + * @param {URL} url + * @returns {URL} + */ +function decode_hash(url) { + const new_url = new URL(url); + // Safari, for some reason, does change # to %23, when entered through the address bar + new_url.hash = decodeURIComponent(url.hash); + return new_url; +} + if (DEV) { // Nasty hack to silence harmless warnings the user can do nothing about const console_warn = console.warn; diff --git a/packages/kit/test/apps/hash-based-routing/test/test.js b/packages/kit/test/apps/hash-based-routing/test/test.js index 6743639fec2c..23666ed5e562 100644 --- a/packages/kit/test/apps/hash-based-routing/test/test.js +++ b/packages/kit/test/apps/hash-based-routing/test/test.js @@ -56,10 +56,10 @@ test.describe('hash based navigation', () => { }); test('navigation works with URL encoded characters', async ({ page }) => { - await page.goto('/#/%23test'); + await page.goto('/?query=%23abc#/%23test'); await expect(page.locator('p')).toHaveText('home'); // hashchange event - await page.goto('/#/a%23test'); + await page.goto('/?query=%23abc#/a%23test'); await expect(page.locator('p')).toHaveText('a'); });