diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php index 6ed70cabdf..e8b02e81c5 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -140,8 +140,8 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt foreach ($tokens as $token) { if ('variable' === $token[0]) { if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) { - // check requirement - if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) { + // check requirement (while ignoring look-around patterns) + if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\(\?(?:=|<=|!|strictRequirements) { throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]))); } @@ -195,7 +195,8 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt $routeHost = ''; foreach ($hostTokens as $token) { if ('variable' === $token[0]) { - if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) { + // check requirement (while ignoring look-around patterns) + if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\(\?(?:=|<=|!|strictRequirements) { throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]))); } diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index d4bf18ccac..900d381054 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -703,6 +703,23 @@ class UrlGeneratorTest extends TestCase $this->assertEquals('/app.php/testing#fragment', $url); } + /** + * @dataProvider provideLookAroundRequirementsInPath + */ + public function testLookRoundRequirementsInPath($expected, $path, $requirement) + { + $routes = $this->getRoutes('test', new Route($path, array(), array('foo' => $requirement, 'baz' => '.+?'))); + $this->assertSame($expected, $this->getGenerator($routes)->generate('test', array('foo' => 'a/b', 'baz' => 'c/d/e'))); + } + + public function provideLookAroundRequirementsInPath() + { + yield array('/app.php/a/b/b%28ar/c/d/e', '/{foo}/b(ar/{baz}', '.+(?=/b\\(ar/)'); + yield array('/app.php/a/b/bar/c/d/e', '/{foo}/bar/{baz}', '.+(?!$)'); + yield array('/app.php/bar/a/b/bam/c/d/e', '/bar/{foo}/bam/{baz}', '(?<=/bar/).+'); + yield array('/app.php/bar/a/b/bam/c/d/e', '/bar/{foo}/bam/{baz}', '(?