Closed
Description
The optimization in line 93 of https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php#L93 does not work correctly and produces a matcher that can match the wrong route.
This is because it aggregates routes with the same prefix but does not consider there might be routes in between these routes that have higher priority and thus should be matched earlier. Hard to explain. Here is a test case that shows it:
$rootCollection = new RouteCollection();
$collection1 = new RouteCollection();
$collection1->add('static1', new Route('/static1'));
$collection1->add('static2', new Route('/static2'));
$collection2 = new RouteCollection();
$collection2->add('var', new Route('/{var}', array(), array('var' => '.*')));
$collection3 = new RouteCollection();
$collection3->add('static3', new Route('/static3'));
$collection3->add('static4', new Route('/static4'));
$rootCollection->addCollection($collection1, '/prefix');
$rootCollection->addCollection($collection2, '/{anyprefix}', array(), array('anyprefix' => '.*'));
$rootCollection->addCollection($collection3, '/prefix');
This creates
public function match($pathinfo)
{
$allow = array();
$pathinfo = urldecode($pathinfo);
if (0 === strpos($pathinfo, '/prefix')) {
// static1
if ($pathinfo === '/prefix/static1') {
return array('_route' => 'static1');
}
// static2
if ($pathinfo === '/prefix/static2') {
return array('_route' => 'static2');
}
// static3
if ($pathinfo === '/prefix/static3') {
return array('_route' => 'static3');
}
// static4
if ($pathinfo === '/prefix/static4') {
return array('_route' => 'static4');
}
}
// var
if (preg_match('#^/(?P<anyprefix>.*)/(?P<var>.*)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'var';
return $matches;
}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
As you can see the route /prefix/static3
would now match route named static3
but should rather match route var
which has higher priority but comes later in the code generation.