merged branch Tobion/4166 (PR #4530)
Commits -------3466896
[Routing] fix encoding of static static, so UrlGenerator produces valid URLs Discussion ---------- [Routing] fix encoding of static text Fixes #4166 As requested by Fabien, I split #4205 into multiple PRs. --------------------------------------------------------------------------- by stof at 2012-06-09T12:49:32Z github tells me this PR cannot be merged automatically. Could you rebase it ? --------------------------------------------------------------------------- by Tobion at 2012-06-09T13:12:55Z Done --------------------------------------------------------------------------- by travisbot at 2012-06-09T13:18:18Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1576266) (merged3466896a
into15b5aa4f
).
This commit is contained in:
commit
11e8a33c7c
@ -31,9 +31,33 @@ class UrlGenerator implements UrlGeneratorInterface
|
||||
protected $context;
|
||||
protected $strictParameters = true;
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* This array defines the characters (besides alphanumeric ones) that will not be percent-encoded in the path segment of the generated URL.
|
||||
*
|
||||
* PHP's rawurlencode() encodes all chars except "a-zA-Z0-9-._~" according to RFC 3986. But we want to allow some chars
|
||||
* to be used in their literal form (reasons below). Other chars inside the path must of course be encoded, e.g.
|
||||
* "?" and "#" (would be interpreted wrongly as query and fragment identifier),
|
||||
* "'" and """ (are used as delimiters in HTML).
|
||||
*/
|
||||
protected $decodedChars = array(
|
||||
// %2F is not valid in a URL, so we don't encode it (which is fine as the requirements explicitly allowed it)
|
||||
// the slash can be used to designate a hierarchical structure and we want allow using it with this meaning
|
||||
// some webservers don't allow the slash in encoded form in the path for security reasons anyway
|
||||
// see http://stackoverflow.com/questions/4069002/http-400-if-2f-part-of-get-url-in-jboss
|
||||
'%2F' => '/',
|
||||
// the following chars are general delimiters in the URI specification but have only special meaning in the authority component
|
||||
// so they can safely be used in the path in unencoded form
|
||||
'%40' => '@',
|
||||
'%3A' => ':',
|
||||
// these chars are only sub-delimiters that have no predefined meaning and can therefore be used literally
|
||||
// so URI producing applications can use these chars to delimit subcomponents in a path segment without being encoded for better readability
|
||||
'%3B' => ';',
|
||||
'%2C' => ',',
|
||||
'%3D' => '=',
|
||||
'%2B' => '+',
|
||||
'%21' => '!',
|
||||
'%2A' => '*',
|
||||
'%7C' => '|',
|
||||
);
|
||||
|
||||
protected $routes;
|
||||
@ -144,7 +168,7 @@ class UrlGenerator implements UrlGeneratorInterface
|
||||
}
|
||||
|
||||
if (!$isEmpty || !$optional) {
|
||||
$url = $token[1].strtr(rawurlencode($tparams[$token[3]]), $this->decodedChars).$url;
|
||||
$url = $token[1].$tparams[$token[3]].$url;
|
||||
}
|
||||
|
||||
$optional = false;
|
||||
@ -159,14 +183,15 @@ class UrlGenerator implements UrlGeneratorInterface
|
||||
$url = '/';
|
||||
}
|
||||
|
||||
// do not encode the contexts base url as it is already encoded (see Symfony\Component\HttpFoundation\Request)
|
||||
$url = $this->context->getBaseUrl().strtr(rawurlencode($url), $this->decodedChars);
|
||||
|
||||
// add a query string if needed
|
||||
$extra = array_diff_key($originParameters, $variables, $defaults);
|
||||
if ($extra && $query = http_build_query($extra, '', '&')) {
|
||||
$url .= '?'.$query;
|
||||
}
|
||||
|
||||
$url = $this->context->getBaseUrl().$url;
|
||||
|
||||
if ($this->context->getHost()) {
|
||||
$scheme = $this->context->getScheme();
|
||||
if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) {
|
||||
|
@ -229,6 +229,22 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('/app.php/foo', $this->getGenerator($routes)->generate('test', array('default' => 'foo')));
|
||||
}
|
||||
|
||||
public function testUrlEncoding()
|
||||
{
|
||||
// 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.
|
||||
$chars = '@:[]/()*\'" +,;-._~&$<>|{}%\\^`!?foo=bar#id';
|
||||
$routes = $this->getRoutes('test', new Route("/$chars/{varpath}", array(), array('varpath' => '.+')));
|
||||
$this->assertSame('/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%2F%28%29%2A%27%22+%2B%2C%3B-._%7E%26%24%3C%3E%7C%7B%7D%25%5C%5E%60%21%3Ffoo%3Dbar%23id',
|
||||
$this->getGenerator($routes)->generate('test', array(
|
||||
'varpath' => $chars,
|
||||
'query' => $chars
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null)
|
||||
{
|
||||
$context = new RequestContext('/app.php');
|
||||
|
Reference in New Issue
Block a user