[Routing] allow comma and other reserved chars without special meaing to not be encoded in the query and fragment

This commit is contained in:
Tobias Schultze 2019-04-16 17:05:04 +02:00
parent 278a7ece35
commit 76f6c97416
2 changed files with 17 additions and 5 deletions

View File

@ -27,6 +27,20 @@ use Symfony\Component\Routing\RouteCollection;
*/
class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInterface
{
private const QUERY_FRAGMENT_DECODED = [
// RFC 3986 explicitly allows those in the query/fragment to reference other URIs unencoded
'%2F' => '/',
'%3F' => '?',
// reserved chars that have no special meaning for HTTP URIs in a query or fragment
// this excludes esp. "&", "=" and also "+" because PHP would treat it as a space (form-encoded)
'%40' => '@',
'%3A' => ':',
'%21' => '!',
'%3B' => ';',
'%2C' => ',',
'%2A' => '*',
];
protected $routes;
protected $context;
@ -275,13 +289,11 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
}
if ($extra && $query = http_build_query($extra, '', '&', PHP_QUERY_RFC3986)) {
// "/" and "?" can be left decoded for better user experience, see
// http://tools.ietf.org/html/rfc3986#section-3.4
$url .= '?'.strtr($query, ['%2F' => '/']);
$url .= '?'.strtr($query, self::QUERY_FRAGMENT_DECODED);
}
if ('' !== $fragment) {
$url .= '#'.strtr(rawurlencode($fragment), ['%2F' => '/', '%3F' => '?']);
$url .= '#'.strtr(rawurlencode($fragment), self::QUERY_FRAGMENT_DECODED);
}
return $url;

View File

@ -337,7 +337,7 @@ class UrlGeneratorTest extends TestCase
{
$expectedPath = '/app.php/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
.'/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
.'?query=%40%3A%5B%5D/%28%29%2A%27%22%20%2B%2C%3B-._~%26%24%3C%3E%7C%7B%7D%25%5C%5E%60%21%3Ffoo%3Dbar%23id';
.'?query=@:%5B%5D/%28%29*%27%22%20%2B,;-._~%26%24%3C%3E%7C%7B%7D%25%5C%5E%60!?foo%3Dbar%23id';
// This tests the encoding of reserved characters that are used for delimiting of URI components (defined in RFC 3986)
// and other special ASCII chars. These chars are tested as static text path, variable path and query param.