From e741d79f9a27e52c7f3e89ec4cbf3ceb142b8354 Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Wed, 7 Mar 2012 06:06:59 +0330 Subject: [PATCH 1/4] urldecode trailing pass --- lib/Cake/Routing/Route/CakeRoute.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Routing/Route/CakeRoute.php b/lib/Cake/Routing/Route/CakeRoute.php index a81ec402d..28d3417ec 100644 --- a/lib/Cake/Routing/Route/CakeRoute.php +++ b/lib/Cake/Routing/Route/CakeRoute.php @@ -240,7 +240,7 @@ class CakeRoute { } if (isset($route['_trailing_'])) { - $route['pass'][] = $route['_trailing_']; + $route['pass'][] = rawurldecode($route['_trailing_']); unset($route['_trailing_']); } From 5e9af65486399ef3f9fb786920e26e40f2484d04 Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Wed, 7 Mar 2012 08:50:11 +0330 Subject: [PATCH 2/4] testParseTrailingUTF8 --- .../Test/Case/Routing/Route/CakeRouteTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php index d4bf61cf4..2f68d90fb 100644 --- a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php +++ b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php @@ -857,4 +857,23 @@ class CakeRouteTest extends CakeTestCase { ); $this->assertEquals($expected, $result); } + +/** + * Test the /** special type on parsing - UTF8. + * + * @return void + */ + + public function testParseTrailingUTF8() { + $route = new CakeRoute('/:controller/:action/**'); + $result = $route->parse('/posts/index/موبایل'); + $expected = array( + 'controller' => 'posts', + 'action' => 'index', + 'pass' => array('موبایل'), + 'named' => array() + ); + $this->assertEquals($expected, $result); + + } } From 683607de5e3b50cfdeeea0e19013b8ac0c10cc99 Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Wed, 7 Mar 2012 21:51:09 +0330 Subject: [PATCH 3/4] fix test Parse Trailing UTF8 --- lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php index 2f68d90fb..55f836339 100644 --- a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php +++ b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php @@ -865,10 +865,10 @@ class CakeRouteTest extends CakeTestCase { */ public function testParseTrailingUTF8() { - $route = new CakeRoute('/:controller/:action/**'); - $result = $route->parse('/posts/index/موبایل'); + $route = new CakeRoute( '/category/**', array('controller' => 'categories','action' => 'index')); + $result = $route->parse('/category/%D9%85%D9%88%D8%A8%D8%A7%DB%8C%D9%84'); $expected = array( - 'controller' => 'posts', + 'controller' => 'categories', 'action' => 'index', 'pass' => array('موبایل'), 'named' => array() From 150c9fc6a3be0a86791202e76b5f0f2578c310fd Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 8 Mar 2012 21:05:28 -0500 Subject: [PATCH 4/4] Remove parse_str() its buggy and wrong. parse_str() replaces `.` with _ and drops duplicated keys, which is incorrect. Replace parse_str with an updated version of parseQuery from 1.x Fixes #2629 Fixes #2647 --- lib/Cake/Network/Http/HttpSocket.php | 53 ++++++++++++++++++- .../Test/Case/Network/Http/HttpSocketTest.php | 10 +++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/Http/HttpSocket.php b/lib/Cake/Network/Http/HttpSocket.php index 3dd78cff8..cc9ed8d84 100644 --- a/lib/Cake/Network/Http/HttpSocket.php +++ b/lib/Cake/Network/Http/HttpSocket.php @@ -768,7 +768,58 @@ class HttpSocket extends CakeSocket { if (is_array($query)) { return $query; } - parse_str(ltrim($query, '?'), $parsedQuery); + + if (is_array($query)) { + return $query; + } + $parsedQuery = array(); + + if (is_string($query) && !empty($query)) { + $query = preg_replace('/^\?/', '', $query); + $items = explode('&', $query); + + foreach ($items as $item) { + if (strpos($item, '=') !== false) { + list($key, $value) = explode('=', $item, 2); + } else { + $key = $item; + $value = null; + } + + $key = urldecode($key); + $value = urldecode($value); + + if (preg_match_all('/\[([^\[\]]*)\]/iUs', $key, $matches)) { + $subKeys = $matches[1]; + $rootKey = substr($key, 0, strpos($key, '[')); + if (!empty($rootKey)) { + array_unshift($subKeys, $rootKey); + } + $queryNode =& $parsedQuery; + + foreach ($subKeys as $subKey) { + if (!is_array($queryNode)) { + $queryNode = array(); + } + + if ($subKey === '') { + $queryNode[] = array(); + end($queryNode); + $subKey = key($queryNode); + } + $queryNode =& $queryNode[$subKey]; + } + $queryNode = $value; + continue; + } + if (!isset($parsedQuery[$key])) { + $parsedQuery[$key] = $value; + } else { + $parsedQuery[$key] = (array)$parsedQuery[$key]; + $parsedQuery[$key][] = $value; + } + } + } return $parsedQuery; } diff --git a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php index 6869e83a8..991a9cd87 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php @@ -1450,7 +1450,15 @@ class HttpSocketTest extends CakeTestCase { ), 'empty' => '' ); - $this->assertEquals($query, $expectedQuery); + $this->assertEquals($expectedQuery, $query); + + $query = 'openid.ns=example.com&foo=bar&foo=baz'; + $result = $this->Socket->parseQuery($query); + $expected = array( + 'openid.ns' => 'example.com', + 'foo' => array('bar', 'baz') + ); + $this->assertEquals($expected, $result); } /**