diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md index b0ec5771871de6..3aaff122a1c36a 100644 --- a/packages/url/CHANGELOG.md +++ b/packages/url/CHANGELOG.md @@ -6,6 +6,7 @@ - `filterURLForDisplay`: Clamp the truncated file name's head slice at zero, so a small `maxLength` no longer returns a string longer than the untruncated one ([#81529](https://github.com/WordPress/gutenberg/pull/81529)). - `getQueryArgs`: Split each query argument on its first `=` only, so values containing `=` — base64 padding, JWTs, nested URLs — are no longer truncated, and ignore malformed pairs with no key instead of promoting the value to one ([#81066](https://github.com/WordPress/gutenberg/pull/81066)). +- `normalizePath` no longer throws a `URIError` when a query parameter contains a malformed percent sequence, such as `/wp/v2/posts?search=50%off`. It now uses `safeDecodeURIComponent`, matching the fix already applied to `getQueryArgs` in [#45561](https://github.com/WordPress/gutenberg/pull/45561) ([#81086](https://github.com/WordPress/gutenberg/pull/81086)). ## 4.53.0 (2026-08-12) diff --git a/packages/url/src/normalize-path.ts b/packages/url/src/normalize-path.ts index 93d7cca54f9158..0cc7564043b0ed 100644 --- a/packages/url/src/normalize-path.ts +++ b/packages/url/src/normalize-path.ts @@ -1,3 +1,5 @@ +import { safeDecodeURIComponent } from './safe-decode-uri-component'; + /** * Given a path, returns a normalized path where equal query parameter values * will be treated as identical, regardless of order they appear in the original @@ -25,7 +27,7 @@ export function normalizePath( path: string ): string { // [ [ 'b, '1%2C2' ], [ 'c', '2' ], [ 'a', '5' ] ] .map( ( entry ) => entry.split( '=' ) ) // [ [ 'b', '1,2' ], [ 'c', '2' ], [ 'a', '5' ] ] - .map( ( pair ) => pair.map( decodeURIComponent ) ) + .map( ( pair ) => pair.map( safeDecodeURIComponent ) ) // [ [ 'a', '5' ], [ 'b, '1,2' ], [ 'c', '2' ] ] .sort( ( a, b ) => a[ 0 ].localeCompare( b[ 0 ] ) ) // [ [ 'a', '5' ], [ 'b, '1%2C2' ], [ 'c', '2' ] ] diff --git a/packages/url/src/test/index.js b/packages/url/src/test/index.js index 22394b8501f284..bc89b49b91cb08 100644 --- a/packages/url/src/test/index.js +++ b/packages/url/src/test/index.js @@ -1305,4 +1305,18 @@ describe( 'normalizePath', () => { const ab = normalizePath( '/foo/bar?a%2Ca=5,5&a,b=1,1' ); expect( ab ).toBe( '/foo/bar?a%2Ca=5%2C5&a%2Cb=1%2C1' ); } ); + + it( 'should not blow up on malformed params', () => { + const path = '/foo/bar?baz=%E0%A4%A'; + + expect( () => normalizePath( path ) ).not.toThrow(); + expect( normalizePath( path ) ).toBe( '/foo/bar?baz=%25E0%25A4%25A' ); + } ); + + it( 'returns a stable path when a param is malformed', () => { + const ab = normalizePath( '/foo/bar?a=5&b=50%off' ); + const ba = normalizePath( '/foo/bar?b=50%off&a=5' ); + + expect( ab ).toBe( ba ); + } ); } );