diff -u b/core/lib/Drupal/Component/Utility/UrlHelper.php b/core/lib/Drupal/Component/Utility/UrlHelper.php --- b/core/lib/Drupal/Component/Utility/UrlHelper.php +++ b/core/lib/Drupal/Component/Utility/UrlHelper.php @@ -201,12 +201,14 @@ $parsed = []; foreach (explode('&', $query) as $param) { list($name) = explode('=', $param, 2); + $name = rawurldecode($name); + // Extract the first item of a potentially nested parameter name. $name = strstr($name, '[', true) ?: $name; // Parse the query parameter. parse_str($param, $param); // Merge the parameter into the parsed array. if (isset($parsed[$name])) { - $parsed[$name] = array_merge($parsed[$name], reset($param)); + $parsed[$name] = array_merge_recursive($parsed[$name], reset($param)); } else { $parsed[$name] = reset($param); diff -u b/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php --- b/core/lib/Drupal/Core/Url.php +++ b/core/lib/Drupal/Core/Url.php @@ -295,15 +295,15 @@ } if (!empty($uri_parts['query'])) { - $uri_query = UrlHelper::parseQueryString($uri_parts['query']); + $uri_query = []; + parse_str($uri_parts['query'], $uri_query); $uri_options['query'] = isset($uri_options['query']) ? $uri_options['query'] + $uri_query : $uri_query; unset($uri_parts['query']); } } if (!empty($uri_parts['query'])) { - $uri_query = []; - parse_str($uri_parts['query'], $uri_query); + $uri_query = UrlHelper::parseQueryString($uri_parts['query']); $uri_options['query'] = isset($uri_options['query']) ? $uri_options['query'] + $uri_query : $uri_query; unset($uri_parts['query']); }