Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2abcf97

Browse files
[HttpFoundation] Don't reorder nested query string keys
1 parent 233774c commit 2abcf97

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,10 @@ public static function normalizeQueryString($qs)
661661
$parts = array();
662662
$order = array();
663663

664+
// since PHP 7, sorting is not stable anymore; we need
665+
// to keep track of some original order using an index
666+
$index = 0;
667+
664668
foreach (explode('&', $qs) as $param) {
665669
if ('' === $param || '=' === $param[0]) {
666670
// Ignore useless delimiters, e.g. "x=y&".
@@ -670,17 +674,16 @@ public static function normalizeQueryString($qs)
670674
}
671675

672676
$keyValuePair = explode('=', $param, 2);
677+
$key = urldecode($keyValuePair[0]);
673678

674679
// GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
675680
// PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str. This is why we use urldecode and then normalize to
676681
// RFC 3986 with rawurlencode.
677-
$parts[] = isset($keyValuePair[1]) ?
678-
rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) :
679-
rawurlencode(urldecode($keyValuePair[0]));
680-
$order[] = urldecode($keyValuePair[0]);
682+
$parts[] = rawurlencode($key).(isset($keyValuePair[1]) ? '='.rawurlencode(urldecode($keyValuePair[1])) : '');
683+
$order[] = false !== ($i = strpos($key, '[')) ? substr_replace($key, \PHP_VERSION_ID >= 70000 ? ++$index : '', 1 + $i) : $key;
681684
}
682685

683-
array_multisort($order, SORT_ASC, $parts);
686+
array_multisort($order, \PHP_VERSION_ID >= 70000 ? SORT_NATURAL : SORT_ASC, $parts);
684687

685688
return implode('&', $parts);
686689
}

src/Symfony/Component/HttpFoundation/Tests/RequestTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,10 @@ public function getQueryStringNormalizationData()
658658
// Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
659659
// PHP also does not include them when building _GET.
660660
array('foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'),
661+
662+
// Don't reorder nested query string keys
663+
array('foo[]=Z&foo[]=A', 'foo%5B%5D=Z&foo%5B%5D=A', 'keeps values order'),
664+
array('foo[Z]=B&foo[A]=B', 'foo%5BZ%5D=B&foo%5BA%5D=B', 'keeps keys order'),
661665
);
662666
}
663667

0 commit comments

Comments
 (0)