Skip to content

Commit

Permalink
Fix route mis-matches with multibyte fixed segments
Browse files Browse the repository at this point in the history
Fix URLs not matching routes when path prefixes contain multi-byte
characters that are received as URL encoded data.

The URL is also decoded inside Route::parse() when pattern matched, but
this initial sieve was missing URL encoding.

Refs #7556
  • Loading branch information
markstory committed Oct 21, 2015
1 parent 9f90a04 commit 4ed1381
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Routing/RouteCollection.php
Expand Up @@ -110,8 +110,9 @@ public function add(Route $route, array $options = [])
*/
public function parse($url)
{
$decoded = urldecode($url);
foreach (array_keys($this->_paths) as $path) {
if (strpos($url, $path) !== 0) {
if (strpos($decoded, $path) !== 0) {
continue;
}

Expand Down
24 changes: 24 additions & 0 deletions tests/TestCase/Routing/RouteCollectionTest.php
Expand Up @@ -105,6 +105,30 @@ public function testParse()
$this->assertEquals($expected, $result);
}

/**
* Test that parse decodes URL data before matching.
* This is important for multibyte URLs that pass through URL rewriting.
*
* @return void
*/
public function testParseEncodedBytesInFixedSegment()
{
$routes = new RouteBuilder($this->collection, '/');
$routes->connect('/ден/:day-:month', ['controller' => 'Events', 'action' => 'index']);
$url = '/%D0%B4%D0%B5%D0%BD/15-%D0%BE%D0%BA%D1%82%D0%BE%D0%BC%D0%B2%D1%80%D0%B8?test=foo';
$result = $this->collection->parse($url);
$expected = [
'pass' => [],
'plugin' => null,
'controller' => 'Events',
'action' => 'index',
'day' => 15,
'month' => 'октомври',
'?' => ['test' => 'foo'],
];
$this->assertEquals($expected, $result);
}

/**
* Test that parsing checks all the related path scopes.
*
Expand Down

0 comments on commit 4ed1381

Please sign in to comment.