Fix missing urlencod/urldecode in routing.

Named params and passed args should be urlencoded, as they
may contain non-ascii characters.

Refs GH-214
This commit is contained in:
mark_story 2011-10-29 20:42:07 -04:00
parent 66cf86c154
commit 92f9a6c1db
2 changed files with 12 additions and 6 deletions

View file

@ -272,11 +272,11 @@ class CakeRoute {
$separatorIsPresent = strpos($param, $namedConfig['separator']) !== false; $separatorIsPresent = strpos($param, $namedConfig['separator']) !== false;
if ((!isset($this->options['named']) || !empty($this->options['named'])) && $separatorIsPresent) { if ((!isset($this->options['named']) || !empty($this->options['named'])) && $separatorIsPresent) {
list($key, $val) = explode($namedConfig['separator'], $param, 2); list($key, $val) = explode($namedConfig['separator'], $param, 2);
$val = urldecode($val); $val = rawurldecode($val);
$hasRule = isset($rules[$key]); $hasRule = isset($rules[$key]);
$passIt = (!$hasRule && !$greedy) || ($hasRule && !$this->_matchNamed($val, $rules[$key], $context)); $passIt = (!$hasRule && !$greedy) || ($hasRule && !$this->_matchNamed($val, $rules[$key], $context));
if ($passIt) { if ($passIt) {
$pass[] = $param; $pass[] = rawurldecode($param);
} else { } else {
if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) { if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) {
$matches = array_reverse($matches); $matches = array_reverse($matches);
@ -297,7 +297,7 @@ class CakeRoute {
$named = array_merge_recursive($named, array($key => $val)); $named = array_merge_recursive($named, array($key => $val));
} }
} else { } else {
$pass[] = $param; $pass[] = rawurldecode($param);
} }
} }
return array($pass, $named); return array($pass, $named);
@ -463,7 +463,7 @@ class CakeRoute {
} }
if (is_array($params['pass'])) { if (is_array($params['pass'])) {
$params['pass'] = implode('/', $params['pass']); $params['pass'] = implode('/', array_map('rawurlencode', $params['pass']));
} }
$namedConfig = Router::namedConfig(); $namedConfig = Router::namedConfig();
@ -474,10 +474,10 @@ class CakeRoute {
foreach ($params['named'] as $key => $value) { foreach ($params['named'] as $key => $value) {
if (is_array($value)) { if (is_array($value)) {
foreach ($value as $namedKey => $namedValue) { foreach ($value as $namedKey => $namedValue) {
$named[] = $key . "[$namedKey]" . $separator . $namedValue; $named[] = $key . "[$namedKey]" . $separator . rawurlencode($namedValue);
} }
} else { } else {
$named[] = $key . $separator . $value; $named[] = $key . $separator . rawurlencode($value);
} }
} }
$params['pass'] = $params['pass'] . '/' . implode('/', $named); $params['pass'] = $params['pass'] . '/' . implode('/', $named);

View file

@ -369,6 +369,8 @@ class CakeRouteTest extends CakeTestCase {
$result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5, 'page' => 1, 'limit' => 20, 'order' => 'title')); $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5, 'page' => 1, 'limit' => 20, 'order' => 'title'));
$this->assertEqual($result, '/posts/view/5/page:1/limit:20/order:title'); $this->assertEqual($result, '/posts/view/5/page:1/limit:20/order:title');
$result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 'word space', 'order' => 'Θ'));
$this->assertEqual($result, '/posts/view/word%20space/order:%CE%98');
$route = new CakeRoute('/test2/*', array('controller' => 'pages', 'action' => 'display', 2)); $route = new CakeRoute('/test2/*', array('controller' => 'pages', 'action' => 'display', 2));
$result = $route->match(array('controller' => 'pages', 'action' => 'display', 1)); $result = $route->match(array('controller' => 'pages', 'action' => 'display', 1));
@ -395,6 +397,10 @@ class CakeRouteTest extends CakeTestCase {
$result = $route->parse('/posts/index/page[]:%CE%98'); $result = $route->parse('/posts/index/page[]:%CE%98');
$this->assertEquals('Θ', $result['named']['page'][0]); $this->assertEquals('Θ', $result['named']['page'][0]);
$result = $route->parse('/posts/index/something%20else/page[]:%CE%98');
$this->assertEquals('Θ', $result['named']['page'][0]);
$this->assertEquals('something else', $result['pass'][0]);
} }
/** /**