8000 [Routing] optimization in PhpMatcherDumper produces wrong result · Issue #3777 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
[Routing] optimization in PhpMatcherDumper produces wrong result #3777
Closed
@Tobion

Description

@Tobion

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0