From 2c112095a94706f0a438478fe714908f67786228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1igo=20In=20The=20Cloud?= Date: Mon, 27 Jun 2016 14:15:05 -0400 Subject: [PATCH 01/39] Issue #9040 - Auth saving json in Auth.redirect AuthComponent is storing JSON or any other AJAX request URL into the session variable Auth.redirect used for login redirect if the AJAX request does not send the X-Requested-With:XMLHttpRequest header. If you send an ajax request without that header and your request is not a (.json) it will store the URL anyway. --- lib/Cake/Controller/Component/AuthComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/AuthComponent.php b/lib/Cake/Controller/Component/AuthComponent.php index 3381d68f1..1b65fd921 100644 --- a/lib/Cake/Controller/Component/AuthComponent.php +++ b/lib/Cake/Controller/Component/AuthComponent.php @@ -359,7 +359,7 @@ class AuthComponent extends Component { return true; } - if (!$controller->request->is('ajax')) { + if (!$controller->request->is('ajax') && !$controller->request->is('json')) { $this->flash($this->authError); $this->Session->write('Auth.redirect', $controller->request->here(false)); $controller->redirect($this->loginAction); From 57e0a9748308557a89f09521a56bfd1111430155 Mon Sep 17 00:00:00 2001 From: nojimage Date: Sat, 21 May 2016 11:01:49 +0900 Subject: [PATCH 02/39] refs #8654 FormHelper cleanup unlockFields key --- .../Test/Case/View/Helper/FormHelperTest.php | 23 +++++++++++++++++++ lib/Cake/View/Helper/FormHelper.php | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index f72ea120d..6ca879919 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -1619,6 +1619,29 @@ class FormHelperTest extends CakeTestCase { $this->assertEquals(1, $this->Form->fields['Contact.id'], 'Hidden input should be secured.'); } +/** + * test unlockField removing from fields array. multiple field version. + * + * @return void + */ + public function testUnlockMultipleFieldRemovingFromFields() { + $this->Form->request['_Token'] = array( + 'key' => 'testKey', + 'unlockedFields' => array() + ); + $this->Form->create('Order'); + $this->Form->hidden('Order.id', array('value' => 1)); + $this->Form->checkbox('Ticked.id.'); + $this->Form->checkbox('Ticked.id.'); + + $this->assertEquals(1, $this->Form->fields['Order.id'], 'Hidden input should be secured.'); + $this->assertTrue(in_array('Ticked.id', $this->Form->fields), 'Field should be secured.'); + + $this->Form->unlockField('Order.id'); + $this->Form->unlockField('Ticked.id'); + $this->assertEquals(array(), $this->Form->fields); + } + /** * testTagIsInvalid method * diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index f52b74ded..e4cbfda9c 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -666,6 +666,10 @@ class FormHelper extends AppHelper { $field = Hash::filter(explode('.', $field)); } + if (is_array($field)) { + $field = array_filter($field, 'strlen'); + } + foreach ($this->_unlockedFields as $unlockField) { $unlockParts = explode('.', $unlockField); if (array_values(array_intersect($field, $unlockParts)) === $unlockParts) { From 7c2d6ae1977c9c135de95177c488b1a8875fc9d6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 28 Jun 2016 22:06:53 -0400 Subject: [PATCH 03/39] Combine code paths. At the end of both if/else arms we should have an array that can be pushed through Hash::filter(). Refs #8654 --- lib/Cake/View/Helper/FormHelper.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index e4cbfda9c..ea190ca6b 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -663,11 +663,10 @@ class FormHelper extends AppHelper { if (!$field) { $field = $this->entity(); } elseif (is_string($field)) { - $field = Hash::filter(explode('.', $field)); + $field = explode('.', $field); } - if (is_array($field)) { - $field = array_filter($field, 'strlen'); + $field = Hash::filter($field); } foreach ($this->_unlockedFields as $unlockField) { From 3a42ecc61cdd73b853375f5512724cf775f6bcb1 Mon Sep 17 00:00:00 2001 From: Alex Para Date: Fri, 1 Jul 2016 11:11:16 +0300 Subject: [PATCH 04/39] fixes #9064 - added new locale for Icelandic language --- lib/Cake/I18n/L10n.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Cake/I18n/L10n.php b/lib/Cake/I18n/L10n.php index 7e57a36fb..d2d540559 100644 --- a/lib/Cake/I18n/L10n.php +++ b/lib/Cake/I18n/L10n.php @@ -272,6 +272,7 @@ class L10n { 'hy' => array('language' => 'Armenian - Armenia', 'locale' => 'hye', 'localeFallback' => 'hye', 'charset' => 'utf-8', 'direction' => 'ltr'), 'id' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'), 'is' => array('language' => 'Icelandic', 'locale' => 'isl', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'), + 'is-is' => array('language' => 'Icelandic', 'locale' => 'is_is', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'), 'it' => array('language' => 'Italian', 'locale' => 'ita', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'), 'it-ch' => array('language' => 'Italian (Swiss) ', 'locale' => 'it_ch', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ja' => array('language' => 'Japanese', 'locale' => 'jpn', 'localeFallback' => 'jpn', 'charset' => 'utf-8', 'direction' => 'ltr'), From 58a31ecfe5bccaaf8f2a71c070ac517d1fed7d76 Mon Sep 17 00:00:00 2001 From: Alex Para Date: Fri, 1 Jul 2016 14:46:27 +0300 Subject: [PATCH 05/39] fixes #9064 --- lib/Cake/I18n/L10n.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/I18n/L10n.php b/lib/Cake/I18n/L10n.php index d2d540559..a87be16c0 100644 --- a/lib/Cake/I18n/L10n.php +++ b/lib/Cake/I18n/L10n.php @@ -272,7 +272,7 @@ class L10n { 'hy' => array('language' => 'Armenian - Armenia', 'locale' => 'hye', 'localeFallback' => 'hye', 'charset' => 'utf-8', 'direction' => 'ltr'), 'id' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'), 'is' => array('language' => 'Icelandic', 'locale' => 'isl', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'), - 'is-is' => array('language' => 'Icelandic', 'locale' => 'is_is', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'), + 'is-is' => array('language' => 'Icelandic (Iceland)', 'locale' => 'is_is', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'), 'it' => array('language' => 'Italian', 'locale' => 'ita', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'), 'it-ch' => array('language' => 'Italian (Swiss) ', 'locale' => 'it_ch', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ja' => array('language' => 'Japanese', 'locale' => 'jpn', 'localeFallback' => 'jpn', 'charset' => 'utf-8', 'direction' => 'ltr'), From e6a3bdf954107f77b53302c8d595b024f989e754 Mon Sep 17 00:00:00 2001 From: ADmad Date: Fri, 1 Jul 2016 17:28:50 +0530 Subject: [PATCH 06/39] Make stickler ignore 2.x and 2.next branches. --- .stickler.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .stickler.yml diff --git a/.stickler.yml b/.stickler.yml new file mode 100644 index 000000000..61243f090 --- /dev/null +++ b/.stickler.yml @@ -0,0 +1,2 @@ +branches: + ignore: ['2.x', '2.next'] From d816ea6e1603f10c7878c4bb2af74daf4c9a78eb Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 30 Jun 2016 23:08:43 -0400 Subject: [PATCH 07/39] Add test showing that niceShort translates month names. Refs #8968 --- lib/Cake/Test/Case/Utility/CakeTimeTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/Cake/Test/Case/Utility/CakeTimeTest.php b/lib/Cake/Test/Case/Utility/CakeTimeTest.php index 2620f7897..f5741272f 100644 --- a/lib/Cake/Test/Case/Utility/CakeTimeTest.php +++ b/lib/Cake/Test/Case/Utility/CakeTimeTest.php @@ -454,6 +454,17 @@ class CakeTimeTest extends CakeTestCase { $this->_restoreSystemTimezone(); } +/** + * testNiceShort translations + * + * @return void + */ + public function testNiceShortI18n() { + setlocale(LC_ALL, 'es_ES'); + $time = strtotime('2015-01-07 03:05:00'); + $this->assertEquals('ene 7th 2015, 03:05', $this->Time->niceShort($time)); + } + /** * testDaysAsSql method * From 234f732d6dfec0c1ddfc59abb0530a1194241e57 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 1 Jul 2016 17:15:23 -0400 Subject: [PATCH 08/39] Attempt to get tests passing on travis. Also attempt to get stickler to ignore the 2.x branch. --- .travis.yml | 1 + lib/Cake/Test/Case/Utility/CakeTimeTest.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index c3492d555..b43db1d25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ before_script: - sh -c "composer global require 'phpunit/phpunit=3.7.33'" - sh -c "ln -s ~/.composer/vendor/phpunit/phpunit/PHPUnit ./vendors/PHPUnit" - sudo locale-gen de_DE + - sudo locale-gen es_ES - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test2;'; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test3;'; fi" diff --git a/lib/Cake/Test/Case/Utility/CakeTimeTest.php b/lib/Cake/Test/Case/Utility/CakeTimeTest.php index f5741272f..dc2a8887c 100644 --- a/lib/Cake/Test/Case/Utility/CakeTimeTest.php +++ b/lib/Cake/Test/Case/Utility/CakeTimeTest.php @@ -460,9 +460,11 @@ class CakeTimeTest extends CakeTestCase { * @return void */ public function testNiceShortI18n() { + $restore = setlocale(LC_ALL, 0); setlocale(LC_ALL, 'es_ES'); $time = strtotime('2015-01-07 03:05:00'); $this->assertEquals('ene 7th 2015, 03:05', $this->Time->niceShort($time)); + setlocale(LC_ALL, $restore); } /** From f22129b9c73734b3c62dc5570d290f02d67c9bf1 Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Wed, 6 Jul 2016 00:25:46 +0200 Subject: [PATCH 09/39] Store user data in memory on login for stateless auth adapters --- lib/Cake/Controller/Component/AuthComponent.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Controller/Component/AuthComponent.php b/lib/Cake/Controller/Component/AuthComponent.php index 1b65fd921..3e62e2cc9 100644 --- a/lib/Cake/Controller/Component/AuthComponent.php +++ b/lib/Cake/Controller/Component/AuthComponent.php @@ -611,8 +611,12 @@ class AuthComponent extends Component { $user = $this->identify($this->request, $this->response); } if ($user) { - $this->Session->renew(); - $this->Session->write(static::$sessionKey, $user); + if (static::$sessionKey) { + $this->Session->renew(); + $this->Session->write(static::$sessionKey, $user); + } else { + static::$_user = $user; + } $event = new CakeEvent('Auth.afterIdentify', $this, array('user' => $user)); $this->_Collection->getController()->getEventManager()->dispatch($event); } From c63de8d9f578cab2372b5e938b6b9aba0382c66d Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Wed, 6 Jul 2016 12:34:23 +0200 Subject: [PATCH 10/39] Added test to prove stateless login sets user --- .../Component/AuthComponentTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php index 0ff514df6..80d6cda58 100644 --- a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php @@ -1721,6 +1721,25 @@ class AuthComponentTest extends CakeTestCase { $this->Auth->startup($this->Controller); } +/** + * testStatelessLoginSetsUser method + * + * @return void + */ + public function testStatelessLoginSetsUser() { + $user = array( + 'id' => 1, + 'username' => 'mark' + ); + + AuthComponent::$sessionKey = false; + $result = $this->Auth->login($user); + $this->assertTrue($result); + + $this->assertTrue($this->Auth->loggedIn()); + $this->assertEquals($user, $this->Auth->user()); + } + /** * testStatelessAuthNoSessionStart method * From 0ea315b2e0c927e06ffeb1b1993c9cc8506ed08e Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Thu, 7 Jul 2016 08:58:51 +0200 Subject: [PATCH 11/39] Add assertion to prove session is not started on stateless login --- .../Test/Case/Controller/Component/AuthComponentTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php index 80d6cda58..33292662f 100644 --- a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php @@ -1722,11 +1722,11 @@ class AuthComponentTest extends CakeTestCase { } /** - * testStatelessLoginSetsUser method + * testStatelessLoginSetUserNoSessionStart method * * @return void */ - public function testStatelessLoginSetsUser() { + public function testStatelessLoginSetUserNoSessionStart() { $user = array( 'id' => 1, 'username' => 'mark' @@ -1738,6 +1738,8 @@ class AuthComponentTest extends CakeTestCase { $this->assertTrue($this->Auth->loggedIn()); $this->assertEquals($user, $this->Auth->user()); + + $this->assertNull($this->Auth->Session->started()); } /** From 1d7a4da903e2b11c948f2ff4541f44c8eb481b27 Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Thu, 7 Jul 2016 09:24:33 +0200 Subject: [PATCH 12/39] Fixed wrong assertion --- lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php index 33292662f..00e1b3559 100644 --- a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php @@ -1739,7 +1739,7 @@ class AuthComponentTest extends CakeTestCase { $this->assertTrue($this->Auth->loggedIn()); $this->assertEquals($user, $this->Auth->user()); - $this->assertNull($this->Auth->Session->started()); + $this->assertFalse($this->Auth->Session->started()); } /** From 7edcdb0799520904c5d1c7ad97e6057e249a99e5 Mon Sep 17 00:00:00 2001 From: Philippe Saint-Just Date: Sat, 9 Jul 2016 16:08:16 +0100 Subject: [PATCH 13/39] Handle plugin association consistently --- lib/Cake/Model/Model.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index ccbae1789..660043040 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -1035,13 +1035,13 @@ class Model extends Object implements CakeEventListener { unset($association[$assoc]); $assoc = $value; $value = array(); - - if (strpos($assoc, '.') !== false) { - list($plugin, $assoc) = pluginSplit($assoc, true); - $association[$assoc] = array('className' => $plugin . $assoc); - } else { - $association[$assoc] = $value; - } + $association[$assoc] = $value; + } + + if (!isset($value['className']) && strpos($assoc, '.') !== false) { + unset($association[$assoc]); + list($plugin, $assoc) = pluginSplit($assoc, true); + $association[$assoc] = array('className' => $plugin . $assoc) + $value; } $this->_generateAssociation($type, $assoc); From b0e5e39e45faefd3762744cbd4af364f778f68b6 Mon Sep 17 00:00:00 2001 From: Philippe Saint-Just Date: Sun, 10 Jul 2016 09:57:24 +0100 Subject: [PATCH 14/39] Added test case --- lib/Cake/Test/Case/Model/ModelIntegrationTest.php | 4 +++- lib/Cake/Test/Case/Model/models.php | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Model/ModelIntegrationTest.php b/lib/Cake/Test/Case/Model/ModelIntegrationTest.php index 65ab2ad3a..ffab35fa7 100644 --- a/lib/Cake/Test/Case/Model/ModelIntegrationTest.php +++ b/lib/Cake/Test/Case/Model/ModelIntegrationTest.php @@ -1617,10 +1617,12 @@ class ModelIntegrationTest extends BaseModelTest { public function testAutoConstructPluginAssociations() { $Comment = ClassRegistry::init('TestPluginComment'); - $this->assertEquals(2, count($Comment->belongsTo), 'Too many associations'); + $this->assertEquals(3, count($Comment->belongsTo), 'Too many associations'); $this->assertFalse(isset($Comment->belongsTo['TestPlugin.User'])); + $this->assertFalse(isset($Comment->belongsTo['TestPlugin.Source'])); $this->assertTrue(isset($Comment->belongsTo['User']), 'Missing association'); $this->assertTrue(isset($Comment->belongsTo['TestPluginArticle']), 'Missing association'); + $this->assertTrue(isset($Comment->belongsTo['Source']), 'Missing association'); } /** diff --git a/lib/Cake/Test/Case/Model/models.php b/lib/Cake/Test/Case/Model/models.php index f49299444..f42bcae35 100644 --- a/lib/Cake/Test/Case/Model/models.php +++ b/lib/Cake/Test/Case/Model/models.php @@ -2991,7 +2991,10 @@ class TestPluginComment extends CakeTestModel { 'className' => 'TestPlugin.TestPluginArticle', 'foreignKey' => 'article_id', ), - 'TestPlugin.User' + 'TestPlugin.User', + 'TestPlugin.Source' => array( + 'foreignKey' => 'source_id' + ) ); } From be7cecbb0078415a4cbb5004c39718acff8d6b0a Mon Sep 17 00:00:00 2001 From: Philippe Saint-Just Date: Sun, 10 Jul 2016 14:02:55 +0100 Subject: [PATCH 15/39] Removed whitespace --- lib/Cake/Model/Model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 660043040..6148317af 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -1037,7 +1037,7 @@ class Model extends Object implements CakeEventListener { $value = array(); $association[$assoc] = $value; } - + if (!isset($value['className']) && strpos($assoc, '.') !== false) { unset($association[$assoc]); list($plugin, $assoc) = pluginSplit($assoc, true); From 4e1b601ed8846439d11076895ed913c2bcd85393 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 12 Jul 2016 22:46:47 -0400 Subject: [PATCH 16/39] Don't split strings headers that lack a ':'. Refs #9106 --- lib/Cake/Network/CakeResponse.php | 2 +- lib/Cake/Test/Case/Network/CakeResponseTest.php | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeResponse.php b/lib/Cake/Network/CakeResponse.php index 6bbf68e73..5fdcec44f 100644 --- a/lib/Cake/Network/CakeResponse.php +++ b/lib/Cake/Network/CakeResponse.php @@ -577,7 +577,7 @@ class CakeResponse { if (is_numeric($header)) { list($header, $value) = array($value, null); } - if ($value === null) { + if ($value === null && strpos($header, ':') !== false) { list($header, $value) = explode(':', $header, 2); } $this->_headers[$header] = is_array($value) ? array_map('trim', $value) : trim($value); diff --git a/lib/Cake/Test/Case/Network/CakeResponseTest.php b/lib/Cake/Test/Case/Network/CakeResponseTest.php index effb57daa..cff657d62 100644 --- a/lib/Cake/Test/Case/Network/CakeResponseTest.php +++ b/lib/Cake/Test/Case/Network/CakeResponseTest.php @@ -164,11 +164,15 @@ class CakeResponseTest extends CakeTestCase { $headers += array('Location' => 'http://example.com'); $this->assertEquals($headers, $response->header()); - //Headers with the same name are overwritten + // Headers with the same name are overwritten $response->header('Location', 'http://example2.com'); $headers = array('Location' => 'http://example2.com'); $this->assertEquals($headers, $response->header()); + $response->header('Date', null); + $headers += array('Date' => null); + $this->assertEquals($headers, $response->header()); + $response->header(array('WWW-Authenticate' => 'Negotiate')); $headers += array('WWW-Authenticate' => 'Negotiate'); $this->assertEquals($headers, $response->header()); From bddff7d2b0c57d756b1ec1eadb3e7da7c8236622 Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Wed, 13 Jul 2016 23:40:27 +0200 Subject: [PATCH 17/39] Dispatch afterDispatch event when exception is thrown --- lib/Cake/Error/ExceptionRenderer.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Error/ExceptionRenderer.php b/lib/Cake/Error/ExceptionRenderer.php index a245b64ee..40f551417 100644 --- a/lib/Cake/Error/ExceptionRenderer.php +++ b/lib/Cake/Error/ExceptionRenderer.php @@ -20,9 +20,12 @@ */ App::uses('Sanitize', 'Utility'); +App::uses('Dispatcher', 'Routing'); App::uses('Router', 'Routing'); -App::uses('CakeResponse', 'Network'); App::uses('Controller', 'Controller'); +App::uses('CakeRequest', 'Network'); +App::uses('CakeResponse', 'Network'); +App::uses('CakeEvent', 'Event'); /** * Exception Renderer. @@ -287,7 +290,7 @@ class ExceptionRenderer { protected function _outputMessage($template) { try { $this->controller->render($template); - $this->controller->afterFilter(); + $this->_shutdown(); $this->controller->response->send(); } catch (MissingViewException $e) { $attributes = $e->getAttributes(); @@ -327,4 +330,15 @@ class ExceptionRenderer { $this->controller->response->send(); } + protected function _shutdown() { + $this->controller->afterFilter(); + + $Dispatcher = new Dispatcher(); + $afterDispatchEvent = new CakeEvent('Dispatcher.afterDispatch', $Dispatcher, array( + 'request' => $this->controller->request, + 'response' => $this->controller->response + )); + $Dispatcher->getEventManager()->dispatch($afterDispatchEvent); + } + } From 5a63ee4e3e0daf076cf0f1e0dc957efa7fd9364e Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Thu, 14 Jul 2016 00:17:02 +0200 Subject: [PATCH 18/39] Added tests to prove that Dispatcher.afterDispatch event is dispatched by exception renderer on error response --- .../Test/Case/Error/ExceptionRendererTest.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php index 51cc4ef70..2bff49aea 100644 --- a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php +++ b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php @@ -20,6 +20,7 @@ App::uses('ExceptionRenderer', 'Error'); App::uses('Controller', 'Controller'); App::uses('Component', 'Controller'); App::uses('Router', 'Routing'); +App::uses('CakeEvent', 'Event'); /** * Short description for class. @@ -61,6 +62,26 @@ class BlueberryComponent extends Component { } +/** + * AfterDispatchEventCallable class + * + * @package Cake.Test.Case.Error + */ +class AfterDispatchEventCallable { + + public $afterDispatchCalled = false; +/** + * AfterDispatchEventCallable::afterDispatch() + * + * @param mixed $event + * @return mixed boolean to stop the event dispatching or null to continue + */ + public function afterDispatch(CakeEvent $event) { + $this->afterDispatchCalled = true; + } + +} + /** * TestErrorController class * @@ -877,4 +898,25 @@ class ExceptionRendererTest extends CakeTestCase { $this->assertContains(h('SELECT * from poo_query < 5 and :seven'), $result); $this->assertContains("'seven' => (int) 7", $result); } + +/** + * Tests that exception renderer dispatches Dispatcher.afterDispatch event on error response + * + * @return void + */ + public function testAfterDispatchEventOnErrorResponse() { + $callable = new AfterDispatchEventCallable(); + Configure::write('Dispatcher.filters', array( + array('callable' => array($callable, 'afterDispatch'), 'on' => 'after') + )); + + $exception = new Exception('Oh no!'); + $ExceptionRenderer = new ExceptionRenderer($exception); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertTrue($callable->afterDispatchCalled); + } } From a05639a30e8385c91fd0a1a12f4874f42ccecb49 Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Thu, 14 Jul 2016 00:20:33 +0200 Subject: [PATCH 19/39] Don't save buffered output to var since it is not used --- lib/Cake/Test/Case/Error/ExceptionRendererTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php index 2bff49aea..abd620d68 100644 --- a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php +++ b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php @@ -915,7 +915,7 @@ class ExceptionRendererTest extends CakeTestCase { ob_start(); $ExceptionRenderer->render(); - $result = ob_get_clean(); + ob_get_clean(); $this->assertTrue($callable->afterDispatchCalled); } From c77b6288418fe504dee2491a8272a1255be5cfaa Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Thu, 14 Jul 2016 04:51:49 +0200 Subject: [PATCH 20/39] Dispatch Controller.shutdown instead of calling afterFilter directly. Updated test --- lib/Cake/Error/ExceptionRenderer.php | 3 +- .../Test/Case/Error/ExceptionRendererTest.php | 39 ++++++------------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/lib/Cake/Error/ExceptionRenderer.php b/lib/Cake/Error/ExceptionRenderer.php index 40f551417..4da938167 100644 --- a/lib/Cake/Error/ExceptionRenderer.php +++ b/lib/Cake/Error/ExceptionRenderer.php @@ -331,7 +331,8 @@ class ExceptionRenderer { } protected function _shutdown() { - $this->controller->afterFilter(); + $afterFilterEvent = new CakeEvent('Controller.shutdown', $this->controller); + $this->controller->getEventManager()->dispatch($afterFilterEvent); $Dispatcher = new Dispatcher(); $afterDispatchEvent = new CakeEvent('Dispatcher.afterDispatch', $Dispatcher, array( diff --git a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php index abd620d68..9decaa7e5 100644 --- a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php +++ b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php @@ -20,7 +20,7 @@ App::uses('ExceptionRenderer', 'Error'); App::uses('Controller', 'Controller'); App::uses('Component', 'Controller'); App::uses('Router', 'Routing'); -App::uses('CakeEvent', 'Event'); +App::uses('CakeEventManager', 'Event'); /** * Short description for class. @@ -62,26 +62,6 @@ class BlueberryComponent extends Component { } -/** - * AfterDispatchEventCallable class - * - * @package Cake.Test.Case.Error - */ -class AfterDispatchEventCallable { - - public $afterDispatchCalled = false; -/** - * AfterDispatchEventCallable::afterDispatch() - * - * @param mixed $event - * @return mixed boolean to stop the event dispatching or null to continue - */ - public function afterDispatch(CakeEvent $event) { - $this->afterDispatchCalled = true; - } - -} - /** * TestErrorController class * @@ -905,18 +885,23 @@ class ExceptionRendererTest extends CakeTestCase { * @return void */ public function testAfterDispatchEventOnErrorResponse() { - $callable = new AfterDispatchEventCallable(); - Configure::write('Dispatcher.filters', array( - array('callable' => array($callable, 'afterDispatch'), 'on' => 'after') - )); + $fired = array(); + $listener = function ($event) use (&$fired) { + $fired[] = $event->name(); + }; - $exception = new Exception('Oh no!'); + $EventManager = CakeEventManager::instance(); + $EventManager->attach($listener, 'Controller.shutdown'); + $EventManager->attach($listener, 'Dispatcher.afterDispatch'); + + $exception = new Exception('Terrible'); $ExceptionRenderer = new ExceptionRenderer($exception); ob_start(); $ExceptionRenderer->render(); ob_get_clean(); - $this->assertTrue($callable->afterDispatchCalled); + $expected = array('Controller.shutdown', 'Dispatcher.afterDispatch'); + $this->assertEquals($expected, $fired); } } From 38cad279d187c4e4f84e1fceba2ce7f4d78f3de5 Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Thu, 14 Jul 2016 04:57:25 +0200 Subject: [PATCH 21/39] Updated test method name and description --- lib/Cake/Test/Case/Error/ExceptionRendererTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php index 9decaa7e5..cebc7dd2c 100644 --- a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php +++ b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php @@ -880,11 +880,11 @@ class ExceptionRendererTest extends CakeTestCase { } /** - * Tests that exception renderer dispatches Dispatcher.afterDispatch event on error response + * Test that rendering exceptions triggers shutdown events. * * @return void */ - public function testAfterDispatchEventOnErrorResponse() { + public function testRenderShutdownEvents() { $fired = array(); $listener = function ($event) use (&$fired) { $fired[] = $event->name(); From cbdc89ddeee1db2b01a357662cdaf3367642655a Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Thu, 14 Jul 2016 05:50:37 +0200 Subject: [PATCH 22/39] Fix CS error --- lib/Cake/Error/ExceptionRenderer.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/Cake/Error/ExceptionRenderer.php b/lib/Cake/Error/ExceptionRenderer.php index 4da938167..d5d32ff95 100644 --- a/lib/Cake/Error/ExceptionRenderer.php +++ b/lib/Cake/Error/ExceptionRenderer.php @@ -330,6 +330,13 @@ class ExceptionRenderer { $this->controller->response->send(); } +/** + * Run the shutdown events. + * + * Triggers the afterFilter and afterDispatch events. + * + * @return void + */ protected function _shutdown() { $afterFilterEvent = new CakeEvent('Controller.shutdown', $this->controller); $this->controller->getEventManager()->dispatch($afterFilterEvent); From 46e8fd1eb7bbb5d8aaaf8b10ab9dfcba9eeeab48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Tue, 19 Jul 2016 16:23:27 +0200 Subject: [PATCH 23/39] Add fix for the httpoxy vulnerability Refs https://github.com/cakephp/cakephp/issues/9137#issuecomment-233637635 --- app/webroot/.htaccess | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/webroot/.htaccess b/app/webroot/.htaccess index 1d499ba73..e3543be40 100644 --- a/app/webroot/.htaccess +++ b/app/webroot/.htaccess @@ -1,3 +1,9 @@ +# Uncomment the following to prevent the httpoxy vulnerability +# See: https://httpoxy.org/ +# +# RequestHeader unset Proxy +# + RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d From d6e45131ad287e97c17d9b1c2bccb657c7cdc4d7 Mon Sep 17 00:00:00 2001 From: Mark van Driel Date: Mon, 25 Jul 2016 17:15:18 +0200 Subject: [PATCH 24/39] Prevent unnecessary joins / complex conditions in delete --- lib/Cake/Model/Datasource/Database/Mysql.php | 2 +- .../Model/Datasource/Database/MysqlTest.php | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 24358c107..d0d3b2375 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -439,7 +439,7 @@ class Mysql extends DboSource { } $complexConditions = false; foreach ((array)$conditions as $key => $value) { - if (strpos($key, $model->alias) === false) { + if (strpos($key, '.') !== false && strpos($key, $model->alias) === false) { $complexConditions = true; break; } diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index aa1353ecf..69f2898d4 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -4045,6 +4045,27 @@ SQL; $this->Dbo->delete($Article, '2=2'); } +/** + * Test deletes without complex conditions. + * + * @return void + */ + public function testDeleteNoComplexCondition() { + $this->loadFixtures('Article', 'User'); + $test = ConnectionManager::getDatasource('test'); + $db = $test->config['database']; + + $this->Dbo = $this->getMock('Mysql', array('execute'), array($test->config)); + + $this->Dbo->expects($this->at(0))->method('execute') + ->with("DELETE `Article` FROM `$db`.`articles` AS `Article` WHERE `id` = 1"); + + $Article = new Article(); + + $conditions = array('id' => 1); + $this->Dbo->delete($Article, $conditions); + } + /** * Test truncate with a mock. * From c01525f2cc5fbef111ddad0c97b011dcb3b9b139 Mon Sep 17 00:00:00 2001 From: Mark van Driel Date: Tue, 26 Jul 2016 11:25:27 +0200 Subject: [PATCH 25/39] Make check more strict to respect existing queries --- lib/Cake/Model/Datasource/Database/Mysql.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index d0d3b2375..3d1d498ed 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -438,8 +438,9 @@ class Mysql extends DboSource { $alias = $joins = false; } $complexConditions = false; + $fields = array_keys($this->describe($model)); foreach ((array)$conditions as $key => $value) { - if (strpos($key, '.') !== false && strpos($key, $model->alias) === false) { + if (strpos($key, $model->alias) === false && !in_array($key, $fields, true)) { $complexConditions = true; break; } From 147693618c049029123001e0100d4564e54b5b08 Mon Sep 17 00:00:00 2001 From: Andrej Griniuk Date: Tue, 26 Jul 2016 23:39:09 +0300 Subject: [PATCH 26/39] refs #9174 fix CakeSchema compare when changing field length to the default one --- lib/Cake/Model/CakeSchema.php | 5 +- lib/Cake/Test/Case/Model/CakeSchemaTest.php | 57 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/CakeSchema.php b/lib/Cake/Model/CakeSchema.php index 38f663cc5..85ec28bb4 100644 --- a/lib/Cake/Model/CakeSchema.php +++ b/lib/Cake/Model/CakeSchema.php @@ -486,8 +486,9 @@ class CakeSchema extends Object { foreach ($fields as $field => $value) { if (!empty($old[$table][$field])) { - $diff = $this->_arrayDiffAssoc($value, $old[$table][$field]); - if (!empty($diff) && $field !== 'indexes' && $field !== 'tableParameters') { + $diff = !empty($this->_arrayDiffAssoc($value, $old[$table][$field])) + || !empty($this->_arrayDiffAssoc($old[$table][$field], $value)); + if ($diff && $field !== 'indexes' && $field !== 'tableParameters') { $tables[$table]['change'][$field] = $value; } } diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index 67c4d8bd5..eb2a64a82 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -953,6 +953,63 @@ class CakeSchemaTest extends CakeTestCase { $this->assertEquals($expected, $compare, 'Invalid SQL, datetime does not have length'); } +/** + * Test comparing with field length/limit changed from some non-default value to the default + * + * @return void + */ + public function testCompareLimitToDefault() { + $old = array( + 'posts' => array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => 1, 'key' => 'primary'), + 'author_id' => array('type' => 'integer', 'null' => false, 'limit' => 5), + 'title' => array('type' => 'string', 'null' => true, 'length' => 45), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => true) + ), + 'tableParameters' => array( + 'charset' => 'latin1', + 'collate' => 'latin1_general_ci' + ) + ), + ); + $new = array( + 'posts' => array( + 'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'), + 'author_id' => array('type' => 'integer', 'null' => false), + 'title' => array('type' => 'varchar', 'null' => true), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => true) + ), + 'tableParameters' => array( + 'charset' => 'latin1', + 'collate' => 'latin1_general_ci' + ) + ), + ); + $compare = $this->Schema->compare($old, $new); + $expected = array( + 'posts' => array( + 'change' => array( + 'id' => array( + 'type' => 'integer', + 'null' => false, + 'key' => 'primary' + ), + 'author_id' => array( + 'type' => 'integer', + 'null' => false, + ), + 'title' => array( + 'type' => 'varchar', + 'null' => true, + ) + ) + ), + ); + $this->assertEquals($expected, $compare, 'Invalid SQL, field length change not detected'); + } + /** * testSchemaLoading method * From e7f3365d8b6f13ab7a10a65ec23cddb29ebabdeb Mon Sep 17 00:00:00 2001 From: Andrej Griniuk Date: Tue, 26 Jul 2016 23:57:14 +0300 Subject: [PATCH 27/39] fix on php < 5.5 --- lib/Cake/Model/CakeSchema.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Model/CakeSchema.php b/lib/Cake/Model/CakeSchema.php index 85ec28bb4..ef08f1587 100644 --- a/lib/Cake/Model/CakeSchema.php +++ b/lib/Cake/Model/CakeSchema.php @@ -486,9 +486,11 @@ class CakeSchema extends Object { foreach ($fields as $field => $value) { if (!empty($old[$table][$field])) { - $diff = !empty($this->_arrayDiffAssoc($value, $old[$table][$field])) - || !empty($this->_arrayDiffAssoc($old[$table][$field], $value)); - if ($diff && $field !== 'indexes' && $field !== 'tableParameters') { + $diff = $this->_arrayDiffAssoc($value, $old[$table][$field]); + if (empty($diff)) { + $diff = $this->_arrayDiffAssoc($old[$table][$field], $value); + } + if (!empty($diff) && $field !== 'indexes' && $field !== 'tableParameters') { $tables[$table]['change'][$field] = $value; } } From 5caac5f340753662ad1b430074c3955697e955de Mon Sep 17 00:00:00 2001 From: Mark van Driel Date: Wed, 27 Jul 2016 16:31:57 +0200 Subject: [PATCH 28/39] Prevent unnecessary joins / complex conditions in delete --- lib/Cake/Model/Datasource/Database/Mysql.php | 30 ++++++++++++++----- lib/Cake/Model/Datasource/DboSource.php | 10 +++++-- .../Model/Datasource/Database/MysqlTest.php | 5 ++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 3d1d498ed..21f763dc4 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -437,14 +437,7 @@ class Mysql extends DboSource { if (empty($conditions)) { $alias = $joins = false; } - $complexConditions = false; - $fields = array_keys($this->describe($model)); - foreach ((array)$conditions as $key => $value) { - if (strpos($key, $model->alias) === false && !in_array($key, $fields, true)) { - $complexConditions = true; - break; - } - } + $complexConditions = $this->_deleteNeedsComplexConditions($model, $conditions); if (!$complexConditions) { $joins = false; } @@ -460,6 +453,27 @@ class Mysql extends DboSource { return true; } +/** + * Checks whether complex conditions are needed for a delete with the given conditions. + * + * @param Model $model The model to delete from. + * @param mixed $conditions The conditions to use. + * @return bool Whether or not complex conditions are needed + */ + protected function _deleteNeedsComplexConditions(Model $model, $conditions) { + $fields = array_keys($this->describe($model)); + foreach ((array)$conditions as $key => $value) { + if (in_array(strtolower(trim($key)), $this->_sqlBoolOps, true)) { + if ($this->_deleteNeedsComplexConditions($model, $value)) { + return true; + } + } elseif (strpos($key, $model->alias) === false && !in_array($key, $fields, true)) { + return true; + } + } + return false; + } + /** * Sets the database encoding * diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index bdd76e986..65e833864 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -183,6 +183,13 @@ class DboSource extends DataSource { */ protected $_sqlOps = array('like', 'ilike', 'rlike', 'or', 'not', 'in', 'between', 'regexp', 'similar to'); +/** + * The set of valid SQL boolean operations usable in a WHERE statement + * + * @var array + */ + protected $_sqlBoolOps = array('and', 'or', 'not', 'and not', 'or not', 'xor', '||', '&&'); + /** * Indicates the level of nested transactions * @@ -2678,7 +2685,6 @@ class DboSource extends DataSource { public function conditionKeysToString($conditions, $quoteValues = true, Model $Model = null) { $out = array(); $data = $columnType = null; - $bool = array('and', 'or', 'not', 'and not', 'or not', 'xor', '||', '&&'); foreach ($conditions as $key => $value) { $join = ' AND '; @@ -2696,7 +2702,7 @@ class DboSource extends DataSource { } elseif (is_numeric($key) && is_string($value)) { $out[] = $this->_quoteFields($value); } elseif ((is_numeric($key) && is_array($value)) || in_array(strtolower(trim($key)), $bool)) { - if (in_array(strtolower(trim($key)), $bool)) { + if (in_array(strtolower(trim($key)), $this->_sqlBoolOps)) { $join = ' ' . strtoupper($key) . ' '; } else { $key = $join; diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index 69f2898d4..dcae76f65 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -4060,10 +4060,15 @@ SQL; $this->Dbo->expects($this->at(0))->method('execute') ->with("DELETE `Article` FROM `$db`.`articles` AS `Article` WHERE `id` = 1"); + $this->Dbo->expects($this->at(1))->method('execute') + ->with("DELETE `Article` FROM `$db`.`articles` AS `Article` WHERE NOT (`id` = 1)"); + $Article = new Article(); $conditions = array('id' => 1); $this->Dbo->delete($Article, $conditions); + $conditions = array('NOT' => array('id' => 1)); + $this->Dbo->delete($Article, $conditions); } /** From 4dc8e541318737a599aa51b936237d016db870ef Mon Sep 17 00:00:00 2001 From: Mark van Driel Date: Wed, 27 Jul 2016 20:27:15 +0200 Subject: [PATCH 29/39] Fixed typo --- lib/Cake/Model/Datasource/DboSource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index 65e833864..d20eefbf5 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -2701,7 +2701,7 @@ class DboSource extends DataSource { continue; } elseif (is_numeric($key) && is_string($value)) { $out[] = $this->_quoteFields($value); - } elseif ((is_numeric($key) && is_array($value)) || in_array(strtolower(trim($key)), $bool)) { + } elseif ((is_numeric($key) && is_array($value)) || in_array(strtolower(trim($key)), $this->_sqlBoolOps)) { if (in_array(strtolower(trim($key)), $this->_sqlBoolOps)) { $join = ' ' . strtoupper($key) . ' '; } else { From 93db51cf1063452004fe2c518aefc069f38d1828 Mon Sep 17 00:00:00 2001 From: "Juan I. Benavides" Date: Mon, 1 Aug 2016 13:09:45 -0500 Subject: [PATCH 30/39] Avoiding circular object reference in SmptTransport This fixes a memory leak while sending multiple emails. Fixes: #9198 --- lib/Cake/Network/Email/SmtpTransport.php | 47 ++++++++----------- .../Case/Network/Email/SmtpTransportTest.php | 22 ++------- 2 files changed, 23 insertions(+), 46 deletions(-) diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index c581c9a2f..6205e443b 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -32,13 +32,6 @@ class SmtpTransport extends AbstractTransport { */ protected $_socket; -/** - * CakeEmail - * - * @var CakeEmail - */ - protected $_cakeEmail; - /** * Content of email to return * @@ -90,12 +83,10 @@ class SmtpTransport extends AbstractTransport { * @throws SocketException */ public function send(CakeEmail $email) { - $this->_cakeEmail = $email; - $this->_connect(); $this->_auth(); - $this->_sendRcpt(); - $this->_sendData(); + $this->_sendRcpt($email); + $this->_sendData($email); $this->_disconnect(); return $this->_content; @@ -237,10 +228,10 @@ class SmtpTransport extends AbstractTransport { * * @return array */ - protected function _prepareFromAddress() { - $from = $this->_cakeEmail->returnPath(); + protected function _prepareFromAddress($email) { + $from = $email->returnPath(); if (empty($from)) { - $from = $this->_cakeEmail->from(); + $from = $email->from(); } return $from; } @@ -250,10 +241,10 @@ class SmtpTransport extends AbstractTransport { * * @return array */ - protected function _prepareRecipientAddresses() { - $to = $this->_cakeEmail->to(); - $cc = $this->_cakeEmail->cc(); - $bcc = $this->_cakeEmail->bcc(); + protected function _prepareRecipientAddresses($email) { + $to = $email->to(); + $cc = $email->cc(); + $bcc = $email->bcc(); return array_merge(array_keys($to), array_keys($cc), array_keys($bcc)); } @@ -262,8 +253,8 @@ class SmtpTransport extends AbstractTransport { * * @return array */ - protected function _prepareMessageHeaders() { - return $this->_cakeEmail->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'to', 'cc', 'subject')); + protected function _prepareMessageHeaders($email) { + return $email->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'to', 'cc', 'subject')); } /** @@ -271,8 +262,8 @@ class SmtpTransport extends AbstractTransport { * * @return string */ - protected function _prepareMessage() { - $lines = $this->_cakeEmail->message(); + protected function _prepareMessage($email) { + $lines = $email->message(); $messages = array(); foreach ($lines as $line) { if ((!empty($line)) && ($line[0] === '.')) { @@ -290,11 +281,11 @@ class SmtpTransport extends AbstractTransport { * @return void * @throws SocketException */ - protected function _sendRcpt() { - $from = $this->_prepareFromAddress(); + protected function _sendRcpt($email) { + $from = $this->_prepareFromAddress($email); $this->_smtpSend($this->_prepareFromCmd(key($from))); - $emails = $this->_prepareRecipientAddresses(); + $emails = $this->_prepareRecipientAddresses($email); foreach ($emails as $email) { $this->_smtpSend($this->_prepareRcptCmd($email)); } @@ -306,11 +297,11 @@ class SmtpTransport extends AbstractTransport { * @return void * @throws SocketException */ - protected function _sendData() { + protected function _sendData($email) { $this->_smtpSend('DATA', '354'); - $headers = $this->_headersToString($this->_prepareMessageHeaders()); - $message = $this->_prepareMessage(); + $headers = $this->_headersToString($this->_prepareMessageHeaders($email)); + $message = $this->_prepareMessage($email); $this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); $this->_content = array('headers' => $headers, 'message' => $message); diff --git a/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php b/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php index 478de6b98..712ea54ae 100644 --- a/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php +++ b/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php @@ -35,16 +35,6 @@ class SmtpTestTransport extends SmtpTransport { $this->_socket = $socket; } -/** - * Helper to change the CakeEmail - * - * @param object $cakeEmail An email object. - * @return void - */ - public function setCakeEmail($cakeEmail) { - $this->_cakeEmail = $cakeEmail; - } - /** * Disabled the socket change * @@ -348,8 +338,7 @@ class SmtpTransportTest extends CakeTestCase { $this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(14))->method('read')->will($this->returnValue("250 OK\r\n")); - $this->SmtpTransport->setCakeEmail($email); - $this->SmtpTransport->sendRcpt(); + $this->SmtpTransport->sendRcpt($email); } /** @@ -370,8 +359,7 @@ class SmtpTransportTest extends CakeTestCase { $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n")); - $this->SmtpTransport->setCakeEmail($email); - $this->SmtpTransport->sendRcpt(); + $this->SmtpTransport->sendRcpt($email); } /** @@ -416,8 +404,7 @@ class SmtpTransportTest extends CakeTestCase { $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n")); - $this->SmtpTransport->setCakeEmail($email); - $this->SmtpTransport->sendData(); + $this->SmtpTransport->sendData($email); } /** @@ -498,8 +485,7 @@ class SmtpTransportTest extends CakeTestCase { $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n")); - $this->SmtpTransport->setCakeEmail($email); - $this->SmtpTransport->sendRcpt(); + $this->SmtpTransport->sendRcpt($email); $expected = array( array('code' => '250', 'message' => 'OK'), From d37f88b20edd18ba13b2924e3e764f40945b4b12 Mon Sep 17 00:00:00 2001 From: "Juan I. Benavides" Date: Mon, 1 Aug 2016 16:46:25 -0500 Subject: [PATCH 31/39] Documentation and declaration of object type in method's parameter This should make pass the phpcs check. #9199 --- lib/Cake/Network/Email/SmtpTransport.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index 6205e443b..c1ba377f1 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -226,6 +226,7 @@ class SmtpTransport extends AbstractTransport { /** * Prepares the `from` email address. * + * @param CakeEmail $email CakeEmail * @return array */ protected function _prepareFromAddress($email) { @@ -239,9 +240,10 @@ class SmtpTransport extends AbstractTransport { /** * Prepares the recipient email addresses. * + * @param CakeEmail $email CakeEmail * @return array */ - protected function _prepareRecipientAddresses($email) { + protected function _prepareRecipientAddresses(CakeEmail $email) { $to = $email->to(); $cc = $email->cc(); $bcc = $email->bcc(); @@ -251,18 +253,20 @@ class SmtpTransport extends AbstractTransport { /** * Prepares the message headers. * + * @param CakeEmail $email CakeEmail * @return array */ - protected function _prepareMessageHeaders($email) { + protected function _prepareMessageHeaders(CakeEmail $email) { return $email->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'to', 'cc', 'subject')); } /** * Prepares the message body. * + * @param CakeEmail $email CakeEmail * @return string */ - protected function _prepareMessage($email) { + protected function _prepareMessage(CakeEmail $email) { $lines = $email->message(); $messages = array(); foreach ($lines as $line) { @@ -278,10 +282,11 @@ class SmtpTransport extends AbstractTransport { /** * Send emails * + * @param CakeEmail $email CakeEmail * @return void * @throws SocketException */ - protected function _sendRcpt($email) { + protected function _sendRcpt(CakeEmail $email) { $from = $this->_prepareFromAddress($email); $this->_smtpSend($this->_prepareFromCmd(key($from))); @@ -294,10 +299,11 @@ class SmtpTransport extends AbstractTransport { /** * Send Data * + * @param CakeEmail $email CakeEmail * @return void * @throws SocketException */ - protected function _sendData($email) { + protected function _sendData(CakeEmail $email) { $this->_smtpSend('DATA', '354'); $headers = $this->_headersToString($this->_prepareMessageHeaders($email)); From 60bd98a593e025e781c56ff0ac4a2c8db876214f Mon Sep 17 00:00:00 2001 From: "Juan I. Benavides" Date: Tue, 2 Aug 2016 02:30:43 -0500 Subject: [PATCH 32/39] Consistency with other methods: Type declaration of CakeEmail parameter. --- lib/Cake/Network/Email/SmtpTransport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index c1ba377f1..b0761d496 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -229,7 +229,7 @@ class SmtpTransport extends AbstractTransport { * @param CakeEmail $email CakeEmail * @return array */ - protected function _prepareFromAddress($email) { + protected function _prepareFromAddress(CakeEmail $email) { $from = $email->returnPath(); if (empty($from)) { $from = $email->from(); From 6dbd5c659d46772a4b7bb7869c0e91b4982f6307 Mon Sep 17 00:00:00 2001 From: antograssiot Date: Tue, 2 Aug 2016 22:01:35 +0200 Subject: [PATCH 33/39] fix api generation --- lib/Cake/View/Helper/HtmlHelper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Cake/View/Helper/HtmlHelper.php b/lib/Cake/View/Helper/HtmlHelper.php index 103511660..e18967e4a 100644 --- a/lib/Cake/View/Helper/HtmlHelper.php +++ b/lib/Cake/View/Helper/HtmlHelper.php @@ -324,7 +324,7 @@ class HtmlHelper extends AppHelper { * - `escapeTitle` Set to false to disable escaping of title. (Takes precedence over value of `escape`) * - `confirm` JavaScript confirmation message. * - * @param string $title The content to be wrapped by tags. + * @param string $title The content to be wrapped by `` tags. * @param string|array $url Cake-relative URL or array of URL parameters, or external URL (starts with http://) * @param array $options Array of options and HTML attributes. * @param string $confirmMessage JavaScript confirmation message. This @@ -412,7 +412,7 @@ class HtmlHelper extends AppHelper { * CSS stylesheets. If `$path` is prefixed with '/', the path will be relative to the webroot * of your application. Otherwise, the path will be relative to your CSS path, usually webroot/css. * @param array $options Array of options and HTML arguments. - * @return string CSS or