This is a (multiple allowed):
What you did
Obviously this is not exactly what I am trying to do, but this is the simplest way I can show what is happening.
// ProductsController.php
public function index(): ?Response
{
$url = Router::url(['action' => 'test', 'xx/yy']); //products/test/xx%2Fyy
return $this->redirect($url);
}
public function test()
{
var_dump(func_get_args());
exit;
}
What happened
- I get redirected to
http://localhost:8080/products/test/xx%2Fyy
- The var dump shows:
/var/www/src/Controller/ProductsController.php:54:
array (size=2)
0 => string 'xx' (length=2)
1 => string 'yy' (length=2)
What you expected to happen
- To get redirected to
http://localhost:8080/products/test/xx%2Fyy
- The var dump to show:
/var/www/src/Controller/ProductsController.php:54:
array (size=1)
0 => string 'xx/yy' (length=5)
What is causing this
In d5283af urldecode got added. Which is still present in 4.2.1.
if (!preg_match($compiledRoute, urldecode($url), $route)) {
return null;
}
This line of code decodes the entire URL before routing the request. Causing this bug. Changing it to if(!preg_match($compiledRoute, $url, $route)) fixed the problem.
Please be aware that all the params are indvidually encoded on Route.php#L794 and decoded on Route.php#L575
So we are now encoding once, and decoding twice, which doesn't make any sense to me.
Disclaimer
I fully understand why this is happening, because of international URI (IRI) which might contain characters like آموزش and I respect that. But I think we should think of another solution, because very basic functionality and expected behavior is now broken.
This is a (multiple allowed):
bug
enhancement
feature-discussion (RFC)
CakePHP Version: 4.2.1
What you did
Obviously this is not exactly what I am trying to do, but this is the simplest way I can show what is happening.
What happened
http://localhost:8080/products/test/xx%2FyyWhat you expected to happen
http://localhost:8080/products/test/xx%2FyyWhat is causing this
In d5283af
urldecodegot added. Which is still present in 4.2.1.This line of code decodes the entire URL before routing the request. Causing this bug. Changing it to
if(!preg_match($compiledRoute, $url, $route))fixed the problem.Please be aware that all the params are indvidually encoded on Route.php#L794 and decoded on Route.php#L575
So we are now encoding once, and decoding twice, which doesn't make any sense to me.
Disclaimer
I fully understand why this is happening, because of international URI (IRI) which might contain characters like
آموزشand I respect that. But I think we should think of another solution, because very basic functionality and expected behavior is now broken.