fix: handle encoded slashes for url parameters - fixes #552

pull/553/head
Daniel Schreiber 11 months ago
parent 043debdda8
commit e6a29c7476

@ -97,7 +97,7 @@ class Route
/**
* Checks if a URL matches the route pattern. Also parses named parameters in the URL.
*
* @param string $url Requested URL
* @param string $url Requested URL (original format, not URL decoded)
* @param bool $case_sensitive Case sensitive matching
*
* @return bool Match status
@ -127,11 +127,18 @@ class Route
}
}
$this->splat = strval(substr($url, $i + 1));
$this->splat = urldecode(strval(substr($url, $i + 1)));
}
// Build the regex for matching
$regex = str_replace([')', '/*'], [')?', '(/?|/.*?)'], $this->pattern);
$pattern_utf_chars_encoded = preg_replace_callback(
'#(\\p{L}+)#u',
static function ($matches) {
return urlencode($matches[0]);
},
$this->pattern
);
$regex = str_replace([')', '/*'], [')?', '(/?|/.*?)'], $pattern_utf_chars_encoded);
$regex = preg_replace_callback(
'#@([\w]+)(:([^/\(\)]*))?#',

@ -215,9 +215,8 @@ class Router
*/
public function route(Request $request)
{
$url_decoded = urldecode($request->url);
while ($route = $this->current()) {
if ($route->matchMethod($request->method) && $route->matchUrl($url_decoded, $this->case_sensitive)) {
if ($route->matchMethod($request->method) && $route->matchUrl($request->url, $this->case_sensitive)) {
$this->executedRoute = $route;
return $route;
}

@ -198,6 +198,16 @@ class RouterTest extends TestCase
$this->check('123');
}
public function testUrlParametersWithEncodedSlash()
{
$this->router->map('/redirect/@id', function ($id) {
echo $id;
});
$this->request->url = '/redirect/before%2Fafter';
$this->check('before/after');
}
// Passing URL parameters matched with regular expression
public function testRegExParameters()
{
@ -390,7 +400,7 @@ class RouterTest extends TestCase
$this->router->map('/категория/@name:[абвгдеёжзийклмнопрстуфхцчшщъыьэюя]+', function ($name) {
echo $name;
});
$this->request->url = urlencode('/категория/цветя');
$this->request->url = '/' . urlencode('категория') . '/' . urlencode('цветя');
$this->check('цветя');
}

Loading…
Cancel
Save