Handle encoded params further#91627
Conversation
Stats from current PR🔴 1 regression
📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📝 Changed Files (25 files)Files with changes:
View diffsapp-page-exp..ntime.dev.jsfailed to diffapp-page-exp..time.prod.jsDiff too large to display app-page-tur..ntime.dev.jsfailed to diffapp-page-tur..time.prod.jsDiff too large to display app-page-tur..ntime.dev.jsfailed to diffapp-page-tur..time.prod.jsfailed to diffapp-page.runtime.dev.jsfailed to diffapp-page.runtime.prod.jsDiff too large to display app-route-ex..ntime.dev.jsDiff too large to display app-route-ex..time.prod.jsDiff too large to display app-route-tu..ntime.dev.jsDiff too large to display app-route-tu..time.prod.jsDiff too large to display app-route-tu..ntime.dev.jsDiff too large to display app-route-tu..time.prod.jsDiff too large to display app-route.runtime.dev.jsDiff too large to display app-route.ru..time.prod.jsDiff too large to display pages-api-tu..ntime.dev.jsDiff too large to display pages-api-tu..time.prod.jsDiff too large to display pages-api.runtime.dev.jsDiff too large to display pages-api.ru..time.prod.jsDiff too large to display pages-turbo...ntime.dev.jsDiff too large to display pages-turbo...time.prod.jsDiff too large to display pages.runtime.dev.jsDiff too large to display pages.runtime.prod.jsDiff too large to display server.runtime.prod.jsDiff too large to display 📎 Tarball URL |
| defaultRouteMatches: ParsedUrlQuery, | ||
| ignoreMissingOptional: boolean | ||
| ) { | ||
| const tryDecodeParamValue = (candidateValue: string) => |
There was a problem hiding this comment.
Is this a problem for doubly encoded params since the route matcher does it once here? e.g. /acme/%2523hash currently matches as %23hash but this would turn it into #hash
Maybe we should compare against a decoded copy rather than mutate the param value returned to user code
There was a problem hiding this comment.
Addressed: placeholder checks now decode only into a temporary comparison value and no longer mutate the param returned to user code. This preserves /acme/%2523hash as %23hash for the param value. Added a unit regression for this case in packages/next/src/server/server-utils.test.ts.
|
|
||
| let normalizedCandidateValue = candidateValue | ||
| for (let i = 0; i < 3; i++) { | ||
| if (normalizedCandidateValue.includes(defaultValue)) { |
There was a problem hiding this comment.
I'm worried about the substring matching here. For ex, a request to /acme/%255Bproject%255D-suffix for route /[team]/[project].
The route matcher already decodes once, so project becomes %5Bproject%5D-suffix.
Then this placeholder check decodes again, which turns it into [project]-suffix, and includes('[project]') returns true.
At that point we reject the param as if it were still the default placeholder, even though it's not.
It seems like this should only reject exact placeholder matches after normalization, not arbitrary values that contain the placeholder text.
There was a problem hiding this comment.
Good catch, fixed. Placeholder detection now uses exact match after normalization instead of substring matching. So /acme/%255Bproject%255D-suffix is no longer treated as a placeholder default. Added a regression test for this exact scenario in packages/next/src/server/server-utils.test.ts.
Continues #91603 applying the encoding normalization further and narrows in a better regression test separate of root params and specific to vary params flag.