[HttpFoundation] fix query string normalization
This commit is contained in:
parent
f9ec2ea3be
commit
c40a4e50a9
@ -466,32 +466,41 @@ class Request
|
|||||||
/**
|
/**
|
||||||
* Normalizes a query string.
|
* Normalizes a query string.
|
||||||
*
|
*
|
||||||
* It builds a normalized query string, where keys/value pairs are alphabetized
|
* It builds a normalized query string, where keys/value pairs are alphabetized,
|
||||||
* and have consistent escaping.
|
* have consistent escaping and unneeded delimiters are removed.
|
||||||
*
|
*
|
||||||
* @param string $qs Query string
|
* @param string $qs Query string
|
||||||
*
|
*
|
||||||
* @return string|null A normalized query string for the Request
|
* @return string A normalized query string for the Request
|
||||||
*/
|
*/
|
||||||
static public function normalizeQueryString($qs = null)
|
static public function normalizeQueryString($qs)
|
||||||
{
|
{
|
||||||
if (!$qs) {
|
if ('' == $qs) {
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$parts = array();
|
$parts = array();
|
||||||
$order = array();
|
$order = array();
|
||||||
|
|
||||||
foreach (explode('&', $qs) as $segment) {
|
foreach (explode('&', $qs) as $param) {
|
||||||
if (false === strpos($segment, '=')) {
|
if ('' === $param || '=' === $param[0]) {
|
||||||
$parts[] = $segment;
|
// Ignore useless delimiters, e.g. "x=y&".
|
||||||
$order[] = $segment;
|
// Also ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
|
||||||
} else {
|
// PHP also does not include them when building _GET.
|
||||||
$tmp = explode('=', rawurldecode($segment), 2);
|
continue;
|
||||||
$parts[] = rawurlencode($tmp[0]).'='.rawurlencode($tmp[1]);
|
|
||||||
$order[] = $tmp[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$keyValuePair = explode('=', $param, 2);
|
||||||
|
|
||||||
|
// GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
|
||||||
|
// 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
|
||||||
|
// RFC 3986 with rawurlencode.
|
||||||
|
$parts[] = isset($keyValuePair[1]) ?
|
||||||
|
rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) :
|
||||||
|
rawurlencode(urldecode($keyValuePair[0]));
|
||||||
|
$order[] = urldecode($keyValuePair[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
array_multisort($order, SORT_ASC, $parts);
|
array_multisort($order, SORT_ASC, $parts);
|
||||||
|
|
||||||
return implode('&', $parts);
|
return implode('&', $parts);
|
||||||
@ -843,7 +852,8 @@ class Request
|
|||||||
*/
|
*/
|
||||||
public function getQueryString()
|
public function getQueryString()
|
||||||
{
|
{
|
||||||
return static::normalizeQueryString($this->server->get('QUERY_STRING'));
|
$qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));
|
||||||
|
return '' === $qs ? null : $qs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user