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. * 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 * @param bool $case_sensitive Case sensitive matching
* *
* @return bool Match status * @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 // 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( $regex = preg_replace_callback(
'#@([\w]+)(:([^/\(\)]*))?#', '#@([\w]+)(:([^/\(\)]*))?#',

@ -215,9 +215,8 @@ class Router
*/ */
public function route(Request $request) public function route(Request $request)
{ {
$url_decoded = urldecode($request->url);
while ($route = $this->current()) { 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; $this->executedRoute = $route;
return $route; return $route;
} }

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

Loading…
Cancel
Save