diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 0034705672dff..bf475dcbd043c 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -12,6 +12,7 @@ CHANGELOG * Add `HeaderRequestMatcher` * Add support for `\SplTempFileObject` in `BinaryFileResponse` * Add `verbose` argument to response test constraints + * [BC BREAK] Query string key/value pairs are now recursively sorted in `Request::normalizeQueryString()`. 7.0 --- diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index df332479de201..0c75f5b036ba4 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -595,7 +595,15 @@ public static function normalizeQueryString(?string $qs): string } $qs = HeaderUtils::parseQuery($qs); - ksort($qs); + $recursive_sort = function (&$array) use (&$recursive_sort) { + foreach ($array as &$v) { + if (is_array($v)) { + $recursive_sort($v); + } + } + ksort($array); + }; + $recursive_sort($qs); return http_build_query($qs, '', '&', \PHP_QUERY_RFC3986); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 89b38ae92b794..2dc9e573225e3 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -826,9 +826,9 @@ public static function getQueryStringNormalizationData() // PHP also does not include them when building _GET. ['foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'], - // Don't reorder nested query string keys + // Provide predictable ordering of nested query string keys. ['foo[]=Z&foo[]=A', 'foo%5B0%5D=Z&foo%5B1%5D=A', 'keeps order of values'], - ['foo[Z]=B&foo[A]=B', 'foo%5BZ%5D=B&foo%5BA%5D=B', 'keeps order of keys'], + ['foo[Z]=A&foo[A]=B', 'foo%5BA%5D=B&foo%5BZ%5D=A', 'nested keys are reordered but values are maintained'], ['utf8=✓', 'utf8=%E2%9C%93', 'encodes UTF-8'], ];
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: