From 5f72a58935d9bdd5237bdf86d2e94bcdc544c7b3 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Wed, 26 Feb 2025 16:29:32 +0000 Subject: [PATCH] fix(core): double encoding during match of routes (#13303) Co-authored-by: florian-lefebvre <69633530+florian-lefebvre@users.noreply.github.com> --- .changeset/stale-oranges-call.md | 5 +++++ packages/astro/src/core/app/index.ts | 2 +- packages/astro/src/core/build/generate.ts | 2 +- packages/astro/src/core/routing/match.ts | 7 +++---- packages/astro/test/params.test.js | 1 + 5 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/stale-oranges-call.md diff --git a/.changeset/stale-oranges-call.md b/.changeset/stale-oranges-call.md new file mode 100644 index 000000000000..dd21fc4927bc --- /dev/null +++ b/.changeset/stale-oranges-call.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes an issue where the dev server was applying second decoding of the URL of the incoming request, causing issues for certain URLs. diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index 543d82d0fdc6..f76408078aa6 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -177,7 +177,7 @@ export class App { if (!pathname) { pathname = prependForwardSlash(this.removeBase(url.pathname)); } - let routeData = matchRoute(pathname, this.#manifestData); + let routeData = matchRoute(decodeURI(pathname), this.#manifestData); // missing routes fall-through, pre rendered are handled by static layer if (!routeData || routeData.prerender) return undefined; diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index d8df4bccf928..0d5c049fc8f9 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -360,7 +360,7 @@ async function getPathsForRoute( // NOTE: The same URL may match multiple routes in the manifest. // Routing priority needs to be verified here for any duplicate // paths to ensure routing priority rules are enforced in the final build. - const matchedRoute = matchRoute(staticPath, options.routesList); + const matchedRoute = matchRoute(decodeURI(staticPath), options.routesList); return matchedRoute === route; }); diff --git a/packages/astro/src/core/routing/match.ts b/packages/astro/src/core/routing/match.ts index 45ad8f595bfb..caa3ae743119 100644 --- a/packages/astro/src/core/routing/match.ts +++ b/packages/astro/src/core/routing/match.ts @@ -5,18 +5,17 @@ import { SERVER_ISLAND_BASE_PREFIX, SERVER_ISLAND_COMPONENT } from '../server-is /** Find matching route from pathname */ export function matchRoute(pathname: string, manifest: RoutesList): RouteData | undefined { - const decodedPathname = decodeURI(pathname); return manifest.routes.find((route) => { return ( - route.pattern.test(decodedPathname) || - route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(decodedPathname)) + route.pattern.test(pathname) || + route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname)) ); }); } /** Finds all matching routes from pathname */ export function matchAllRoutes(pathname: string, manifest: RoutesList): RouteData[] { - return manifest.routes.filter((route) => route.pattern.test(decodeURI(pathname))); + return manifest.routes.filter((route) => route.pattern.test(pathname)); } const ROUTE404_RE = /^\/404\/?$/; diff --git a/packages/astro/test/params.test.js b/packages/astro/test/params.test.js index 60890637d357..7917e32f1ba2 100644 --- a/packages/astro/test/params.test.js +++ b/packages/astro/test/params.test.js @@ -113,6 +113,7 @@ describe('Astro.params in dev mode', () => { const $ = cheerio.load(html); assert.equal($('.category').text(), '你好'); }); + }); describe('Astro.params in static mode', () => {