Skip to content

Commit

Permalink
Merge pull request #3172 from michalsn/router_regex
Browse files Browse the repository at this point in the history
Add Unicode support for regular expressions in router
  • Loading branch information
MGatner authored Jul 1, 2020
2 parents d9864e3 + 6203e42 commit 458e2d4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 5 deletions.
2 changes: 1 addition & 1 deletion system/Router/RouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1348,7 +1348,7 @@ protected function fillRouteParams(string $from, array $params = null): string
// the expected param type.
$pos = strpos($from, $pattern);

if (preg_match('#' . $pattern . '#', $params[$index]))
if (preg_match('#^' . $pattern . '$#u', $params[$index]))
{
$from = substr_replace($from, $params[$index], $pos, strlen($pattern));
}
Expand Down
11 changes: 7 additions & 4 deletions system/Router/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ public function handle(string $uri = null)
: $this->controller;
}

// Decode URL-encoded string
$uri = urldecode($uri);

if ($this->checkRoutes($uri))
{
if ($this->collection->isFiltered($this->matchedRoute[0]))
Expand Down Expand Up @@ -420,12 +423,12 @@ protected function checkRoutes(string $uri): bool

// Replace it with a regex so it
// will actually match.
$key = str_replace('/', '\/', $key);
$key = str_replace('/', '\/', $key);
$key = str_replace('{locale}', '[^\/]+', $key);
}

// Does the RegEx match?
if (preg_match('#^' . $key . '$#', $uri, $matches))
if (preg_match('#^' . $key . '$#u', $uri, $matches))
{
// Is this route supposed to redirect to another?
if ($this->collection->isRedirect($key))
Expand Down Expand Up @@ -470,12 +473,12 @@ protected function checkRoutes(string $uri): bool
if (strpos($val, '$') !== false && strpos($key, '(') !== false && strpos($key, '/') !== false)
{
$replacekey = str_replace('/(.*)', '', $key);
$val = preg_replace('#^' . $key . '$#', $val, $uri);
$val = preg_replace('#^' . $key . '$#u', $val, $uri);
$val = str_replace($replacekey, str_replace('/', '\\', $replacekey), $val);
}
elseif (strpos($val, '$') !== false && strpos($key, '(') !== false)
{
$val = preg_replace('#^' . $key . '$#', $val, $uri);
$val = preg_replace('#^' . $key . '$#u', $val, $uri);
}
elseif (strpos($val, '/') !== false)
{
Expand Down
41 changes: 41 additions & 0 deletions tests/system/Router/RouterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -531,4 +531,45 @@ public function testAutoRouteMethodEmpty()
$this->assertEquals('Home', $router->controllerName());
$this->assertEquals('index', $router->methodName());
}

//--------------------------------------------------------------------

/**
* @see https://github.com/codeigniter4/CodeIgniter4/issues/3169
*/
public function testRegularExpressionWithUnicode()
{
$this->collection->get('news/([a-z0-9\x{0980}-\x{09ff}-]+)', 'News::view/$1');

$router = new Router($this->collection, $this->request);

$router->handle('news/a0%E0%A6%80%E0%A7%BF-');
$this->assertEquals('\News', $router->controllerName());
$this->assertEquals('view', $router->methodName());

$expected = [
'a0ঀ৿-',
];
$this->assertEquals($expected, $router->params());
}

/**
* @see https://github.com/codeigniter4/CodeIgniter4/issues/3169
*/
public function testRegularExpressionPlaceholderWithUnicode()
{
$this->collection->addPlaceholder('custom', '[a-z0-9\x{0980}-\x{09ff}-]+');
$this->collection->get('news/(:custom)', 'News::view/$1');

$router = new Router($this->collection, $this->request);

$router->handle('news/a0%E0%A6%80%E0%A7%BF-');
$this->assertEquals('\News', $router->controllerName());
$this->assertEquals('view', $router->methodName());

$expected = [
'a0ঀ৿-',
];
$this->assertEquals($expected, $router->params());
}
}

0 comments on commit 458e2d4

Please sign in to comment.