From 41851d60b466b7740647f73f317494b23ff7344c Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Sun, 28 Aug 2016 19:16:59 +0200 Subject: [PATCH 01/41] fix HTTP Basic Auth on FastCGI PHP --- app/webroot/.htaccess | 1 + lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/app/webroot/.htaccess b/app/webroot/.htaccess index e3543be40..bb4c43955 100644 --- a/app/webroot/.htaccess +++ b/app/webroot/.htaccess @@ -6,6 +6,7 @@ RewriteEngine On + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index 02144b171..c0cfbbd54 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -82,6 +82,15 @@ class BasicAuthenticate extends BaseAuthenticate { * @return mixed Either false or an array of user information */ public function getUser(CakeRequest $request) { + if(!isset($_SERVER['PHP_AUTH_USER'])) { + if (isset($_SERVER['HTTP_AUTHORIZATION']) && (strlen($_SERVER['HTTP_AUTHORIZATION']) > 0)) { + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); + if( strlen($_SERVER['PHP_AUTH_USER']) == 0 || strlen($_SERVER['PHP_AUTH_PW']) == 0 ) { + unset($_SERVER['PHP_AUTH_USER']); + unset($_SERVER['PHP_AUTH_PW']); + } + } + } $username = env('PHP_AUTH_USER'); $pass = env('PHP_AUTH_PW'); From 6b17567ea7c4971ded01ed98f2b4ef0844aeec2c Mon Sep 17 00:00:00 2001 From: Marcin Stramek Date: Wed, 15 Feb 2017 10:25:00 +0100 Subject: [PATCH 02/41] #10230 - Extend available TLS encrypt methods in CakeSocket --- lib/Cake/Network/CakeSocket.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php index 9b0af00d6..64a7e5be9 100644 --- a/lib/Cake/Network/CakeSocket.php +++ b/lib/Cake/Network/CakeSocket.php @@ -44,7 +44,8 @@ class CakeSocket { 'host' => 'localhost', 'protocol' => 'tcp', 'port' => 80, - 'timeout' => 30 + 'timeout' => 30, + 'cryptoType' => 'tls' ); /** @@ -93,10 +94,14 @@ class CakeSocket { 'sslv3_client' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT, 'sslv23_client' => STREAM_CRYPTO_METHOD_SSLv23_CLIENT, 'tls_client' => STREAM_CRYPTO_METHOD_TLS_CLIENT, + 'tlsv1_1_client' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, + 'tlsv1_2_client' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, 'sslv2_server' => STREAM_CRYPTO_METHOD_SSLv2_SERVER, 'sslv3_server' => STREAM_CRYPTO_METHOD_SSLv3_SERVER, 'sslv23_server' => STREAM_CRYPTO_METHOD_SSLv23_SERVER, - 'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER + 'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER, + 'tlsv1_1_server' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, + 'tlsv1_2_server' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER // @codingStandardsIgnoreEnd ); @@ -205,7 +210,7 @@ class CakeSocket { } } - $this->enableCrypto('tls', 'client'); + $this->enableCrypto($this->config['cryptoType'], 'client'); } } return $this->connected; @@ -433,7 +438,7 @@ class CakeSocket { /** * Encrypts current stream socket, using one of the defined encryption methods. * - * @param string $type Type which can be one of 'sslv2', 'sslv3', 'sslv23' or 'tls'. + * @param string $type Type which can be one of 'sslv2', 'sslv3', 'sslv23', 'tls', 'tlsv1_1' or 'tlsv1_2'. * @param string $clientOrServer Can be one of 'client', 'server'. Default is 'client'. * @param bool $enable Enable or disable encryption. Default is true (enable) * @return bool True on success From 5c1f60baba6fc375d3409e6feaa19734bda9caf2 Mon Sep 17 00:00:00 2001 From: Marcin Stramek Date: Wed, 15 Feb 2017 10:28:06 +0100 Subject: [PATCH 03/41] #10230 - Extend available TLS encrypt methods in CakeSocket - formatting --- lib/Cake/Network/CakeSocket.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php index 64a7e5be9..c208805c8 100644 --- a/lib/Cake/Network/CakeSocket.php +++ b/lib/Cake/Network/CakeSocket.php @@ -45,7 +45,7 @@ class CakeSocket { 'protocol' => 'tcp', 'port' => 80, 'timeout' => 30, - 'cryptoType' => 'tls' + 'cryptoType' => 'tls' ); /** @@ -94,14 +94,14 @@ class CakeSocket { 'sslv3_client' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT, 'sslv23_client' => STREAM_CRYPTO_METHOD_SSLv23_CLIENT, 'tls_client' => STREAM_CRYPTO_METHOD_TLS_CLIENT, - 'tlsv1_1_client' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, - 'tlsv1_2_client' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'tlsv1_1_client' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, + 'tlsv1_2_client' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, 'sslv2_server' => STREAM_CRYPTO_METHOD_SSLv2_SERVER, 'sslv3_server' => STREAM_CRYPTO_METHOD_SSLv3_SERVER, 'sslv23_server' => STREAM_CRYPTO_METHOD_SSLv23_SERVER, 'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER, - 'tlsv1_1_server' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, - 'tlsv1_2_server' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER + 'tlsv1_1_server' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, + 'tlsv1_2_server' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER // @codingStandardsIgnoreEnd ); @@ -210,7 +210,7 @@ class CakeSocket { } } - $this->enableCrypto($this->config['cryptoType'], 'client'); + $this->enableCrypto($this->config['cryptoType'], 'client'); } } return $this->connected; From 3849df0f2f55e161767b16b2af45830e2cd7b3cb Mon Sep 17 00:00:00 2001 From: Sebastien Barre Date: Sat, 4 Mar 2017 00:51:20 -0500 Subject: [PATCH 04/41] fix duplicate primary keys for tables without models --- lib/Cake/Model/CakeSchema.php | 9 ++- lib/Cake/Test/Case/Model/CakeSchemaTest.php | 63 +++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/CakeSchema.php b/lib/Cake/Model/CakeSchema.php index 529ceb5f8..51bab41ab 100644 --- a/lib/Cake/Model/CakeSchema.php +++ b/lib/Cake/Model/CakeSchema.php @@ -613,9 +613,16 @@ class CakeSchema extends CakeObject { $db = $Obj->getDataSource(); $fields = $Obj->schema(true); + $hasPrimaryAlready = false; + foreach ($fields as $value) { + if (isset($value['key']) && $value['key'] === 'primary') { + $hasPrimaryAlready = true; + } + } + $columns = array(); foreach ($fields as $name => $value) { - if ($Obj->primaryKey === $name) { + if ($Obj->primaryKey === $name && !$hasPrimaryAlready && !isset($value['key'])) { $value['key'] = 'primary'; } if (!isset($db->columns[$value['type']])) { diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index aedb6ef3d..bb9ddb7bb 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -363,6 +363,39 @@ class SchemaCrossDatabaseFixture extends CakeTestFixture { ); } +/** + * NonConventionalPrimaryKeyFixture class + * + * @package Cake.Test.Case.Model + */ +class NonConventionalPrimaryKeyFixture extends CakeTestFixture { + +/** + * name property + * + * @var string + */ + public $name = 'NonConventional'; + +/** + * table property + * + * @var string + */ + public $table = 'non_conventional'; + +/** + * fields property + * + * @var array + */ + public $fields = array( + 'version_id' => array('type' => 'integer', 'key' => 'primary'), + 'id' => array('type' => 'integer'), + 'name' => 'string' + ); +} + /** * SchemaPrefixAuthUser class * @@ -649,6 +682,36 @@ class CakeSchemaTest extends CakeTestCase { $fixture->drop($db); } +/** + * testSchemaRead method when a primary key is on a non-conventional column + * + * @return void + */ + public function testSchemaReadWithNonConventionalPrimaryKey() { + $db = ConnectionManager::getDataSource('test'); + $fixture = new NonConventionalPrimaryKeyFixture(); + $fixture->create($db); + + $read = $this->Schema->read(array( + 'connection' => 'test', + 'name' => 'TestApp', + 'models' => false + )); + $fixture->drop($db); + + $has_table = isset($read['tables']['non_conventional']); + $this->assertTrue($has_table, 'non_conventional table should appear'); + if ($has_table) { + $version_id_has_key = isset($read['tables']['non_conventional']['version_id']['key']); + $this->assertTrue($version_id_has_key, 'version_id key should be set'); + if ($version_id_has_key) { + $version_id_key_is_primary = $read['tables']['non_conventional']['version_id']['key'] === 'primary'; + $this->assertTrue($version_id_key_is_primary, 'version_id key should be primary'); + } + $this->assertFalse(isset($read['tables']['non_conventional']['id']['key']), 'id key should not be set'); + } + } + /** * test that tables are generated correctly * From a0e023d3a9396a9def87eb212f7583137623ffca Mon Sep 17 00:00:00 2001 From: Sebastien Barre Date: Mon, 6 Mar 2017 15:58:03 -0500 Subject: [PATCH 05/41] fix coding standard, skip Postgres --- lib/Cake/Test/Case/Model/CakeSchemaTest.php | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index bb9ddb7bb..1e7158aca 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -688,6 +688,7 @@ class CakeSchemaTest extends CakeTestCase { * @return void */ public function testSchemaReadWithNonConventionalPrimaryKey() { + $this->skipIf($this->db instanceof Postgres, 'Cannot test on Postgres'); $db = ConnectionManager::getDataSource('test'); $fixture = new NonConventionalPrimaryKeyFixture(); $fixture->create($db); @@ -699,17 +700,14 @@ class CakeSchemaTest extends CakeTestCase { )); $fixture->drop($db); - $has_table = isset($read['tables']['non_conventional']); - $this->assertTrue($has_table, 'non_conventional table should appear'); - if ($has_table) { - $version_id_has_key = isset($read['tables']['non_conventional']['version_id']['key']); - $this->assertTrue($version_id_has_key, 'version_id key should be set'); - if ($version_id_has_key) { - $version_id_key_is_primary = $read['tables']['non_conventional']['version_id']['key'] === 'primary'; - $this->assertTrue($version_id_key_is_primary, 'version_id key should be primary'); - } - $this->assertFalse(isset($read['tables']['non_conventional']['id']['key']), 'id key should not be set'); - } + $hasTable = isset($read['tables']['non_conventional']); + $this->assertTrue($hasTable, 'non_conventional table should appear'); + $versionIdHasKey = $hasTable && isset($read['tables']['non_conventional']['version_id']['key']); + $this->assertTrue($versionIdHasKey, 'version_id key should be set'); + $versionIdKeyIsPrimary = $versionIdHasKey && $read['tables']['non_conventional']['version_id']['key'] === 'primary'; + $this->assertTrue($versionIdKeyIsPrimary, 'version_id key should be primary'); + $idHasNoKey = $hasTable && !isset($read['tables']['non_conventional']['id']['key']); + $this->assertTrue($idHasNoKey, 'id key should not be set'); } /** From 1ebdc61fdc317a0cb70cbecf854447c262c5320f Mon Sep 17 00:00:00 2001 From: Sebastien Barre Date: Thu, 9 Mar 2017 23:11:17 -0500 Subject: [PATCH 06/41] clean up assertions now that we are dropping the fixture early --- lib/Cake/Test/Case/Model/CakeSchemaTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index 1e7158aca..7d27fc681 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -702,11 +702,11 @@ class CakeSchemaTest extends CakeTestCase { $hasTable = isset($read['tables']['non_conventional']); $this->assertTrue($hasTable, 'non_conventional table should appear'); - $versionIdHasKey = $hasTable && isset($read['tables']['non_conventional']['version_id']['key']); + $versionIdHasKey = isset($read['tables']['non_conventional']['version_id']['key']); $this->assertTrue($versionIdHasKey, 'version_id key should be set'); - $versionIdKeyIsPrimary = $versionIdHasKey && $read['tables']['non_conventional']['version_id']['key'] === 'primary'; + $versionIdKeyIsPrimary = $read['tables']['non_conventional']['version_id']['key'] === 'primary'; $this->assertTrue($versionIdKeyIsPrimary, 'version_id key should be primary'); - $idHasNoKey = $hasTable && !isset($read['tables']['non_conventional']['id']['key']); + $idHasNoKey = !isset($read['tables']['non_conventional']['id']['key']); $this->assertTrue($idHasNoKey, 'id key should not be set'); } From f5795f05a5409cd6e8ae5b1a8742cf17e346b425 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Wed, 15 Mar 2017 13:59:56 +0100 Subject: [PATCH 07/41] BasicAuthenticate - code styling and strong type comparison --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index c0cfbbd54..fcb0ddec5 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -85,9 +85,8 @@ class BasicAuthenticate extends BaseAuthenticate { if(!isset($_SERVER['PHP_AUTH_USER'])) { if (isset($_SERVER['HTTP_AUTHORIZATION']) && (strlen($_SERVER['HTTP_AUTHORIZATION']) > 0)) { list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); - if( strlen($_SERVER['PHP_AUTH_USER']) == 0 || strlen($_SERVER['PHP_AUTH_PW']) == 0 ) { - unset($_SERVER['PHP_AUTH_USER']); - unset($_SERVER['PHP_AUTH_PW']); + if(strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { + unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); } } } From a15c5c7a70bc742a5ba612084619706c5cc6128b Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Wed, 15 Mar 2017 14:08:17 +0100 Subject: [PATCH 08/41] BasicAuthenticate - added check to avoid parsing if "Authorization: Bearer " is in place --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index fcb0ddec5..563fa3071 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -83,7 +83,7 @@ class BasicAuthenticate extends BaseAuthenticate { */ public function getUser(CakeRequest $request) { if(!isset($_SERVER['PHP_AUTH_USER'])) { - if (isset($_SERVER['HTTP_AUTHORIZATION']) && (strlen($_SERVER['HTTP_AUTHORIZATION']) > 0)) { + if (isset($_SERVER['HTTP_AUTHORIZATION']) && strlen($_SERVER['HTTP_AUTHORIZATION']) > 0 && strpos($_SERVER['HTTP_AUTHORIZATION'], 'basic') !== false) { list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); if(strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); From 089a0ae087bf70ac0c2582bb23211eca86da0d93 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Wed, 15 Mar 2017 15:06:39 +0100 Subject: [PATCH 09/41] using $request->header in place of $_SERVER['HTTP_AUTHORIZATION'] --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index 563fa3071..9e6ce8a18 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -83,8 +83,8 @@ class BasicAuthenticate extends BaseAuthenticate { */ public function getUser(CakeRequest $request) { if(!isset($_SERVER['PHP_AUTH_USER'])) { - if (isset($_SERVER['HTTP_AUTHORIZATION']) && strlen($_SERVER['HTTP_AUTHORIZATION']) > 0 && strpos($_SERVER['HTTP_AUTHORIZATION'], 'basic') !== false) { - list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); + if ($request->header('Authorization') !== false && strlen($request->header('Authorization')) > 0 && strpos($request->header('Authorization'), 'basic') !== false) { + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($request->header('Authorization'), 6))); if(strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); } From 74f700882c22e61cd62df56de5230ce853296e13 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Wed, 15 Mar 2017 16:27:27 +0100 Subject: [PATCH 10/41] local variable optimization --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index 9e6ce8a18..6e5d666ba 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -83,8 +83,9 @@ class BasicAuthenticate extends BaseAuthenticate { */ public function getUser(CakeRequest $request) { if(!isset($_SERVER['PHP_AUTH_USER'])) { - if ($request->header('Authorization') !== false && strlen($request->header('Authorization')) > 0 && strpos($request->header('Authorization'), 'basic') !== false) { - list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($request->header('Authorization'), 6))); + $httpAuthorization = $request->header('Authorization'); + if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'basic') !== false) { + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($httpAuthorization, 6))); if(strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); } From 5fb1b71cb62b12631a85b139668273b63dfc6f06 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Wed, 15 Mar 2017 17:22:31 +0100 Subject: [PATCH 11/41] code style fix --- .../Controller/Component/Auth/BasicAuthenticate.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) mode change 100644 => 100755 lib/Cake/Controller/Component/Auth/BasicAuthenticate.php diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php old mode 100644 new mode 100755 index 6e5d666ba..e3a9326c7 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -84,12 +84,12 @@ class BasicAuthenticate extends BaseAuthenticate { public function getUser(CakeRequest $request) { if(!isset($_SERVER['PHP_AUTH_USER'])) { $httpAuthorization = $request->header('Authorization'); - if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'basic') !== false) { - list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($httpAuthorization, 6))); - if(strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { - unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); - } - } + if($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'basic') !== false) { + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($httpAuthorization, 6))); + if(strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { + unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + } + } } $username = env('PHP_AUTH_USER'); $pass = env('PHP_AUTH_PW'); From ff210b04d721d28be0c57c7010faf73eb04eefd8 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Wed, 15 Mar 2017 17:32:47 +0100 Subject: [PATCH 12/41] code style --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index e3a9326c7..e5395c8ee 100755 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -82,11 +82,11 @@ class BasicAuthenticate extends BaseAuthenticate { * @return mixed Either false or an array of user information */ public function getUser(CakeRequest $request) { - if(!isset($_SERVER['PHP_AUTH_USER'])) { + if (!isset($_SERVER['PHP_AUTH_USER'])) { $httpAuthorization = $request->header('Authorization'); - if($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'basic') !== false) { + if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'basic') !== false) { list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($httpAuthorization, 6))); - if(strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { + if (strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); } } From ca6ca9376ed9a66a100339bd60595eb8efcf68d2 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Sat, 18 Mar 2017 13:34:26 +0100 Subject: [PATCH 13/41] refactoring to avoid tampering with $_SERVER --- .../Controller/Component/Auth/BasicAuthenticate.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index e5395c8ee..df9dc3e57 100755 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -82,17 +82,17 @@ class BasicAuthenticate extends BaseAuthenticate { * @return mixed Either false or an array of user information */ public function getUser(CakeRequest $request) { + $username = ''; + $pass = ''; if (!isset($_SERVER['PHP_AUTH_USER'])) { + $username = env('PHP_AUTH_USER'); + $pass = env('PHP_AUTH_PW'); + } else { $httpAuthorization = $request->header('Authorization'); if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'basic') !== false) { - list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($httpAuthorization, 6))); - if (strlen($_SERVER['PHP_AUTH_USER']) === 0 || strlen($_SERVER['PHP_AUTH_PW']) === 0) { - unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); - } + list($username, $pass) = explode(':', base64_decode(substr($httpAuthorization, 6))); } } - $username = env('PHP_AUTH_USER'); - $pass = env('PHP_AUTH_PW'); if (!is_string($username) || $username === '' || !is_string($pass) || $pass === '') { return false; From 7cd9d4381a26cc3799a7e1209d26439f7779cf31 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Sat, 18 Mar 2017 14:44:44 +0100 Subject: [PATCH 14/41] typo --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index df9dc3e57..29c6e8100 100755 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -84,7 +84,7 @@ class BasicAuthenticate extends BaseAuthenticate { public function getUser(CakeRequest $request) { $username = ''; $pass = ''; - if (!isset($_SERVER['PHP_AUTH_USER'])) { + if (isset($_SERVER['PHP_AUTH_USER'])) { $username = env('PHP_AUTH_USER'); $pass = env('PHP_AUTH_PW'); } else { From e285df4f827b8eda57990a33cbb8610b4ed2bb91 Mon Sep 17 00:00:00 2001 From: Sebastien Barre Date: Sat, 25 Mar 2017 09:30:34 -0400 Subject: [PATCH 15/41] optimization, break early --- lib/Cake/Model/CakeSchema.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Cake/Model/CakeSchema.php b/lib/Cake/Model/CakeSchema.php index 51bab41ab..69d608ba0 100644 --- a/lib/Cake/Model/CakeSchema.php +++ b/lib/Cake/Model/CakeSchema.php @@ -617,6 +617,7 @@ class CakeSchema extends CakeObject { foreach ($fields as $value) { if (isset($value['key']) && $value['key'] === 'primary') { $hasPrimaryAlready = true; + break; } } From 0b6c23d04fe99ab1a4b10ed773fbfa4047747fe6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 26 Mar 2017 22:22:51 -0400 Subject: [PATCH 16/41] Update schema reflection for postgres. Use the schema reflection query from 3.x to provide access to the serial column attributes. These attributes give a more reliable way to access primary key data than comparing the primary key of the model. The old approach failed when schema was generated and concrete model's were missing. Refs #10356 --- .../Model/Datasource/Database/Postgres.php | 50 +++++++++++++------ lib/Cake/Test/Case/Model/CakeSchemaTest.php | 9 ++-- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index 8673fbc5c..173c67c67 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -198,14 +198,26 @@ class Postgres extends DboSource { $fields = parent::describe($table); $this->_sequenceMap[$table] = array(); $cols = null; + $hasPrimary = false; if ($fields === null) { $cols = $this->_execute( - "SELECT DISTINCT table_schema AS schema, column_name AS name, data_type AS type, is_nullable AS null, - column_default AS default, ordinal_position AS position, character_maximum_length AS char_length, - character_octet_length AS oct_length FROM information_schema.columns - WHERE table_name = ? AND table_schema = ? ORDER BY position", - array($table, $this->config['schema']) + 'SELECT DISTINCT table_schema AS schema, + column_name AS name, + data_type AS type, + is_nullable AS null, + column_default AS default, + ordinal_position AS position, + character_maximum_length AS char_length, + character_octet_length AS oct_length, + pg_get_serial_sequence(attr.attrelid::regclass::text, attr.attname) IS NOT NULL AS has_serial + FROM information_schema.columns c + INNER JOIN pg_catalog.pg_namespace ns ON (ns.nspname = table_schema) + INNER JOIN pg_catalog.pg_class cl ON (cl.relnamespace = ns.oid AND cl.relname = table_name) + LEFT JOIN pg_catalog.pg_attribute attr ON (cl.oid = attr.attrelid AND column_name = attr.attname) + WHERE table_name = ? AND table_schema = ? AND table_catalog = ? + ORDER BY ordinal_position', + array($table, $this->config['schema'], $this->config['database']) ); // @codingStandardsIgnoreStart @@ -238,17 +250,25 @@ class Postgres extends DboSource { "$1", preg_replace('/::.*/', '', $c->default) ), - 'length' => $length + 'length' => $length, ); - if ($model instanceof Model) { - if ($c->name === $model->primaryKey) { - $fields[$c->name]['key'] = 'primary'; - if ( - $fields[$c->name]['type'] !== 'string' && - $fields[$c->name]['type'] !== 'uuid' - ) { - $fields[$c->name]['length'] = 11; - } + + // Serial columns are primary integer keys + if ($c->has_serial) { + $fields[$c->name]['key'] = 'primary'; + $fields[$c->name]['length'] = 11; + $hasPrimary = true; + } + if ($hasPrimary === false && + $model instanceof Model && + $c->name === $model->primaryKey + ) { + $fields[$c->name]['key'] = 'primary'; + if ( + $fields[$c->name]['type'] !== 'string' && + $fields[$c->name]['type'] !== 'uuid' + ) { + $fields[$c->name]['length'] = 11; } } if ( diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index 7d27fc681..b2e887313 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -688,7 +688,6 @@ class CakeSchemaTest extends CakeTestCase { * @return void */ public function testSchemaReadWithNonConventionalPrimaryKey() { - $this->skipIf($this->db instanceof Postgres, 'Cannot test on Postgres'); $db = ConnectionManager::getDataSource('test'); $fixture = new NonConventionalPrimaryKeyFixture(); $fixture->create($db); @@ -700,14 +699,14 @@ class CakeSchemaTest extends CakeTestCase { )); $fixture->drop($db); - $hasTable = isset($read['tables']['non_conventional']); - $this->assertTrue($hasTable, 'non_conventional table should appear'); + $this->assertArrayHasKey('non_conventional', $read['tables']); $versionIdHasKey = isset($read['tables']['non_conventional']['version_id']['key']); $this->assertTrue($versionIdHasKey, 'version_id key should be set'); $versionIdKeyIsPrimary = $read['tables']['non_conventional']['version_id']['key'] === 'primary'; $this->assertTrue($versionIdKeyIsPrimary, 'version_id key should be primary'); - $idHasNoKey = !isset($read['tables']['non_conventional']['id']['key']); - $this->assertTrue($idHasNoKey, 'id key should not be set'); + + $idHasKey = isset($read['tables']['non_conventional']['id']['key']); + $this->assertFalse($idHasKey, 'id key should not be set'); } /** From 240c8477b8531be83d0ca08d6fe1ca6e0c603cfa Mon Sep 17 00:00:00 2001 From: Henrik Gemal Date: Thu, 30 Mar 2017 09:40:17 +0200 Subject: [PATCH 17/41] Fixing locale names --- lib/Cake/I18n/L10n.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Cake/I18n/L10n.php b/lib/Cake/I18n/L10n.php index c2bc64f56..c7808fddd 100644 --- a/lib/Cake/I18n/L10n.php +++ b/lib/Cake/I18n/L10n.php @@ -269,7 +269,7 @@ class L10n { 'hi' => array('language' => 'Hindi', 'locale' => 'hin', 'localeFallback' => 'hin', 'charset' => 'utf-8', 'direction' => 'ltr'), 'hr' => array('language' => 'Croatian', 'locale' => 'hrv', 'localeFallback' => 'hrv', 'charset' => 'utf-8', 'direction' => 'ltr'), 'hu' => array('language' => 'Hungarian', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'), - 'hu-hu' => array('language' => 'Hungarian (Hungary)', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'), + 'hu-hu' => array('language' => 'Hungarian (Hungary)', 'locale' => 'hu_hu', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'), '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'), @@ -287,7 +287,7 @@ class L10n { 'li' => array('language' => 'Limburgish', 'locale' => 'lim', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'), 'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', 'direction' => 'ltr'), 'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'), - 'lv-lv' => array('language' => 'Latvian (Latvia)', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'), + 'lv-lv' => array('language' => 'Latvian (Latvia)', 'locale' => 'lv_lv', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'), 'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mkd', 'localeFallback' => 'mkd', 'charset' => 'utf-8', 'direction' => 'ltr'), 'mk-mk' => array('language' => 'Macedonian', 'locale' => 'mk_mk', 'localeFallback' => 'mkd', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ms' => array('language' => 'Malaysian', 'locale' => 'msa', 'localeFallback' => 'msa', 'charset' => 'utf-8', 'direction' => 'ltr'), @@ -309,7 +309,7 @@ class L10n { 'ro-ro' => array('language' => 'Romanian (Romania)', 'locale' => 'ro_ro', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ru' => array('language' => 'Russian', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ru-mo' => array('language' => 'Russian (Moldavia)', 'locale' => 'ru_mo', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'), - 'ru-ru' => array('language' => 'Russian (Russia)', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'), + 'ru-ru' => array('language' => 'Russian (Russia)', 'locale' => 'ru_ru', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'), 'sb' => array('language' => 'Sorbian', 'locale' => 'wen', 'localeFallback' => 'wen', 'charset' => 'utf-8', 'direction' => 'ltr'), 'sk' => array('language' => 'Slovak', 'locale' => 'slk', 'localeFallback' => 'slk', 'charset' => 'utf-8', 'direction' => 'ltr'), 'sl' => array('language' => 'Slovenian', 'locale' => 'slv', 'localeFallback' => 'slv', 'charset' => 'utf-8', 'direction' => 'ltr'), From 6cdb2d2905813c35bf7674cd77c347f50449c494 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 1 Apr 2017 22:09:17 -0400 Subject: [PATCH 18/41] Update version number to 2.9.7 --- lib/Cake/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/VERSION.txt b/lib/Cake/VERSION.txt index 2cfeb3fd8..86ce29b56 100644 --- a/lib/Cake/VERSION.txt +++ b/lib/Cake/VERSION.txt @@ -17,4 +17,4 @@ // @license http://www.opensource.org/licenses/mit-license.php MIT License // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -2.9.6 +2.9.7 From 9be647cefd792ac2e86fa2c03b6d0b67b7462c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Mon, 3 Apr 2017 12:17:32 +0200 Subject: [PATCH 19/41] Use more readable variable names --- lib/Cake/Core/CakePlugin.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Core/CakePlugin.php b/lib/Cake/Core/CakePlugin.php index 426e22a94..6dde9221d 100644 --- a/lib/Cake/Core/CakePlugin.php +++ b/lib/Cake/Core/CakePlugin.php @@ -124,6 +124,7 @@ class CakePlugin { /** * Will load all the plugins located in the configured plugins folders + * * If passed an options array, it will be used as a common default for all plugins to be loaded * It is possible to set specific defaults for each plugins in the options array. Examples: * @@ -155,12 +156,12 @@ class CakePlugin { */ public static function loadAll($options = array()) { $plugins = App::objects('plugins'); - foreach ($plugins as $p) { - $opts = isset($options[$p]) ? (array)$options[$p] : array(); + foreach ($plugins as $plugin) { + $pluginOptions = isset($options[$plugin]) ? (array)$options[$plugin] : array(); if (isset($options[0])) { - $opts += $options[0]; + $pluginOptions += $options[0]; } - static::load($p, $opts); + static::load($plugin, $pluginOptions); } } From 192a4c5ef0697bd0bd143b40b5237929984eb656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Mon, 3 Apr 2017 12:30:24 +0200 Subject: [PATCH 20/41] Improve punctuation & code examples in doc blocks --- lib/Cake/Core/CakePlugin.php | 55 +++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/lib/Cake/Core/CakePlugin.php b/lib/Cake/Core/CakePlugin.php index 426e22a94..40dc20226 100644 --- a/lib/Cake/Core/CakePlugin.php +++ b/lib/Cake/Core/CakePlugin.php @@ -17,8 +17,9 @@ */ /** - * CakePlugin is responsible for loading and unloading plugins. It also can - * retrieve plugin paths and load their bootstrap and routes files. + * CakePlugin is responsible for loading and unloading plugins. + * + * It also can retrieve plugin paths and load their bootstrap and routes files. * * @package Cake.Core * @link http://book.cakephp.org/2.0/en/plugins.html @@ -37,45 +38,47 @@ class CakePlugin { * * Examples: * - * `CakePlugin::load('DebugKit')` + * `CakePlugin::load('DebugKit');` * - * Will load the DebugKit plugin and will not load any bootstrap nor route files + * Will load the DebugKit plugin and will not load any bootstrap nor route files. * - * `CakePlugin::load('DebugKit', array('bootstrap' => true, 'routes' => true))` + * `CakePlugin::load('DebugKit', array('bootstrap' => true, 'routes' => true));` * - * will load the bootstrap.php and routes.php files + * Will load the bootstrap.php and routes.php files. * - * `CakePlugin::load('DebugKit', array('bootstrap' => false, 'routes' => true))` + * `CakePlugin::load('DebugKit', array('bootstrap' => false, 'routes' => true));` * - * will load routes.php file but not bootstrap.php + * Will load routes.php file but not bootstrap.php. * - * `CakePlugin::load('DebugKit', array('bootstrap' => array('config1', 'config2')))` + * `CakePlugin::load('DebugKit', array('bootstrap' => array('config1', 'config2')));` * - * will load config1.php and config2.php files + * Will load config1.php and config2.php files. * - * `CakePlugin::load('DebugKit', array('bootstrap' => 'aCallableMethod'))` + * `CakePlugin::load('DebugKit', array('bootstrap' => 'aCallableMethod'));` * - * will run the aCallableMethod function to initialize it + * Will run the aCallableMethod function to initialize it. * * Bootstrap initialization functions can be expressed as a PHP callback type, * including closures. Callbacks will receive two parameters - * (plugin name, plugin configuration) + * (plugin name, plugin configuration). * * It is also possible to load multiple plugins at once. Examples: * - * `CakePlugin::load(array('DebugKit', 'ApiGenerator'))` + * `CakePlugin::load(array('DebugKit', 'ApiGenerator'));` * - * will load the DebugKit and ApiGenerator plugins + * Will load the DebugKit and ApiGenerator plugins. * - * `CakePlugin::load(array('DebugKit', 'ApiGenerator'), array('bootstrap' => true))` + * `CakePlugin::load(array('DebugKit', 'ApiGenerator'), array('bootstrap' => true));` * - * will load bootstrap file for both plugins + * Will load bootstrap file for both plugins. * * ``` * CakePlugin::load(array( - * 'DebugKit' => array('routes' => true), - * 'ApiGenerator' - * ), array('bootstrap' => true)) + * 'DebugKit' => array('routes' => true), + * 'ApiGenerator' + * ), + * array('bootstrap' => true) + * ); * ``` * * Will only load the bootstrap for ApiGenerator and only the routes for DebugKit. @@ -131,7 +134,7 @@ class CakePlugin { * CakePlugin::loadAll(array( * array('bootstrap' => true), * 'DebugKit' => array('routes' => true, 'bootstrap' => false), - * )) + * )); * ``` * * The above example will load the bootstrap file for all plugins, but for DebugKit it will only load @@ -140,11 +143,11 @@ class CakePlugin { * each plugin you can use the `ignoreMissing` option: * * ``` - * CakePlugin::loadAll(array( - * 'ignoreMissing' => true, - * 'bootstrap' => true, - * 'routes' => true, - * )); + * CakePlugin::loadAll(array( + * 'ignoreMissing' => true, + * 'bootstrap' => true, + * 'routes' => true, + * )); * ``` * * The ignoreMissing option will do additional file_exists() calls but is simpler From 7dbc71df8c93766e87833a0316ecba332000c776 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 4 Apr 2017 22:59:05 -0400 Subject: [PATCH 21/41] Conditionally define TLS constants & add test for new types. Only map the new TLS constants if they exist. --- lib/Cake/Network/CakeSocket.php | 18 ++++++++++--- lib/Cake/Test/Case/Network/CakeSocketTest.php | 25 +++++++++++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php index c208805c8..7a9d27588 100644 --- a/lib/Cake/Network/CakeSocket.php +++ b/lib/Cake/Network/CakeSocket.php @@ -94,14 +94,10 @@ class CakeSocket { 'sslv3_client' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT, 'sslv23_client' => STREAM_CRYPTO_METHOD_SSLv23_CLIENT, 'tls_client' => STREAM_CRYPTO_METHOD_TLS_CLIENT, - 'tlsv1_1_client' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, - 'tlsv1_2_client' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, 'sslv2_server' => STREAM_CRYPTO_METHOD_SSLv2_SERVER, 'sslv3_server' => STREAM_CRYPTO_METHOD_SSLv3_SERVER, 'sslv23_server' => STREAM_CRYPTO_METHOD_SSLv23_SERVER, 'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER, - 'tlsv1_1_server' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, - 'tlsv1_2_server' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER // @codingStandardsIgnoreEnd ); @@ -121,6 +117,20 @@ class CakeSocket { */ public function __construct($config = array()) { $this->config = array_merge($this->_baseConfig, $config); + + // These TLS versions are not supported by older PHP versions, + // so we have to conditionally set them if they are supported. + $conditionalCrypto = array( + 'tlsv1_1_client' => 'STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT', + 'tlsv1_2_client' => 'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT', + 'tlsv1_1_server' => 'STREAM_CRYPTO_METHOD_TLSv1_1_SERVER', + 'tlsv1_2_server' => 'STREAM_CRYPTO_METHOD_TLSv1_2_SERVER' + ); + foreach ($conditionalCrypto as $key => $const) { + if (defined($const)) { + $this->_encryptMethods[$key] = constant($const); + } + } } /** diff --git a/lib/Cake/Test/Case/Network/CakeSocketTest.php b/lib/Cake/Test/Case/Network/CakeSocketTest.php index c678d9c5b..43a4c3936 100644 --- a/lib/Cake/Test/Case/Network/CakeSocketTest.php +++ b/lib/Cake/Test/Case/Network/CakeSocketTest.php @@ -54,11 +54,12 @@ class CakeSocketTest extends CakeTestCase { $this->Socket = new CakeSocket(); $config = $this->Socket->config; $this->assertSame($config, array( - 'persistent' => false, - 'host' => 'localhost', - 'protocol' => 'tcp', - 'port' => 80, - 'timeout' => 30 + 'persistent' => false, + 'host' => 'localhost', + 'protocol' => 'tcp', + 'port' => 80, + 'timeout' => 30, + 'cryptoType' => 'tls', )); $this->Socket->reset(); @@ -324,6 +325,20 @@ class CakeSocketTest extends CakeTestCase { $this->Socket->disconnect(); } +/** + * testEnableCrypto tlsv1_1 + * + * @return void + */ + public function testEnableCryptoTlsV11() { + $this->skipIf(!defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT'), 'TLS1.1 is not supported on this system'); + + // testing on tls server + $this->_connectSocketToSslTls(); + $this->assertTrue($this->Socket->enableCrypto('tlsv1_1', 'client')); + $this->Socket->disconnect(); + } + /** * testEnableCryptoExceptionEnableTwice * From 4475cc06fd36017632ced497fc22ab01bd87f5d2 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 4 Apr 2017 23:17:30 -0400 Subject: [PATCH 22/41] Update tls_client and tls_server to include newer TLS versions. Refs #10445 --- lib/Cake/Network/CakeSocket.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php index 7a9d27588..461ce31a5 100644 --- a/lib/Cake/Network/CakeSocket.php +++ b/lib/Cake/Network/CakeSocket.php @@ -131,6 +131,18 @@ class CakeSocket { $this->_encryptMethods[$key] = constant($const); } } + + // As of PHP5.6.6, STREAM_CRYPTO_METHOD_TLS_CLIENT does not include + // TLS1.1 or 1.2. If we have TLS1.2 support we need to update the method map. + // + // See https://bugs.php.net/bug.php?id=69195 & + // https://github.com/php/php-src/commit/10bc5fd4c4c8e1dd57bd911b086e9872a56300a0 + if (isset($this->_encryptMethods['tlsv1_2_client'])) { + $this->_encryptMethods['tls_client'] = STREAM_CRYPTO_METHOD_TLS_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + } + if (isset($this->_encryptMethods['tlsv1_2_server'])) { + $this->_encryptMethods['tls_server'] = STREAM_CRYPTO_METHOD_TLS_SERVER | STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; + } } /** From 5685c031e21756b791202651f1323902d1f324fd Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 5 Apr 2017 13:02:17 -0400 Subject: [PATCH 23/41] Disable autocomplete on CSRF/Security token fields. New versions of Safari will overwrite these fields when a user uses the back button. If one-time CSRF tokens are in use the request will be blackholed. Refs #10486 --- .../Test/Case/View/Helper/FormHelperTest.php | 95 ++++++++++++------- lib/Cake/View/Helper/FormHelper.php | 5 +- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 2fe621ff8..24c5badef 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -592,7 +592,7 @@ class FormHelperTest extends CakeTestCase { 'div' => array('style' => 'display:none;'), array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testKey', 'id' + 'type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testKey', 'id', 'autocomplete' )), '/div' ); @@ -708,11 +708,13 @@ class FormHelperTest extends CakeTestCase { 'type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => $hash, 'id' => 'preg:/TokenFields\d+/', 'form' => 'MyTestForm', + 'autocomplete' => 'off', )), array('input' => array( 'type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/', 'form' => 'MyTestForm', + 'autocomplete' => 'off', )), '/div' ); @@ -877,11 +879,13 @@ class FormHelperTest extends CakeTestCase { 'div' => array('style' => 'display:none;'), array('input' => array( 'type' => 'hidden', 'name' => 'data[_Token][fields]', - 'value' => $hash, 'id' => 'preg:/TokenFields\d+/' + 'value' => $hash, 'id' => 'preg:/TokenFields\d+/', + 'autocomplete' => 'off', )), array('input' => array( 'type' => 'hidden', 'name' => 'data[_Token][unlocked]', - 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/' + 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/', + 'autocomplete' => 'off', )), '/div' ); @@ -924,11 +928,13 @@ class FormHelperTest extends CakeTestCase { 'div' => array('style' => 'display:none;'), array('input' => array( 'type' => 'hidden', 'name' => 'data[_Token][fields]', - 'value' => 'preg:/.+/', 'id' => 'preg:/TokenFields\d+/' + 'value' => 'preg:/.+/', 'id' => 'preg:/TokenFields\d+/', + 'autocomplete' => 'off', )), array('input' => array( 'type' => 'hidden', 'name' => 'data[_Token][unlocked]', - 'value' => 'cancel%7Csave', 'id' => 'preg:/TokenUnlocked\d+/' + 'value' => 'cancel%7Csave', 'id' => 'preg:/TokenUnlocked\d+/', + 'autocomplete' => 'off', )), '/div' ); @@ -1044,11 +1050,13 @@ class FormHelperTest extends CakeTestCase { 'div' => array('style' => 'display:none;'), array('input' => array( 'type' => 'hidden', 'name' => 'data[_Token][fields]', - 'value' => $hash, 'id' => 'preg:/TokenFields\d+/' + 'value' => $hash, 'id' => 'preg:/TokenFields\d+/', + 'autocomplete' => 'off', )), array('input' => array( 'type' => 'hidden', 'name' => 'data[_Token][unlocked]', - 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/' + 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/', + 'autocomplete' => 'off', )), '/div' ); @@ -1108,12 +1116,18 @@ class FormHelperTest extends CakeTestCase { $expected = array( 'div' => array('style' => 'display:none;'), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][fields]', - 'value' => $hash, 'id' => 'preg:/TokenFields\d+/' + 'type' => 'hidden', 'name' => + 'data[_Token][fields]', + 'value' => $hash, + 'id' => 'preg:/TokenFields\d+/', + 'autocomplete' => 'off' )), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][unlocked]', - 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/' + 'type' => 'hidden', + 'name' => 'data[_Token][unlocked]', + 'value' => 'address%7Cfirst_name', + 'id' => 'preg:/TokenUnlocked\d+/', + 'autocomplete' => 'off' )), '/div' ); @@ -1157,12 +1171,18 @@ class FormHelperTest extends CakeTestCase { $expected = array( 'div' => array('style' => 'display:none;'), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][fields]', - 'value' => $hash, 'id' => 'preg:/TokenFields\d+/' + 'type' => 'hidden', + 'name' => 'data[_Token][fields]', + 'value' => $hash, + 'id' => 'preg:/TokenFields\d+/', + 'autocomplete' => 'off', )), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][unlocked]', - 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/' + 'type' => 'hidden', + 'name' => 'data[_Token][unlocked]', + 'value' => 'address%7Cfirst_name', + 'id' => 'preg:/TokenUnlocked\d+/', + 'autocomplete' => 'off', )), '/div' ); @@ -1201,8 +1221,11 @@ class FormHelperTest extends CakeTestCase { 'div' => array('style' => 'display:none;'), array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][key]', - 'value' => 'testKey', 'id' => 'preg:/Token\d+/' + 'type' => 'hidden', + 'name' => 'data[_Token][key]', + 'value' => 'testKey', + 'id' => 'preg:/Token\d+/', + 'autocomplete' => 'off', )), '/div' ); @@ -1282,12 +1305,18 @@ class FormHelperTest extends CakeTestCase { $expected = array( 'div' => array('style' => 'display:none;'), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][fields]', - 'value' => $hash, 'id' => 'preg:/TokenFields\d+/' + 'type' => 'hidden', + 'name' => 'data[_Token][fields]', + 'value' => $hash, + 'id' => 'preg:/TokenFields\d+/', + 'autocomplete' => 'off', )), array('input' => array( - 'type' => 'hidden', 'name' => 'data[_Token][unlocked]', - 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/' + 'type' => 'hidden', + 'name' => 'data[_Token][unlocked]', + 'value' => '', + 'id' => 'preg:/TokenUnlocked\d+/', + 'autocomplete' => 'off', )), '/div' ); @@ -8143,14 +8172,14 @@ class FormHelperTest extends CakeTestCase { ), array('div' => array('style' => 'display:none;')), array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/', 'autocomplete')), '/div', 'button' => array('type' => 'submit'), 'Delete', '/button', array('div' => array('style' => 'display:none;')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/', 'autocomplete')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/', 'autocomplete')), '/div', '/form', ); @@ -8271,10 +8300,10 @@ class FormHelperTest extends CakeTestCase { 'name', 'id', 'style' => 'display:none;' ), array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'test', 'id')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'test', 'id', 'autocomplete')), 'div' => array('style' => 'display:none;'), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => $hash, 'id')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => $hash, 'id', 'autocomplete')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id', 'autocomplete')), '/div', '/form', 'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'), @@ -8353,10 +8382,10 @@ class FormHelperTest extends CakeTestCase { 'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;' ), array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/', 'autocomplete' => 'off')), 'div' => array('style' => 'display:none;'), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/', 'autocomplete')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/', 'autocomplete')), '/div', '/form', 'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'), @@ -8380,10 +8409,10 @@ class FormHelperTest extends CakeTestCase { 'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;' ), array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/', 'autocomplete' => 'off')), 'div' => array('style' => 'display:none;'), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')), - array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/', 'autocomplete')), + array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/', 'autocomplete')), '/div', '/form', 'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'), diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 810d5a358..9990c73c9 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -504,7 +504,8 @@ class FormHelper extends AppHelper { } return $this->hidden('_Token.key', array( 'value' => $this->request->params['_Token']['key'], 'id' => 'Token' . mt_rand(), - 'secure' => static::SECURE_SKIP + 'secure' => static::SECURE_SKIP, + 'autocomplete' => 'off', )); } @@ -614,12 +615,14 @@ class FormHelper extends AppHelper { 'value' => urlencode($fields . ':' . $locked), 'id' => 'TokenFields' . mt_rand(), 'secure' => static::SECURE_SKIP, + 'autocomplete' => 'off', )); $out = $this->hidden('_Token.fields', $tokenFields); $tokenUnlocked = array_merge($secureAttributes, array( 'value' => urlencode($unlocked), 'id' => 'TokenUnlocked' . mt_rand(), 'secure' => static::SECURE_SKIP, + 'autocomplete' => 'off', )); $out .= $this->hidden('_Token.unlocked', $tokenUnlocked); return $this->Html->useTag('hiddenblock', $out); From c74d2e086040ea8b85f97ac86da4809c66c65a25 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 6 Apr 2017 10:00:47 -0400 Subject: [PATCH 24/41] Split conditional TLS versions into a separate method Having a separate method gives a nicer home to the inline comments. I've had to disable coding standards checks as the constants provided by PHP do not follow the UPPER_CASE conventions. --- lib/Cake/Network/CakeSocket.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php index 461ce31a5..61ec5ff40 100644 --- a/lib/Cake/Network/CakeSocket.php +++ b/lib/Cake/Network/CakeSocket.php @@ -45,7 +45,7 @@ class CakeSocket { 'protocol' => 'tcp', 'port' => 80, 'timeout' => 30, - 'cryptoType' => 'tls' + 'cryptoType' => 'tls', ); /** @@ -118,8 +118,23 @@ class CakeSocket { public function __construct($config = array()) { $this->config = array_merge($this->_baseConfig, $config); - // These TLS versions are not supported by older PHP versions, - // so we have to conditionally set them if they are supported. + $this->_addTlsVersions(); + } + +/** + * Add TLS versions that are dependent on specific PHP versions. + * + * These TLS versions are not supported by older PHP versions, + * so we have to conditionally set them if they are supported. + * + * As of PHP5.6.6, STREAM_CRYPTO_METHOD_TLS_CLIENT does not include + * TLS1.1 or 1.2. If we have TLS1.2 support we need to update the method map. + * + * @see https://bugs.php.net/bug.php?id=69195 + * @see https://github.com/php/php-src/commit/10bc5fd4c4c8e1dd57bd911b086e9872a56300a0 + * @return void + */ + protected function _addTlsVersions() { $conditionalCrypto = array( 'tlsv1_1_client' => 'STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT', 'tlsv1_2_client' => 'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT', @@ -132,17 +147,14 @@ class CakeSocket { } } - // As of PHP5.6.6, STREAM_CRYPTO_METHOD_TLS_CLIENT does not include - // TLS1.1 or 1.2. If we have TLS1.2 support we need to update the method map. - // - // See https://bugs.php.net/bug.php?id=69195 & - // https://github.com/php/php-src/commit/10bc5fd4c4c8e1dd57bd911b086e9872a56300a0 + // @codingStandardsIgnoreStart if (isset($this->_encryptMethods['tlsv1_2_client'])) { $this->_encryptMethods['tls_client'] = STREAM_CRYPTO_METHOD_TLS_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; } if (isset($this->_encryptMethods['tlsv1_2_server'])) { $this->_encryptMethods['tls_server'] = STREAM_CRYPTO_METHOD_TLS_SERVER | STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; } + // @codingStandardsIgnoreEnd } /** From fa68c93c2d2934cae4399b08e7bcb54d1b320236 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 6 Apr 2017 10:08:17 -0400 Subject: [PATCH 25/41] Fix failing test. This test merges config funny. --- lib/Cake/Test/Case/Network/Http/HttpSocketTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php index 404f977f1..89bbcdb21 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php @@ -215,11 +215,13 @@ class HttpSocketTest extends CakeTestCase { $this->Socket->expects($this->never())->method('connect'); $this->Socket->__construct(array('host' => 'foo-bar')); $baseConfig['host'] = 'foo-bar'; + $baseConfig['cryptoType'] = 'tls'; $this->assertEquals($this->Socket->config, $baseConfig); $this->Socket->reset(); $baseConfig = $this->Socket->config; $this->Socket->__construct('http://www.cakephp.org:23/'); + $baseConfig['cryptoType'] = 'tls'; $baseConfig['host'] = $baseConfig['request']['uri']['host'] = 'www.cakephp.org'; $baseConfig['port'] = $baseConfig['request']['uri']['port'] = 23; $baseConfig['request']['uri']['scheme'] = 'http'; From 7d74818d9a0a7cd3bddb49b3192927a8d5a4444c Mon Sep 17 00:00:00 2001 From: ndm2 Date: Thu, 13 Apr 2017 13:39:17 +0200 Subject: [PATCH 26/41] Fix `ControllerTestCase::testAction()` incompatibility with `App.base`. When using array URLs with `testAction()`, the generated URL possibly contains the configured `App.base` path, which needs to be stripped when set on the request object, as otherwise routes cannot be matched correctly. When passing the URL as an option to the `CakeRequest` constructor, the it will be set as-is, unlike when the URL is being generated by `CakeRequest::_url()`, which grabs the URL from the environment, and strips the possible base path. --- .../Case/TestSuite/ControllerTestCaseTest.php | 26 +++++++++++++++++++ lib/Cake/TestSuite/ControllerTestCase.php | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php index 4f47c1e10..ee8440758 100644 --- a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php +++ b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php @@ -624,4 +624,30 @@ class ControllerTestCaseTest extends CakeTestCase { $this->assertEquals($restored, $_POST); } +/** + * Tests that the `App.base` path is properly stripped from the URL generated from the + * given URL array, and that consequently the correct controller/action is being matched. + * + * @return void + */ + public function testAppBaseConfigCompatibilityWithArrayUrls() { + Configure::write('App.base', '/cakephp'); + + $this->Case->generate('TestsApps'); + $this->Case->testAction(array('controller' => 'tests_apps', 'action' => 'index')); + + $this->assertEquals('/cakephp', $this->Case->controller->request->base); + $this->assertEquals('/cakephp/', $this->Case->controller->request->webroot); + $this->assertEquals('/cakephp/tests_apps', $this->Case->controller->request->here); + $this->assertEquals('tests_apps', $this->Case->controller->request->url); + + $expected = array( + 'plugin' => null, + 'controller' => 'tests_apps', + 'action' => 'index', + 'named' => array(), + 'pass' => array(), + ); + $this->assertEquals($expected, array_intersect_key($expected, $this->Case->controller->request->params)); + } } diff --git a/lib/Cake/TestSuite/ControllerTestCase.php b/lib/Cake/TestSuite/ControllerTestCase.php index 768fea5f3..11ec526ab 100644 --- a/lib/Cake/TestSuite/ControllerTestCase.php +++ b/lib/Cake/TestSuite/ControllerTestCase.php @@ -248,7 +248,8 @@ abstract class ControllerTestCase extends CakeTestCase { $_GET = array(); } } - $request = $this->getMock('CakeRequest', array('_readInput'), array($url)); + $_SERVER['REQUEST_URI'] = $url; + $request = $this->getMock('CakeRequest', array('_readInput')); if (is_string($options['data'])) { $request->expects($this->any()) From d9059b6d3b7d104acb4bab22db5bb95646a59d06 Mon Sep 17 00:00:00 2001 From: ndm2 Date: Sat, 15 Apr 2017 21:27:29 +0200 Subject: [PATCH 27/41] Fix `array_intersect_key()` argument order, the source comes first. --- lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php index ee8440758..9a5f33124 100644 --- a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php +++ b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php @@ -648,6 +648,6 @@ class ControllerTestCaseTest extends CakeTestCase { 'named' => array(), 'pass' => array(), ); - $this->assertEquals($expected, array_intersect_key($expected, $this->Case->controller->request->params)); + $this->assertEquals($expected, array_intersect_key($this->Case->controller->request->params, $expected)); } } From 9007a7fe5857db94ef7154a614bfa073d89f4d4d Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 16 Apr 2017 09:57:36 -0400 Subject: [PATCH 28/41] Fix notBlank() to pass on -0.0 Copy the implementation from 3.x as it works with -0.0 already. Refs #10521 --- lib/Cake/Test/Case/Utility/ValidationTest.php | 4 ++++ lib/Cake/Utility/Validation.php | 11 +++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/ValidationTest.php b/lib/Cake/Test/Case/Utility/ValidationTest.php index bec844dcb..1cb2bfd08 100644 --- a/lib/Cake/Test/Case/Utility/ValidationTest.php +++ b/lib/Cake/Test/Case/Utility/ValidationTest.php @@ -148,6 +148,10 @@ class ValidationTest extends CakeTestCase { * @return void */ public function testNotBlank() { + $this->assertTrue(Validation::notBlank(0)); + $this->assertTrue(Validation::notBlank(0.0)); + $this->assertTrue(Validation::notBlank(-0)); + $this->assertTrue(Validation::notBlank(-0.0)); $this->assertTrue(Validation::notBlank('abcdefg')); $this->assertTrue(Validation::notBlank('fasdf ')); $this->assertTrue(Validation::notBlank('fooo' . chr(243) . 'blabla')); diff --git a/lib/Cake/Utility/Validation.php b/lib/Cake/Utility/Validation.php index da614de1d..bc7a18829 100644 --- a/lib/Cake/Utility/Validation.php +++ b/lib/Cake/Utility/Validation.php @@ -66,19 +66,14 @@ class Validation { * * Returns true if string contains something other than whitespace * - * $check can be passed as an array: - * array('check' => 'valueToCheck'); - * - * @param string|array $check Value to check + * @param string $check Value to check * @return bool Success */ public static function notBlank($check) { - if (!is_scalar($check)) { - return false; - } - if (empty($check) && (string)$check !== '0') { + if (empty($check) && !is_bool($check) && !is_numeric($check)) { return false; } + return static::_check($check, '/[^\s]+/m'); } From ea05b041933a854d259d57f132000c72f41bdfae Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 16 Apr 2017 23:00:21 -0400 Subject: [PATCH 29/41] Add additional test for -0.0 In PHP5 `-0.0` doesn't work. Include the other way of making -0 for PHP5. Refs #10521 --- lib/Cake/Test/Case/Utility/ValidationTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/ValidationTest.php b/lib/Cake/Test/Case/Utility/ValidationTest.php index 1cb2bfd08..d10aa2f6e 100644 --- a/lib/Cake/Test/Case/Utility/ValidationTest.php +++ b/lib/Cake/Test/Case/Utility/ValidationTest.php @@ -148,10 +148,10 @@ class ValidationTest extends CakeTestCase { * @return void */ public function testNotBlank() { - $this->assertTrue(Validation::notBlank(0)); - $this->assertTrue(Validation::notBlank(0.0)); - $this->assertTrue(Validation::notBlank(-0)); - $this->assertTrue(Validation::notBlank(-0.0)); + $this->assertTrue(Validation::notBlank(0), 'zero should not be blank'); + $this->assertTrue(Validation::notBlank(0.0), 'zero should not be blank'); + $this->assertTrue(Validation::notBlank(0.0 * -1), 'negative 0 should not be blank'); + $this->assertTrue(Validation::notBlank(-0.0), 'negative 0 should not be blank'); $this->assertTrue(Validation::notBlank('abcdefg')); $this->assertTrue(Validation::notBlank('fasdf ')); $this->assertTrue(Validation::notBlank('fooo' . chr(243) . 'blabla')); From efb347442069b4521abff3c363a152fd3d6c1338 Mon Sep 17 00:00:00 2001 From: ndm2 Date: Tue, 18 Apr 2017 20:54:34 +0200 Subject: [PATCH 30/41] Fix query string data in URL arrays not being passed anymore. refs #10555, #10517, #5473 --- .../Case/TestSuite/ControllerTestCaseTest.php | 77 +++++++++++++++++++ lib/Cake/TestSuite/ControllerTestCase.php | 7 ++ 2 files changed, 84 insertions(+) diff --git a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php index 9a5f33124..0819f8db3 100644 --- a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php +++ b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php @@ -650,4 +650,81 @@ class ControllerTestCaseTest extends CakeTestCase { ); $this->assertEquals($expected, array_intersect_key($this->Case->controller->request->params, $expected)); } + +/** + * Tests that query string data from URL arrays properly makes it into the request object + * on GET requests. + * + * @return void + */ + public function testTestActionWithArrayUrlQueryStringDataViaGetRequest() { + $query = array('foo' => 'bar'); + + $this->Case->generate('TestsApps'); + $this->Case->testAction( + array( + 'controller' => 'tests_apps', + 'action' => 'index', + '?' => $query + ), + array( + 'method' => 'get' + ) + ); + + $this->assertEquals('tests_apps', $this->Case->controller->request->url); + $this->assertEquals($query, $this->Case->controller->request->query); + } + +/** + * Tests that query string data from URL arrays properly makes it into the request object + * on POST requests. + * + * @return void + */ + public function testTestActionWithArrayUrlQueryStringDataViaPostRequest() { + $query = array('foo' => 'bar'); + + $this->Case->generate('TestsApps'); + $this->Case->testAction( + array( + 'controller' => 'tests_apps', + 'action' => 'index', + '?' => $query + ), + array( + 'method' => 'post' + ) + ); + + $this->assertEquals('tests_apps', $this->Case->controller->request->url); + $this->assertEquals($query, $this->Case->controller->request->query); + } + +/** + * Tests that query string data from both, URL arrays as well as the `data` option, + * properly makes it into the request object. + * + * @return void + */ + public function testTestActionWithArrayUrlQueryStringDataAndDataOptionViaGetRequest() { + $query = array('foo' => 'bar'); + $data = array('bar' => 'foo'); + + $this->Case->generate('TestsApps'); + $this->Case->testAction( + array( + 'controller' => 'tests_apps', + 'action' => 'index', + '?' => $query + ), + array( + 'method' => 'get', + 'data' => $data + ) + ); + + $this->assertEquals('tests_apps', $this->Case->controller->request->url); + $this->assertEquals($data + $query, $this->Case->controller->request->query); + } } diff --git a/lib/Cake/TestSuite/ControllerTestCase.php b/lib/Cake/TestSuite/ControllerTestCase.php index 11ec526ab..0036546bd 100644 --- a/lib/Cake/TestSuite/ControllerTestCase.php +++ b/lib/Cake/TestSuite/ControllerTestCase.php @@ -248,6 +248,13 @@ abstract class ControllerTestCase extends CakeTestCase { $_GET = array(); } } + + if (strpos($url, '?') !== false) { + list($url, $query) = explode('?', $url, 2); + parse_str($query, $queryArgs); + $_GET += $queryArgs; + } + $_SERVER['REQUEST_URI'] = $url; $request = $this->getMock('CakeRequest', array('_readInput')); From ce9f33314d700e4c47700a450efe821806e60bc8 Mon Sep 17 00:00:00 2001 From: Livia Scapin Date: Wed, 19 Apr 2017 17:12:24 +0200 Subject: [PATCH 31/41] Added documentation for App.base As discussed in https://github.com/cakephp/docs/issues/4895 --- app/Config/core.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/Config/core.php b/app/Config/core.php index 61277674d..7bb39ee5a 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -116,10 +116,17 @@ * for any URL generation inside the application, set the following * configuration variable to the http(s) address to your domain. This * will override the automatic detection of full base URL and can be - * useful when generating links from the CLI (e.g. sending emails) + * useful when generating links from the CLI (e.g. sending emails). + * If the application runs in a subfolder, you should also set App.base. */ //Configure::write('App.fullBaseUrl', 'http://example.com'); +/** + * The base directory the app resides in. Should be used if the + * application runs in a subfolder and App.fullBaseUrl is set. + */ + //Configure::write('App.base', '/my_app'); + /** * Web path to the public images directory under webroot. * If not set defaults to 'img/' From 043b320358e6cbe300dbb761d5b87e7901c6831e Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 21 Apr 2017 21:26:39 -0400 Subject: [PATCH 32/41] Update version number to 2.9.8 --- lib/Cake/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/VERSION.txt b/lib/Cake/VERSION.txt index 86ce29b56..50d3380f9 100644 --- a/lib/Cake/VERSION.txt +++ b/lib/Cake/VERSION.txt @@ -17,4 +17,4 @@ // @license http://www.opensource.org/licenses/mit-license.php MIT License // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -2.9.7 +2.9.8 From a1eb067c71387de9e8bea4e794ac0b690f58e1fb Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Sun, 23 Apr 2017 18:27:09 +0200 Subject: [PATCH 33/41] bugfix basic to Basic --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index 29c6e8100..8e98fda21 100755 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -89,7 +89,7 @@ class BasicAuthenticate extends BaseAuthenticate { $pass = env('PHP_AUTH_PW'); } else { $httpAuthorization = $request->header('Authorization'); - if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'basic') !== false) { + if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'Basic') !== false) { list($username, $pass) = explode(':', base64_decode(substr($httpAuthorization, 6))); } } From 99d02a8698e8959619b1c5216eeae15dfa9ce205 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Sun, 23 Apr 2017 18:41:45 +0200 Subject: [PATCH 34/41] fix permission --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 lib/Cake/Controller/Component/Auth/BasicAuthenticate.php diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php old mode 100755 new mode 100644 From 09a981ba383170d8a56d97fa1b46937150d4ef22 Mon Sep 17 00:00:00 2001 From: Nicola Beghin Date: Sun, 23 Apr 2017 18:44:42 +0200 Subject: [PATCH 35/41] code style fix as requested --- lib/Cake/Controller/Component/Auth/BasicAuthenticate.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index 8e98fda21..b7daa74f4 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -82,12 +82,9 @@ class BasicAuthenticate extends BaseAuthenticate { * @return mixed Either false or an array of user information */ public function getUser(CakeRequest $request) { - $username = ''; - $pass = ''; - if (isset($_SERVER['PHP_AUTH_USER'])) { - $username = env('PHP_AUTH_USER'); - $pass = env('PHP_AUTH_PW'); - } else { + $username = env('PHP_AUTH_USER'); + $pass = env('PHP_AUTH_PW'); + if (empty($username)) { $httpAuthorization = $request->header('Authorization'); if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'Basic') !== false) { list($username, $pass) = explode(':', base64_decode(substr($httpAuthorization, 6))); From 6321d5612af783b485842a58408a369a0793c899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Sat, 29 Apr 2017 00:49:28 +0200 Subject: [PATCH 36/41] Really correct return type --- app/Controller/PagesController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Controller/PagesController.php b/app/Controller/PagesController.php index e9ba9d9bd..5f8d1c4cc 100644 --- a/app/Controller/PagesController.php +++ b/app/Controller/PagesController.php @@ -40,7 +40,7 @@ class PagesController extends AppController { /** * Displays a view * - * @return \Cake\Network\Response|null + * @return CakeResponse|null * @throws ForbiddenException When a directory traversal attempt. * @throws NotFoundException When the view file could not be found * or MissingViewException in debug mode. From 275385d676c8c59ec2af9db4b6a29b8d1edf7404 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 28 Apr 2017 21:48:31 -0400 Subject: [PATCH 37/41] Add test covering basic auth reading from headers. In some FastCGI setups basic auth values will only be present in the header. Fallback to reading that value if the PHP_AUTH super globals are empty. Refs #9365 --- .../Component/Auth/BasicAuthenticate.php | 4 ++-- .../Component/Auth/BasicAuthenticateTest.php | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index b7daa74f4..86f70c8ca 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -84,9 +84,9 @@ class BasicAuthenticate extends BaseAuthenticate { public function getUser(CakeRequest $request) { $username = env('PHP_AUTH_USER'); $pass = env('PHP_AUTH_PW'); - if (empty($username)) { + if (!strlen($username)) { $httpAuthorization = $request->header('Authorization'); - if ($httpAuthorization !== false && strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'Basic') !== false) { + if (strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'Basic') !== false) { list($username, $pass) = explode(':', base64_decode(substr($httpAuthorization, 6))); } } diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php index df18703c4..af5086caf 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php @@ -15,8 +15,6 @@ * @since CakePHP(tm) v 2.0 * @license http://www.opensource.org/licenses/mit-license.php MIT License */ - -App::uses('AuthComponent', 'Controller/Component'); App::uses('BasicAuthenticate', 'Controller/Component/Auth'); App::uses('AppModel', 'Model'); App::uses('CakeRequest', 'Network'); @@ -197,6 +195,28 @@ class BasicAuthenticateTest extends CakeTestCase { $this->assertEquals($expected, $result); } +/** + * test authenticate success with header values + * + * @return void + */ + public function testAuthenticateSuccessFromHeaders() { + $_SERVER['HTTP_AUTHORIZATION'] = 'Basic ' . base64_encode('mariano:password'); + unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + + $request = new CakeRequest('posts/index', false); + $request->addParams(array('pass' => array(), 'named' => array())); + + $result = $this->auth->authenticate($request, $this->response); + $expected = array( + 'id' => 1, + 'user' => 'mariano', + 'created' => '2007-03-17 01:16:23', + 'updated' => '2007-03-17 01:18:31' + ); + $this->assertEquals($expected, $result); + } + /** * test contain success * From bef0c766b6ae284464c4f7fe560f7c6e327643cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Tue, 16 May 2017 13:24:25 +0200 Subject: [PATCH 38/41] Add inline type hint annotations Improves the experience when debugging in an IDE --- lib/Cake/TestSuite/ControllerTestCase.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Cake/TestSuite/ControllerTestCase.php b/lib/Cake/TestSuite/ControllerTestCase.php index 0036546bd..bd3dcf6ca 100644 --- a/lib/Cake/TestSuite/ControllerTestCase.php +++ b/lib/Cake/TestSuite/ControllerTestCase.php @@ -256,6 +256,7 @@ abstract class ControllerTestCase extends CakeTestCase { } $_SERVER['REQUEST_URI'] = $url; + /** @var CakeRequest|PHPUnit_Framework_MockObject_MockObject $request */ $request = $this->getMock('CakeRequest', array('_readInput')); if (is_string($options['data'])) { @@ -357,9 +358,12 @@ abstract class ControllerTestCase extends CakeTestCase { ), (array)$mocks); list($plugin, $name) = pluginSplit($controller); + /** @var Controller|PHPUnit_Framework_MockObject_MockObject $controllerObj */ $controllerObj = $this->getMock($name . 'Controller', $mocks['methods'], array(), '', false); $controllerObj->name = $name; + /** @var CakeRequest|PHPUnit_Framework_MockObject_MockObject $request */ $request = $this->getMock('CakeRequest'); + /** @var CakeResponse|PHPUnit_Framework_MockObject_MockObject $response */ $response = $this->getMock($this->_responseClass, array('_sendHeader')); $controllerObj->__construct($request, $response); $controllerObj->Components->setController($controllerObj); @@ -393,6 +397,7 @@ abstract class ControllerTestCase extends CakeTestCase { )); } $config = isset($controllerObj->components[$component]) ? $controllerObj->components[$component] : array(); + /** @var Component|PHPUnit_Framework_MockObject_MockObject $componentObj */ $componentObj = $this->getMock($componentClass, $methods, array($controllerObj->Components, $config)); $controllerObj->Components->set($name, $componentObj); $controllerObj->Components->enable($name); From bfd2d21d782a69626bcf1ae2d22aad6e565fb29c Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 25 May 2017 21:15:23 -0400 Subject: [PATCH 39/41] Update version number to 2.9.9 --- lib/Cake/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/VERSION.txt b/lib/Cake/VERSION.txt index 50d3380f9..4717ddebc 100644 --- a/lib/Cake/VERSION.txt +++ b/lib/Cake/VERSION.txt @@ -17,4 +17,4 @@ // @license http://www.opensource.org/licenses/mit-license.php MIT License // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -2.9.8 +2.9.9 From 04e5fdc9b2e000f2343c97416470baac5f406f69 Mon Sep 17 00:00:00 2001 From: Henrik Gemal Date: Fri, 26 May 2017 11:11:10 +0200 Subject: [PATCH 40/41] add polish locale --- 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 c7808fddd..22e4a8606 100644 --- a/lib/Cake/I18n/L10n.php +++ b/lib/Cake/I18n/L10n.php @@ -301,6 +301,7 @@ class L10n { 'nn-no' => array('language' => 'Norwegian Nynorsk (Norway)', 'locale' => 'nn_no', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'), 'no' => array('language' => 'Norwegian', 'locale' => 'nor', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'), 'pl' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'), + 'pl-pl' => array('language' => 'Polish (Polen)', 'locale' => 'pl_pl', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'), 'pt' => array('language' => 'Portuguese (Portugal)', 'locale' => 'por', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'), 'pt-br' => array('language' => 'Portuguese (Brazil)', 'locale' => 'pt_br', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'), 'rm' => array('language' => 'Rhaeto-Romanic', 'locale' => 'roh', 'localeFallback' => 'roh', 'charset' => 'utf-8', 'direction' => 'ltr'), From 3f0fb07122b2bc9b420533b82475ddbb7ce92591 Mon Sep 17 00:00:00 2001 From: Henrik Gemal Date: Fri, 26 May 2017 15:39:06 +0200 Subject: [PATCH 41/41] fix --- 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 22e4a8606..46b63ef40 100644 --- a/lib/Cake/I18n/L10n.php +++ b/lib/Cake/I18n/L10n.php @@ -301,7 +301,7 @@ class L10n { 'nn-no' => array('language' => 'Norwegian Nynorsk (Norway)', 'locale' => 'nn_no', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'), 'no' => array('language' => 'Norwegian', 'locale' => 'nor', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'), 'pl' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'), - 'pl-pl' => array('language' => 'Polish (Polen)', 'locale' => 'pl_pl', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'), + 'pl-pl' => array('language' => 'Polish (Poland)', 'locale' => 'pl_pl', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'), 'pt' => array('language' => 'Portuguese (Portugal)', 'locale' => 'por', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'), 'pt-br' => array('language' => 'Portuguese (Brazil)', 'locale' => 'pt_br', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'), 'rm' => array('language' => 'Rhaeto-Romanic', 'locale' => 'roh', 'localeFallback' => 'roh', 'charset' => 'utf-8', 'direction' => 'ltr'),