fix(routing): return 404 for dynamic segments with un-decodable percent-encoded sequences#92557
Open
sleitor wants to merge 1 commit intovercel:canaryfrom
Open
fix(routing): return 404 for dynamic segments with un-decodable percent-encoded sequences#92557sleitor wants to merge 1 commit intovercel:canaryfrom
sleitor wants to merge 1 commit intovercel:canaryfrom
Conversation
…nt-encoded sequences Previously, requests to dynamic routes with malformed percent-encoding (e.g. /foo/%A0 where %A0 is not a valid UTF-8 sequence) produced inconsistent responses: a 400 in development and a 500 in production. Both are incorrect. An un-decodable URL cannot match any real resource, so the correct response is 404 Not Found. Fix: in resolve-routes.ts, catch DecodeError thrown by route.match() in the dynamic route loop (checkTrue) and in the custom-route handler (handleRoute). When the error occurs, skip the route instead of propagating — this lets the request fall through to 404 handling. Fixes vercel#92527
Collaborator
|
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Dynamic routes like
/foo/[slug]produce inconsistent errors when the URL contains a percent-encoded sequence that is not valid UTF-8 (e.g./foo/%A0):Why?
When
route.match()inresolve-routes.tsis called for a dynamic route against a URL with an un-decodable segment, it callsdecodeURIComponent('%A0')which throws aURIError. This was wrapped into aDecodeErrorinroute-matcher.ts, but in certain production paths the error propagated unhandled, resulting in a 500.More importantly, both 400 and 500 are wrong responses. A URL that cannot be decoded cannot match any real resource — the correct response is 404 Not Found.
How?
Catch
DecodeErrorthrown byroute.match()at both call sites inresolve-routes.ts:checkTrue()— the dynamic route loop used for filesystem-based route resolution. When aDecodeErroris caught,continueto the next route, allowing the request to fall through to 404 handling.handleRoute()— the custom-route handler (headers, redirects, rewrites). When aDecodeErroris caught,return(no match), so the loop continues.A new e2e test (
test/e2e/app-dir/dynamic-segment-invalid-encoding) covers both the broken case (%A0→ 404) and the valid case (%20→ 200).Fixes #92527