URL: Stop normalizePath throwing on a malformed percent sequence - #81086
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @konnen916. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @konnen916! In case you missed it, we'd love to have you join us in our Slack community. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
cd98ef8 to
0457272
Compare
normalizePath decoded each query parameter with bare decodeURIComponent, which throws a URIError when a value contains a malformed percent sequence such as `?search=50%off`. This is the same failure that was fixed for getQueryArgs in WordPress#45561, by switching to the package's own safeDecodeURIComponent. normalizePath was not updated at the time. Well formed input is unaffected, and the function stays order stable, which is what it exists for. It matters past the function itself because the api-fetch preloading middleware calls normalizePath on every preload key and on every request path, so the throw takes out the middleware rather than failing a single request.
0457272 to
df32b75
Compare
|
Thanks, fixed both. The lint error was the dependency group comment block I put above the import. No other I also took your CHANGELOG wording, and rebased on trunk since it had picked up a conflict from the 4.53.0 section being cut. |
hbhalodia
left a comment
There was a problem hiding this comment.
Thanks @konnen916, LGTM! and works well. Below is the test report.
Without patch
Screen.Recording.2026-08-14.at.1.02.22.PM.mov
With patch
Screen.Recording.2026-08-14.at.1.03.04.PM.mov
Unit tests
normalizePath
✓ returns same value if no query parameters
✓ returns a stable path (1 ms)
✓ sorts urldecoded values and returns property urlencoded query string
✓ should not blow up on malformed params (1 ms)
✓ returns a stable path when a param is malformed
|
Congratulations on your first merged pull request, @konnen916! We'd like to credit you for your contribution in the post announcing the next WordPress release, but we can't find a WordPress.org profile associated with your GitHub account. When you have a moment, visit the following URL and click "link your GitHub account" under "GitHub Username" to link your accounts: https://profiles.wordpress.org/me/profile/edit/ And if you don't have a WordPress.org account, you can create one on this page: https://login.wordpress.org/register Kudos! |
What?
Closes #81085
normalizePaththrows aURIErrorwhen a query parameter contains a malformed percent sequence. This switches it to the package's ownsafeDecodeURIComponent.Why?
normalizePathdecodes each parameter with baredecodeURIComponent, so a lone%in a value takes the whole call down:This is the same failure that was fixed for
getQueryArgsin #45561, where the throw was breaking Calypso. That PR introducedsafeDecodeURIComponentfor exactly this, andnormalizePathwas not updated at the time.It reaches past the function because the preloading middleware in
@wordpress/api-fetchcallsnormalizePathon every key of the preloaded data and onoptions.pathfor every request that passes through it. One unencoded%, in a hand-written path or in a server-generated preload key, takes out the middleware instead of failing a single request, and it surfaces during normalization rather than as an API error.How?
One line plus the import, matching #45561:
decodeURIComponentbecomessafeDecodeURIComponent, which returns the component untouched when decoding fails.Well-formed input is unaffected. Malformed input now normalizes instead of throwing, and the function stays order-stable, which is the property it exists to provide:
Testing Instructions
wp.url.normalizePath( '/wp/v2/posts?search=50%off' ).URIError: URI malformed. With this branch it returns/wp/v2/posts?search=50%25off.Or run the package tests:
Two tests are added, one asserting it no longer throws and one asserting it stays order-stable when a parameter is malformed.
packages/api-fetchalso passes, since it is the consumer of this function.Testing Instructions for Keyboard
Not applicable, this is a package-level change with no UI.
Screenshots or screencast
Not applicable.