diff --git a/.travis.yml b/.travis.yml index 297d3e631..900901156 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ php: - 5.4 - 5.5 - 5.6 + - 7.0 env: - DB=mysql diff --git a/lib/Cake/Cache/Cache.php b/lib/Cake/Cache/Cache.php index 2cba7dadc..a7a01d0a1 100644 --- a/lib/Cake/Cache/Cache.php +++ b/lib/Cake/Cache/Cache.php @@ -275,10 +275,10 @@ class Cache { * * @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default' * @param int $expires [optional] An expires timestamp. Defaults to NULL - * @return void + * @return bool */ public static function gc($config = 'default', $expires = null) { - static::$_engines[$config]->gc($expires); + return static::$_engines[$config]->gc($expires); } /** diff --git a/lib/Cake/Cache/Engine/FileEngine.php b/lib/Cake/Cache/Engine/FileEngine.php index 80f0f2d6b..d650e60ee 100644 --- a/lib/Cake/Cache/Engine/FileEngine.php +++ b/lib/Cake/Cache/Engine/FileEngine.php @@ -109,7 +109,7 @@ class FileEngine extends CacheEngine { * @return bool True if the data was successfully cached, false on failure */ public function write($key, $data, $duration) { - if ($data === '' || !$this->_init) { + if (!$this->_init) { return false; } diff --git a/lib/Cake/Console/ConsoleErrorHandler.php b/lib/Cake/Console/ConsoleErrorHandler.php index a488b10f9..7cbb2df15 100644 --- a/lib/Cake/Console/ConsoleErrorHandler.php +++ b/lib/Cake/Console/ConsoleErrorHandler.php @@ -49,10 +49,10 @@ class ConsoleErrorHandler { /** * Handle an exception in the console environment. Prints a message to stderr. * - * @param Exception $exception The exception to handle + * @param Exception|ParserError $exception The exception to handle * @return void */ - public function handleException(Exception $exception) { + public function handleException($exception) { $stderr = static::getStderr(); $stderr->write(__d('cake_console', "Error: %s\n%s", $exception->getMessage(), diff --git a/lib/Cake/Error/ErrorHandler.php b/lib/Cake/Error/ErrorHandler.php index 3192ed5f8..9da40a660 100644 --- a/lib/Cake/Error/ErrorHandler.php +++ b/lib/Cake/Error/ErrorHandler.php @@ -109,11 +109,11 @@ class ErrorHandler { * This will either use custom exception renderer class if configured, * or use the default ExceptionRenderer. * - * @param Exception $exception The exception to render. + * @param Exception|ParseError $exception The exception to render. * @return void * @see http://php.net/manual/en/function.set-exception-handler.php */ - public static function handleException(Exception $exception) { + public static function handleException($exception) { $config = Configure::read('Exception'); static::_log($exception, $config); @@ -169,11 +169,11 @@ class ErrorHandler { /** * Handles exception logging * - * @param Exception $exception The exception to render. + * @param Exception|ParseError $exception The exception to render. * @param array $config An array of configuration for logging. * @return bool */ - protected static function _log(Exception $exception, $config) { + protected static function _log($exception, $config) { if (empty($config['log'])) { return false; } diff --git a/lib/Cake/Error/ExceptionRenderer.php b/lib/Cake/Error/ExceptionRenderer.php index 04190eba5..a245b64ee 100644 --- a/lib/Cake/Error/ExceptionRenderer.php +++ b/lib/Cake/Error/ExceptionRenderer.php @@ -86,9 +86,9 @@ class ExceptionRenderer { * If the error is a CakeException it will be converted to either a 400 or a 500 * code error depending on the code used to construct the error. * - * @param Exception $exception Exception + * @param Exception|ParseError $exception Exception */ - public function __construct(Exception $exception) { + public function __construct($exception) { $this->controller = $this->_getController($exception); if (method_exists($this->controller, 'appError')) { diff --git a/lib/Cake/Model/Datasource/CakeSession.php b/lib/Cake/Model/Datasource/CakeSession.php index b3b471686..147cc102b 100644 --- a/lib/Cake/Model/Datasource/CakeSession.php +++ b/lib/Cake/Model/Datasource/CakeSession.php @@ -143,7 +143,7 @@ class CakeSession { public static function init($base = null) { static::$time = time(); - if (env('HTTP_USER_AGENT')) { + if (env('HTTP_USER_AGENT') && !static::$_userAgent) { static::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt')); } @@ -202,7 +202,6 @@ class CakeSession { $id = static::id(); static::_startSession(); - if (!$id && static::started()) { static::_checkValid(); } @@ -218,6 +217,9 @@ class CakeSession { * @return bool True if session has been started. */ public static function started() { + if (function_exists('session_status')) { + return isset($_SESSION) && (session_status() === PHP_SESSION_ACTIVE); + } return isset($_SESSION) && session_id(); } @@ -461,7 +463,12 @@ class CakeSession { } if (static::started()) { + if (session_id() && static::_hasSession()) { + session_write_close(); + session_start(); + } session_destroy(); + unset($_COOKIE[static::_cookieName()]); } $_SESSION = null; @@ -584,7 +591,7 @@ class CakeSession { * @return bool */ protected static function _hasSession() { - return static::started() || isset($_COOKIE[static::_cookieName()]); + return static::started() || isset($_COOKIE[session_name()]) || (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg'); } /** @@ -753,7 +760,11 @@ class CakeSession { if (isset($_COOKIE[session_name()])) { setcookie(Configure::read('Session.cookie'), '', time() - 42000, static::$path); } - session_regenerate_id(true); + if (!headers_sent()) { + session_write_close(); + session_start(); + session_regenerate_id(true); + } } /** diff --git a/lib/Cake/Model/Datasource/Session/CacheSession.php b/lib/Cake/Model/Datasource/Session/CacheSession.php index 793701992..35f40d56e 100644 --- a/lib/Cake/Model/Datasource/Session/CacheSession.php +++ b/lib/Cake/Model/Datasource/Session/CacheSession.php @@ -52,7 +52,12 @@ class CacheSession implements CakeSessionHandlerInterface { * @return mixed The value of the key or false if it does not exist */ public function read($id) { - return Cache::read($id, Configure::read('Session.handler.config')); + $data = Cache::read($id, Configure::read('Session.handler.config')); + + if (!is_numeric($data) && empty($data)) { + return ''; + } + return $data; } /** @@ -63,7 +68,7 @@ class CacheSession implements CakeSessionHandlerInterface { * @return bool True for successful write, false otherwise. */ public function write($id, $data) { - return Cache::write($id, $data, Configure::read('Session.handler.config')); + return (bool)Cache::write($id, $data, Configure::read('Session.handler.config')); } /** @@ -73,7 +78,7 @@ class CacheSession implements CakeSessionHandlerInterface { * @return bool True for successful delete, false otherwise. */ public function destroy($id) { - return Cache::delete($id, Configure::read('Session.handler.config')); + return (bool)Cache::delete($id, Configure::read('Session.handler.config')); } /** @@ -83,7 +88,7 @@ class CacheSession implements CakeSessionHandlerInterface { * @return bool Success */ public function gc($expires = null) { - return Cache::gc(Configure::read('Session.handler.config'), $expires); + return (bool)Cache::gc(Configure::read('Session.handler.config'), $expires); } } diff --git a/lib/Cake/Model/Datasource/Session/DatabaseSession.php b/lib/Cake/Model/Datasource/Session/DatabaseSession.php index 81cd708e8..cd4b904a8 100644 --- a/lib/Cake/Model/Datasource/Session/DatabaseSession.php +++ b/lib/Cake/Model/Datasource/Session/DatabaseSession.php @@ -92,11 +92,15 @@ class DatabaseSession implements CakeSessionHandlerInterface { 'conditions' => array($this->_model->alias . '.' . $this->_model->primaryKey => $id) )); - if (empty($row[$this->_model->alias]['data'])) { - return false; + if (empty($row[$this->_model->alias])) { + return ''; } - return $row[$this->_model->alias]['data']; + if (!is_numeric($row[$this->_model->alias]['data']) && empty($row[$this->_model->alias]['data'])) { + return ''; + } + + return (string)$row[$this->_model->alias]['data']; } /** @@ -123,9 +127,9 @@ class DatabaseSession implements CakeSessionHandlerInterface { 'counterCache' => false ); try { - return $this->_model->save($record, $options); + return (bool)$this->_model->save($record, $options); } catch (PDOException $e) { - return $this->_model->save($record, $options); + return (bool)$this->_model->save($record, $options); } } @@ -136,7 +140,7 @@ class DatabaseSession implements CakeSessionHandlerInterface { * @return bool True for successful delete, false otherwise. */ public function destroy($id) { - return $this->_model->delete($id); + return (bool)$this->_model->delete($id); } /** @@ -151,7 +155,8 @@ class DatabaseSession implements CakeSessionHandlerInterface { } else { $expires = time() - $expires; } - return $this->_model->deleteAll(array($this->_model->alias . ".expires <" => $expires), false, false); + $this->_model->deleteAll(array($this->_model->alias . ".expires <" => $expires), false, false); + return true; } } diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php index 80bb5c258..3216cdc3a 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php @@ -48,10 +48,15 @@ class ControllerAuthorizeTest extends CakeTestCase { * testControllerTypeError * * @expectedException PHPUnit_Framework_Error + * @throws PHPUnit_Framework_Error * @return void */ public function testControllerTypeError() { - $this->auth->controller(new StdClass()); + try { + $this->auth->controller(new StdClass()); + } catch (Throwable $t) { + throw new PHPUnit_Framework_Error($t); + } } /** diff --git a/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php b/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php index fa7bae08b..294d46670 100644 --- a/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php @@ -202,7 +202,6 @@ class SessionComponentTest extends CakeTestCase { $this->assertEquals($Session->read('Test'), $array); $Session->delete('Test'); - $this->assertTrue($Session->write(array('Test'), 'some value')); $this->assertTrue($Session->write(array('Test' => 'some value'))); $this->assertEquals('some value', $Session->read('Test')); $Session->delete('Test'); diff --git a/lib/Cake/Test/Case/Core/ConfigureTest.php b/lib/Cake/Test/Case/Core/ConfigureTest.php index 744932dac..6a1b4bbbd 100644 --- a/lib/Cake/Test/Case/Core/ConfigureTest.php +++ b/lib/Cake/Test/Case/Core/ConfigureTest.php @@ -450,11 +450,17 @@ class ConfigureTest extends CakeTestCase { * test reader() throwing exceptions on missing interface. * * @expectedException PHPUnit_Framework_Error + * @throws PHPUnit_Framework_Error * @return void */ public function testReaderExceptionOnIncorrectClass() { $reader = new StdClass(); - Configure::config('test', $reader); + + try { + Configure::config('test', $reader); + } catch (Throwable $t) { + throw new PHPUnit_Framework_Error($t); + } } /** diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index 6ad52f539..aa1353ecf 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -2909,10 +2909,15 @@ SQL; * testDropSchemaNoSchema method * * @expectedException PHPUnit_Framework_Error + * @throws PHPUnit_Framework_Error * @return void */ public function testDropSchemaNoSchema() { - $this->Dbo->dropSchema(null); + try { + $this->Dbo->dropSchema(null); + } catch (Throwable $t) { + throw new PHPUnit_Framework_Error($t); + } } /** diff --git a/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php b/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php index 553f70bf4..387c05fc1 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php @@ -104,6 +104,8 @@ class CacheSessionTest extends CakeTestCase { public function testRead() { $this->storage->write('test_one', 'Some other value'); $this->assertEquals('Some other value', $this->storage->read('test_one'), 'Incorrect value.'); + $this->storage->write('test_two', 0); + $this->assertEquals(0, $this->storage->read('test_two')); } /** diff --git a/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php b/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php index da19cfcc6..fb5b0bfef 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php @@ -122,19 +122,8 @@ class DatabaseSessionTest extends CakeTestCase { * @return void */ public function testWrite() { - $result = $this->storage->write('foo', 'Some value'); - $expected = array( - 'Session' => array( - 'id' => 'foo', - 'data' => 'Some value', - ) - ); - $expires = $result['Session']['expires']; - unset($result['Session']['expires']); - $this->assertEquals($expected, $result); - - $expected = time() + (Configure::read('Session.timeout') * 60); - $this->assertWithinMargin($expires, $expected, 1); + $this->storage->write('foo', 'Some value'); + $this->assertEquals($this->storage->read('foo'), 'Some value'); } /** @@ -154,13 +143,10 @@ class DatabaseSessionTest extends CakeTestCase { */ public function testRead() { $this->storage->write('foo', 'Some value'); - - $result = $this->storage->read('foo'); - $expected = 'Some value'; - $this->assertEquals($expected, $result); - - $result = $this->storage->read('made up value'); - $this->assertFalse($result); + $this->assertEquals($this->storage->read('foo'), 'Some value'); + $this->storage->write('bar', 0); + $this->assertEquals(0, $this->storage->read('bar')); + $this->assertSame('', $this->storage->read('made up value')); } /** @@ -172,7 +158,7 @@ class DatabaseSessionTest extends CakeTestCase { $this->storage->write('foo', 'Some value'); $this->assertTrue($this->storage->destroy('foo'), 'Destroy failed'); - $this->assertFalse($this->storage->read('foo'), 'Value still present.'); + $this->assertSame($this->storage->read('foo'), ''); } /** @@ -189,7 +175,7 @@ class DatabaseSessionTest extends CakeTestCase { sleep(1); $storage->gc(); - $this->assertFalse($storage->read('foo')); + $this->assertSame($storage->read('foo'), ''); } /** diff --git a/lib/Cake/Test/Case/Model/ModelValidationTest.php b/lib/Cake/Test/Case/Model/ModelValidationTest.php index bd65b16e9..1636f7a21 100644 --- a/lib/Cake/Test/Case/Model/ModelValidationTest.php +++ b/lib/Cake/Test/Case/Model/ModelValidationTest.php @@ -2224,10 +2224,15 @@ class ModelValidationTest extends BaseModelTest { * Test that type hint exception is thrown * * @expectedException PHPUnit_Framework_Error + * @throws PHPUnit_Framework_Error * @return void */ public function testValidatorTypehintException() { - new ModelValidator('asdasds'); + try { + new ModelValidator('asdasds'); + } catch (Throwable $t) { + throw new PHPUnit_Framework_Error($t); + } } /** diff --git a/lib/Cake/Test/Case/View/JsonViewTest.php b/lib/Cake/Test/Case/View/JsonViewTest.php index aa5027ae1..d90596f47 100644 --- a/lib/Cake/Test/Case/View/JsonViewTest.php +++ b/lib/Cake/Test/Case/View/JsonViewTest.php @@ -362,7 +362,9 @@ class JsonViewTest extends CakeTestCase { $Controller = new Controller($Request, $Response); // non utf-8 stuff - $data = array('data' => array('foo' => 'bar' . chr('0x97'))); + $bar = 'bar'; + $bar .= chr(0x97); + $data = array('data' => array('foo' => $bar)); $Controller->set($data); $Controller->set('_serialize', 'data'); diff --git a/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php b/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php index 2ba874dba..d4ac56fd8 100644 --- a/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php +++ b/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php @@ -12,18 +12,23 @@ class TestAppLibSession implements CakeSessionHandlerInterface { } public function close() { + return true; } public function read($id) { + return ''; } public function write($id, $data) { + return true; } public function destroy($id) { + return true; } public function gc($expires = null) { + return true; } } diff --git a/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php b/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php index acad188e0..b297fb47f 100644 --- a/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php +++ b/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php @@ -12,18 +12,23 @@ class TestPluginSession implements CakeSessionHandlerInterface { } public function close() { + return true; } public function read($id) { + return ''; } public function write($id, $data) { + return true; } public function destroy($id) { + return true; } public function gc($expires = null) { + return true; } } diff --git a/lib/Cake/Utility/Security.php b/lib/Cake/Utility/Security.php index 6ad3c01c1..511cf5efc 100644 --- a/lib/Cake/Utility/Security.php +++ b/lib/Cake/Utility/Security.php @@ -187,7 +187,7 @@ class Security { return ''; } - srand(Configure::read('Security.cipherSeed')); + srand((int)Configure::read('Security.cipherSeed')); $out = ''; $keyLength = strlen($key); for ($i = 0, $textLength = strlen($text); $i < $textLength; $i++) {