From 2097d5a968e57ea72bbe1710b667e20130374402 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 17 Feb 2012 21:09:48 -0500 Subject: [PATCH 1/5] Fix duplicate items in HABTM associations. Apply patch from 'Kim Biesbjerg'. Fixes issues where nested HABTM associations would create duplicate content. Fixes #2564 Fixes #1598 --- lib/Cake/Model/Datasource/DboSource.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index 575af5493..191f51f6d 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -1389,14 +1389,16 @@ class DboSource extends DataSource { } } else { foreach ($merge as $i => $row) { + $insert = array(); if (count($row) === 1) { - if (empty($data[$association]) || (isset($data[$association]) && !in_array($row[$association], $data[$association]))) { - $data[$association][] = $row[$association]; - } - } elseif (!empty($row)) { - $tmp = array_merge($row[$association], $row); - unset($tmp[$association]); - $data[$association][] = $tmp; + $insert = $row[$association]; + } elseif (isset($row[$association])) { + $insert = array_merge($row[$association], $row); + unset($insert[$association]); + } + + if (empty($data[$association]) || (isset($data[$association]) && !in_array($insert, $data[$association], true))) { + $data[$association][] = $insert; } } } From 2f51ef00ed4cd215e797c6c80c6c9aaeb2c4f34f Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 18 Feb 2012 10:53:47 -0500 Subject: [PATCH 2/5] Add failing tests for patches from 'teddyzeenny'. --- lib/Cake/Test/Case/Network/CakeRequestTest.php | 14 ++++++++++++++ .../Test/Case/Routing/Route/CakeRouteTest.php | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index c1bf4a8e6..d10fc4dc2 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -1113,6 +1113,20 @@ class CakeRequestTest extends CakeTestCase { $this->assertEquals(array(), $request->query); } +/** + * Test that a request with urlencoded bits in the main GET parameter are filtered out. + * + * @return void + */ + public function testGetParamWithUrlencodedElement() { + $_GET['/posts/add/∂∂'] = ''; + $_SERVER['PHP_SELF'] = '/cake_dev/app/webroot/index.php'; + $_SERVER['REQUEST_URI'] = '/cake_dev/posts/add/%2202%2202'; + + $request = new CakeRequest(); + $this->assertEquals(array(), $request->query); + } + /** * generator for environment configurations * diff --git a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php index ace61e181..a75fe1a43 100644 --- a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php +++ b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php @@ -508,6 +508,23 @@ class CakeRouteTest extends CakeTestCase { $this->assertEquals($result['action'], 'index'); } +/** + * Test that :key elements are urldecoded + * + * @return void + */ + public function testParseUrlDecodeElements() { + $route = new Cakeroute( + '/:controller/:slug', + array('action' => 'view') + ); + $route->compile(); + $result = $route->parse('/posts/%2202%2202'); + $this->assertEquals($result['controller'], 'posts'); + $this->assertEquals($result['action'], 'view'); + $this->assertEquals($result['slug'], '∂∂'); + } + /** * test numerically indexed defaults, get appeneded to pass * From e6905b44c3d4512b6989c59a1489bc983d88bcdc Mon Sep 17 00:00:00 2001 From: teddy Date: Sat, 18 Feb 2012 14:33:34 +0200 Subject: [PATCH 3/5] urldecode custom route element values --- lib/Cake/Routing/Route/CakeRoute.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Routing/Route/CakeRoute.php b/lib/Cake/Routing/Route/CakeRoute.php index 2452d273b..85c28c521 100644 --- a/lib/Cake/Routing/Route/CakeRoute.php +++ b/lib/Cake/Routing/Route/CakeRoute.php @@ -221,7 +221,13 @@ class CakeRoute { } $route[$key] = $value; } - + + foreach ($this->keys as $key) { + if (isset($route[$key])) { + $route[$key] = rawurldecode($route[$key]); + } + } + if (isset($route['_args_'])) { list($pass, $named) = $this->_parseArgs($route['_args_'], $route); $route['pass'] = array_merge($route['pass'], $pass); From 0ea00c5f07f17ea8c6bbce81a52116c06d053089 Mon Sep 17 00:00:00 2001 From: teddy Date: Sat, 18 Feb 2012 12:35:52 +0200 Subject: [PATCH 4/5] urldecode $this->url before unsetting it from CakeRequest->query --- lib/Cake/Network/CakeRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index 2b3e7ed75..f05319f87 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -184,7 +184,7 @@ class CakeRequest implements ArrayAccess { $query = $_GET; } - unset($query['/' . str_replace('.', '_', $this->url)]); + unset($query['/' . str_replace('.', '_', urldecode($this->url))]); if (strpos($this->url, '?') !== false) { list(, $querystr) = explode('?', $this->url); parse_str($querystr, $queryArgs); From fce70df6ff26da0b63fa342e024f524faed18213 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 18 Feb 2012 11:18:03 -0500 Subject: [PATCH 5/5] Fix failing tests. rawurlencode() and urlencode() handle utf8 differently. --- lib/Cake/Test/Case/Network/CakeRequestTest.php | 2 +- lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index d10fc4dc2..7bba6bd56 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -1121,7 +1121,7 @@ class CakeRequestTest extends CakeTestCase { public function testGetParamWithUrlencodedElement() { $_GET['/posts/add/∂∂'] = ''; $_SERVER['PHP_SELF'] = '/cake_dev/app/webroot/index.php'; - $_SERVER['REQUEST_URI'] = '/cake_dev/posts/add/%2202%2202'; + $_SERVER['REQUEST_URI'] = '/cake_dev/posts/add/%E2%88%82%E2%88%82'; $request = new CakeRequest(); $this->assertEquals(array(), $request->query); diff --git a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php index a75fe1a43..64ca3d7ce 100644 --- a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php +++ b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php @@ -519,7 +519,12 @@ class CakeRouteTest extends CakeTestCase { array('action' => 'view') ); $route->compile(); - $result = $route->parse('/posts/%2202%2202'); + $result = $route->parse('/posts/%E2%88%82%E2%88%82'); + $this->assertEquals($result['controller'], 'posts'); + $this->assertEquals($result['action'], 'view'); + $this->assertEquals($result['slug'], '∂∂'); + + $result = $route->parse('/posts/∂∂'); $this->assertEquals($result['controller'], 'posts'); $this->assertEquals($result['action'], 'view'); $this->assertEquals($result['slug'], '∂∂');