Merge branch 'daniel-sc-552-handle-encoded-slashes-in-url-param'

pull/556/head
Austin Collier 10 months ago
commit ebe0613589

@ -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,67 @@ 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');
}
public function testUrlParametersWithRealSlash()
{
$this->router->map('/redirect/@id', function ($id) {
echo $id;
});
$this->request->url = '/redirect/before/after';
$this->check('404');
}
public function testUrlParametersWithJapanese()
{
$this->router->map('/わたしはひとです', function () {
echo 'はい';
});
$this->request->url = '/わたしはひとです';
$this->check('はい');
}
public function testUrlParametersWithJapaneseAndParam()
{
$this->router->map('/わたしはひとです/@name', function ($name) {
echo $name;
});
$this->request->url = '/'.urlencode('わたしはひとです').'/'.urlencode('ええ');
$this->check('ええ');
}
// Passing URL parameters matched with regular expression for a URL containing Cyrillic letters:
public function testRegExParametersCyrillic()
{
$this->router->map('/категория/@name:[абвгдеёжзийклмнопрстуфхцчшщъыьэюя]+', function ($name) {
echo $name;
});
$this->request->url = '/'.urlencode('категория').'/'.urlencode('цветя');
$this->check('цветя');
}
public function testRegExOnlyCyrillicUrl()
{
$this->router->map('/категория/цветя', function () {
echo 'цветя';
});
$this->request->url = '/категория/цветя';
$this->check('цветя');
}
// Passing URL parameters matched with regular expression
public function testRegExParameters()
{
@ -384,17 +445,6 @@ class RouterTest extends TestCase
$this->check('404');
}
// Passing URL parameters matched with regular expression for a URL containing Cyrillic letters:
public function testRegExParametersCyrillic()
{
$this->router->map('/категория/@name:[абвгдеёжзийклмнопрстуфхцчшщъыьэюя]+', function ($name) {
echo $name;
});
$this->request->url = urlencode('/категория/цветя');
$this->check('цветя');
}
public function testGetAndClearRoutes()
{
$this->router->map('/path1', [$this, 'ok']);

@ -78,6 +78,9 @@ class LayoutMiddleware
<li><a href="/redirect">Redirect</a></li>
<li><a href="/streamResponse">Stream</a></li>
<li><a href="/overwrite">Overwrite Body</a></li>
<li><a href="/redirect/before%2Fafter">Slash in Param</a></li>
<li><a href="/わたしはひとです">UTF8 URL</a></li>
<li><a href="/わたしはひとです/ええ">UTF8 URL w/ Param</a></li>
</ul>
HTML;
echo '<div id="container">';

@ -124,6 +124,21 @@ Flight::group('', function () {
Flight::route('/overwrite', function () {
echo '<span id="infotext">Route text:</span> This route status is that it <span style="color:red; font-weight: bold;">failed</span>';
})->addMiddleware([new OverwriteBodyMiddleware()]);
// Test 15: UTF8 Chars in url
Flight::route('/わたしはひとです', function () {
echo '<span id="infotext">Route text:</span> This route status is that it <span style="color:green; font-weight: bold;">succeeded はい!!!</span>';
});
// Test 16: UTF8 Chars in url with utf8 params
Flight::route('/わたしはひとです/@name', function ($name) {
echo '<span id="infotext">Route text:</span> This route status is that it <span style="color:'.($name === 'ええ' ? 'green' : 'red').'; font-weight: bold;">'.($name === 'ええ' ? 'succeeded' : 'failed').' URL Param: '.$name.'</span>';
});
// Test 17: Slash in param
Flight::route('/redirect/@id', function ($id) {
echo '<span id="infotext">Route text:</span> This route status is that it <span style="color:'.($id === 'before/after' ? 'green' : 'red').'; font-weight: bold;">'.($id === 'before/after' ? 'succeeded' : 'failed').' URL Param: '.$id.'</span>';
});
}, [ new LayoutMiddleware() ]);
// Test 9: JSON output (should not output any other html)

Loading…
Cancel
Save