From 25d326b55ee92a5335ad37e1427dee14a531baa4 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Thu, 10 May 2012 03:50:37 +0200 Subject: [PATCH] [Routing] fix encoding of path segments '.' and '..' --- .../Component/Routing/Generator/UrlGenerator.php | 7 ++++++- .../Routing/Tests/Generator/UrlGeneratorTest.php | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php index 500b562bc8..6391dbf9cd 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -179,13 +179,18 @@ class UrlGenerator implements UrlGeneratorInterface } } - if (!$url) { + if ('' === $url) { $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); + // the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3 + // so we need to encode them as they are not used for this purpose here + // otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route + $url = preg_replace(array('#/\.\.(/|$)#', '#/\.(/|$)#'), array('/%2E%2E$1', '/%2E$1'), $url); + // add a query string if needed $extra = array_diff_key($originParameters, $variables, $defaults); if ($extra && $query = http_build_query($extra, '', '&')) { diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index 3ca31af952..852de411ea 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -245,6 +245,16 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase ); } + public function testEncodingOfRelativePathSegments() + { + $routes = $this->getRoutes('test', new Route('/dir/../dir/..')); + $this->assertSame('/app.php/dir/%2E%2E/dir/%2E%2E', $this->getGenerator($routes)->generate('test')); + $routes = $this->getRoutes('test', new Route('/dir/./dir/.')); + $this->assertSame('/app.php/dir/%2E/dir/%2E', $this->getGenerator($routes)->generate('test')); + $routes = $this->getRoutes('test', new Route('/a./.a/a../..a/...')); + $this->assertSame('/app.php/a./.a/a../..a/...', $this->getGenerator($routes)->generate('test')); + } + protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null) { $context = new RequestContext('/app.php');