Skip to content

Commit

Permalink
bug #27498 [Routing] Don't reorder past variable-length placeholders …
Browse files Browse the repository at this point in the history
…(nanocom, nicolas-grekas)

This PR was merged into the 4.1 branch.

Discussion
----------

[Routing] Don't reorder past variable-length placeholders

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | no
| Fixed tickets | #27491
| License       | MIT

Commits
-------

44616d9 [Router] regression when matching a route
7a750d4 [Routing] Don't reorder past variable-length placeholders
  • Loading branch information
nicolas-grekas committed Jun 4, 2018
2 parents 7605706 + 44616d9 commit 2521e7b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ private function getCommonPrefix(string $prefix, string $anotherPrefix): array
break; break;
} }
$subPattern = substr($prefix, $i, $j - $i); $subPattern = substr($prefix, $i, $j - $i);
if ($prefix !== $anotherPrefix && !preg_match('/^\(\[[^\]]++\]\+\+\)$/', $subPattern) && !preg_match('{(?<!'.$subPattern.')}', '')) { if ($prefix !== $anotherPrefix && !preg_match('{(?<!'.$subPattern.')}', '')) {
// sub-patterns of variable length are not considered as common prefixes because their greediness would break in-order matching // sub-patterns of variable length are not considered as common prefixes because their greediness would break in-order matching
break; break;
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,21 +29,13 @@ public function match($rawPathinfo)
$matchedPathinfo = $pathinfo; $matchedPathinfo = $pathinfo;
$regexList = array( $regexList = array(
0 => '{^(?' 0 => '{^(?'
.'|/abc([^/]++)/(?' .'|/abc(?'
.'|1(?' .'|([^/]++)/1(*:24)'
.'|(*:27)' .'|([^/]++)/2(*:41)'
.'|0(?' .'|([^/]++)/10(*:59)'
.'|(*:38)' .'|([^/]++)/20(*:77)'
.'|0(*:46)' .'|([^/]++)/100(*:96)'
.')' .'|([^/]++)/200(*:115)'
.')'
.'|2(?'
.'|(*:59)'
.'|0(?'
.'|(*:70)'
.'|0(*:78)'
.')'
.')'
.')' .')'
.')$}sD', .')$}sD',
); );
Expand All @@ -53,12 +45,12 @@ public function match($rawPathinfo)
switch ($m = (int) $matches['MARK']) { switch ($m = (int) $matches['MARK']) {
default: default:
$routes = array( $routes = array(
27 => array(array('_route' => 'r1'), array('foo'), null, null), 24 => array(array('_route' => 'r1'), array('foo'), null, null),
38 => array(array('_route' => 'r10'), array('foo'), null, null), 41 => array(array('_route' => 'r2'), array('foo'), null, null),
46 => array(array('_route' => 'r100'), array('foo'), null, null), 59 => array(array('_route' => 'r10'), array('foo'), null, null),
59 => array(array('_route' => 'r2'), array('foo'), null, null), 77 => array(array('_route' => 'r20'), array('foo'), null, null),
70 => array(array('_route' => 'r20'), array('foo'), null, null), 96 => array(array('_route' => 'r100'), array('foo'), null, null),
78 => array(array('_route' => 'r200'), array('foo'), null, null), 115 => array(array('_route' => 'r200'), array('foo'), null, null),
); );


list($ret, $vars, $requiredMethods, $requiredSchemes) = $routes[$m]; list($ret, $vars, $requiredMethods, $requiredSchemes) = $routes[$m];
Expand All @@ -84,7 +76,7 @@ public function match($rawPathinfo)
return $ret; return $ret;
} }


if (78 === $m) { if (115 === $m) {
break; break;
} }
$regex = substr_replace($regex, 'F', $m - $offset, 1 + strlen($m)); $regex = substr_replace($regex, 'F', $m - $offset, 1 + strlen($m));
Expand Down
12 changes: 12 additions & 0 deletions src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@ public function testMatchRegression()
} }
} }


public function testMultipleParams()
{
$coll = new RouteCollection();
$coll->add('foo1', new Route('/foo/{a}/{b}'));
$coll->add('foo2', new Route('/foo/{a}/test/test/{b}'));
$coll->add('foo3', new Route('/foo/{a}/{b}/{c}/{d}'));

$route = $this->getUrlMatcher($coll)->match('/foo/test/test/test/bar')['_route'];

$this->assertEquals('foo2', $route);
}

public function testDefaultRequirementForOptionalVariables() public function testDefaultRequirementForOptionalVariables()
{ {
$coll = new RouteCollection(); $coll = new RouteCollection();
Expand Down

0 comments on commit 2521e7b

Please sign in to comment.