summaryrefslogtreecommitdiffstats
path: root/system/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'system/libraries')
-rw-r--r--system/libraries/Cache/drivers/Cache_apc.php8
-rw-r--r--system/libraries/Cache/drivers/Cache_apcu.php8
-rw-r--r--system/libraries/Cache/drivers/Cache_dummy.php8
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php48
-rw-r--r--system/libraries/Cache/drivers/Cache_wincache.php8
-rw-r--r--system/libraries/Cache/drivers/index.html2
-rw-r--r--system/libraries/Cache/index.html2
-rw-r--r--system/libraries/Calendar.php2
-rw-r--r--system/libraries/Email.php4
-rw-r--r--system/libraries/Encrypt.php4
-rw-r--r--system/libraries/Encryption.php14
-rw-r--r--system/libraries/Form_validation.php11
-rw-r--r--system/libraries/Ftp.php4
-rw-r--r--system/libraries/Image_lib.php29
-rw-r--r--system/libraries/Migration.php2
-rw-r--r--system/libraries/Pagination.php2
-rw-r--r--system/libraries/Parser.php2
-rw-r--r--system/libraries/Profiler.php20
-rw-r--r--system/libraries/Session/CI_Session_driver_interface.php58
-rw-r--r--system/libraries/Session/OldSessionWrapper.php88
-rw-r--r--system/libraries/Session/PHP8SessionWrapper.php90
-rw-r--r--system/libraries/Session/Session.php115
-rw-r--r--system/libraries/Session/Session_driver.php52
-rw-r--r--system/libraries/Session/drivers/Session_database_driver.php92
-rw-r--r--system/libraries/Session/drivers/Session_files_driver.php19
-rw-r--r--system/libraries/Session/drivers/Session_memcached_driver.php27
-rw-r--r--system/libraries/Session/drivers/Session_redis_driver.php101
-rw-r--r--system/libraries/Session/drivers/index.html2
-rw-r--r--system/libraries/Session/index.html2
-rw-r--r--system/libraries/Table.php2
-rw-r--r--system/libraries/Trackback.php2
-rw-r--r--system/libraries/Typography.php2
-rw-r--r--system/libraries/Unit_test.php2
-rw-r--r--system/libraries/Upload.php8
-rw-r--r--system/libraries/User_agent.php4
-rw-r--r--system/libraries/Xmlrpc.php12
-rw-r--r--system/libraries/Xmlrpcs.php4
-rw-r--r--system/libraries/Zip.php9
-rw-r--r--system/libraries/index.html2
39 files changed, 644 insertions, 227 deletions
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
index 8da8854ee..c0527e665 100644
--- a/system/libraries/Cache/drivers/Cache_apc.php
+++ b/system/libraries/Cache/drivers/Cache_apc.php
@@ -160,10 +160,10 @@ class CI_Cache_apc extends CI_Driver {
* @param string user/filehits
* @return mixed array on success, false on failure
*/
- public function cache_info($type = NULL)
- {
- return apc_cache_info($type);
- }
+ public function cache_info($type = NULL)
+ {
+ return apc_cache_info($type);
+ }
// ------------------------------------------------------------------------
diff --git a/system/libraries/Cache/drivers/Cache_apcu.php b/system/libraries/Cache/drivers/Cache_apcu.php
index 0d84f8ee3..01f80e79b 100644
--- a/system/libraries/Cache/drivers/Cache_apcu.php
+++ b/system/libraries/Cache/drivers/Cache_apcu.php
@@ -171,10 +171,10 @@ class CI_Cache_apcu extends CI_Driver {
*
* @return mixed array on success, false on failure
*/
- public function cache_info()
- {
- return apcu_cache_info();
- }
+ public function cache_info()
+ {
+ return apcu_cache_info();
+ }
// ------------------------------------------------------------------------
diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php
index fdb9042ef..0a90d0692 100644
--- a/system/libraries/Cache/drivers/Cache_dummy.php
+++ b/system/libraries/Cache/drivers/Cache_dummy.php
@@ -138,10 +138,10 @@ class CI_Cache_dummy extends CI_Driver {
* @param string user/filehits
* @return bool FALSE
*/
- public function cache_info($type = NULL)
- {
- return FALSE;
- }
+ public function cache_info($type = NULL)
+ {
+ return FALSE;
+ }
// ------------------------------------------------------------------------
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
index 3bc3ccd6c..9b082d11b 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -69,6 +69,21 @@ class CI_Cache_redis extends CI_Driver
*/
protected $_redis;
+
+ /**
+ * del()/delete() method name depending on phpRedis version
+ *
+ * @var string
+ */
+ protected static $_delete_name;
+
+ /**
+ * sRem()/sRemove() method name depending on phpRedis version
+ *
+ * @var string
+ */
+ protected static $_sRemove_name;
+
// ------------------------------------------------------------------------
/**
@@ -90,6 +105,20 @@ class CI_Cache_redis extends CI_Driver
return;
}
+ if ( ! isset(static::$_delete_name, static::$_sRemove_name))
+ {
+ if (version_compare(phpversion('redis'), '5', '>='))
+ {
+ static::$_delete_name = 'del';
+ static::$_sRemove_name = 'sRem';
+ }
+ else
+ {
+ static::$_delete_name = 'delete';
+ static::$_sRemove_name = 'sRemove';
+ }
+ }
+
$CI =& get_instance();
if ($CI->config->load('redis', TRUE, TRUE))
@@ -138,7 +167,7 @@ class CI_Cache_redis extends CI_Driver
{
$data = $this->_redis->hMGet($key, array('__ci_type', '__ci_value'));
- if ( ! isset($data['__ci_type'], $data['__ci_value']) OR $data['__ci_value'] === FALSE)
+ if ($value !== FALSE && $this->_redis->sIsMember('_ci_redis_serialized', $key))
{
return FALSE;
}
@@ -196,9 +225,9 @@ class CI_Cache_redis extends CI_Driver
{
return FALSE;
}
- elseif ($ttl)
+ else
{
- $this->_redis->expireAt($id, time() + $ttl);
+ $this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $id);
}
return TRUE;
@@ -214,7 +243,14 @@ class CI_Cache_redis extends CI_Driver
*/
public function delete($key)
{
- return ($this->_redis->delete($key) === 1);
+ if ($this->_redis->{static::$_delete_name}($key) !== 1)
+ {
+ return FALSE;
+ }
+
+ $this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $key);
+
+ return TRUE;
}
// ------------------------------------------------------------------------
@@ -228,7 +264,7 @@ class CI_Cache_redis extends CI_Driver
*/
public function increment($id, $offset = 1)
{
- return $this->_redis->hIncrBy($id, 'data', $offset);
+ return $this->_redis->incrBy($id, $offset);
}
// ------------------------------------------------------------------------
@@ -242,7 +278,7 @@ class CI_Cache_redis extends CI_Driver
*/
public function decrement($id, $offset = 1)
{
- return $this->_redis->hIncrBy($id, 'data', -$offset);
+ return $this->_redis->decrBy($id, $offset);
}
// ------------------------------------------------------------------------
diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php
index e19c6ca99..703fece7a 100644
--- a/system/libraries/Cache/drivers/Cache_wincache.php
+++ b/system/libraries/Cache/drivers/Cache_wincache.php
@@ -169,10 +169,10 @@ class CI_Cache_wincache extends CI_Driver {
*
* @return mixed array on success, false on failure
*/
- public function cache_info()
- {
- return wincache_ucache_info(TRUE);
- }
+ public function cache_info()
+ {
+ return wincache_ucache_info(TRUE);
+ }
// ------------------------------------------------------------------------
diff --git a/system/libraries/Cache/drivers/index.html b/system/libraries/Cache/drivers/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Cache/drivers/index.html
+++ b/system/libraries/Cache/drivers/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Cache/index.html b/system/libraries/Cache/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Cache/index.html
+++ b/system/libraries/Cache/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index a6bdae50a..fcfcf62ca 100644
--- a/system/libraries/Calendar.php
+++ b/system/libraries/Calendar.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/calendar.html
+ * @link https://codeigniter.com/userguide3/libraries/calendar.html
*/
class CI_Calendar {
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 1912e0442..b01e44a63 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/email.html
+ * @link https://codeigniter.com/userguide3/libraries/email.html
*/
class CI_Email {
@@ -389,7 +389,7 @@ class CI_Email {
$this->charset = config_item('charset');
$this->initialize($config);
- isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
+ isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload'));
log_message('info', 'Email Class Initialized');
}
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 7ed185f1b..df1af4cf4 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/encryption.html
+ * @link https://codeigniter.com/userguide3/libraries/encryption.html
*/
class CI_Encrypt {
@@ -198,7 +198,7 @@ class CI_Encrypt {
* This allows for backwards compatibility and a method to transition to the
* new encryption algorithms.
*
- * For more details, see https://codeigniter.com/user_guide/installation/upgrade_200.html#encryption
+ * For more details, see https://codeigniter.com/userguide3/installation/upgrade_200.html#encryption
*
* @param string
* @param int (mcrypt mode constant)
diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php
index fd858cb29..7d648dfa3 100644
--- a/system/libraries/Encryption.php
+++ b/system/libraries/Encryption.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Libraries
* @author Andrey Andreev
- * @link https://codeigniter.com/user_guide/libraries/encryption.html
+ * @link https://codeigniter.com/userguide3/libraries/encryption.html
*/
class CI_Encryption {
@@ -161,7 +161,7 @@ class CI_Encryption {
show_error('Encryption: Unable to find an available encryption driver.');
}
- isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
+ isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload'));
$this->initialize($params);
if ( ! isset($this->_key) && self::strlen($key = config_item('encryption_key')) > 0)
@@ -476,7 +476,7 @@ class CI_Encryption {
$iv = ($iv_size = openssl_cipher_iv_length($params['handle']))
? $this->create_key($iv_size)
- : NULL;
+ : '';
$data = openssl_encrypt(
$data,
@@ -585,7 +585,7 @@ class CI_Encryption {
}
else
{
- $iv = NULL;
+ $iv = '';
}
if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0)
@@ -632,7 +632,7 @@ class CI_Encryption {
}
else
{
- $iv = NULL;
+ $iv = '';
}
return empty($params['handle'])
@@ -910,8 +910,8 @@ class CI_Encryption {
protected static function strlen($str)
{
return (self::$func_overload)
- ? mb_strlen($str, '8bit')
- : strlen($str);
+ ? mb_strlen((string) $str, '8bit')
+ : strlen((string) $str);
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index e38c44277..043a97c6d 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Validation
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/form_validation.html
+ * @link https://codeigniter.com/userguide3/libraries/form_validation.html
*/
class CI_Form_validation {
@@ -1062,7 +1062,7 @@ class CI_Form_validation {
{
return is_array($str)
? (empty($str) === FALSE)
- : (trim($str) !== '');
+ : (trim((string) $str) !== '');
}
// --------------------------------------------------------------------
@@ -1214,6 +1214,13 @@ class CI_Form_validation {
$str = $matches[2];
}
+ // Apparently, FILTER_VALIDATE_URL doesn't reject digit-only names for some reason ...
+ // See https://github.com/bcit-ci/CodeIgniter/issues/5755
+ if (ctype_digit($str))
+ {
+ return FALSE;
+ }
+
// PHP 7 accepts IPv6 addresses within square brackets as hostnames,
// but it appears that the PR that came in with https://bugs.php.net/bug.php?id=68039
// was never merged into a PHP 5 branch ... https://3v4l.org/8PsSN
diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php
index 4f0f5dfb3..92644153a 100644
--- a/system/libraries/Ftp.php
+++ b/system/libraries/Ftp.php
@@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/ftp.html
+ * @link https://codeigniter.com/userguide3/libraries/ftp.html
*/
class CI_FTP {
@@ -202,7 +202,7 @@ class CI_FTP {
*/
protected function _is_conn()
{
- if ( ! is_resource($this->conn_id))
+ if ($this->conn_id !== FALSE)
{
if ($this->debug === TRUE)
{
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 9cd0d1dfa..6aeee1790 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Image_lib
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/image_lib.html
+ * @link https://codeigniter.com/userguide3/libraries/image_lib.html
*/
class CI_Image_lib {
@@ -946,6 +946,10 @@ class CI_Image_lib {
$cmd_in = 'pngtopnm';
$cmd_out = 'ppmtopng';
break;
+ case 18 :
+ $cmd_in = 'webptopnm';
+ $cmd_out = 'ppmtowebp';
+ break;
}
if ($action === 'crop')
@@ -1472,6 +1476,14 @@ class CI_Image_lib {
}
return imagecreatefrompng($path);
+ case 18:
+ if ( ! function_exists('imagecreatefromwebp'))
+ {
+ $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_webp_not_supported'));
+ return FALSE;
+ }
+
+ return imagecreatefromwebp($path);
default:
$this->set_error(array('imglib_unsupported_imagecreate'));
return FALSE;
@@ -1532,6 +1544,19 @@ class CI_Image_lib {
return FALSE;
}
break;
+ case 18:
+ if ( ! function_exists('imagewebp'))
+ {
+ $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_webp_not_supported'));
+ return FALSE;
+ }
+
+ if ( ! @imagewebp($resource, $this->full_dst_path))
+ {
+ $this->set_error('imglib_save_failed');
+ return FALSE;
+ }
+ break;
default:
$this->set_error(array('imglib_unsupported_imagecreate'));
return FALSE;
@@ -1573,6 +1598,8 @@ class CI_Image_lib {
break;
case 3 : imagepng($resource);
break;
+ case 18 : imagewebp($resource);
+ break;
default: echo 'Unable to display the image';
break;
}
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index 1b7808923..915d4e453 100644
--- a/system/libraries/Migration.php
+++ b/system/libraries/Migration.php
@@ -288,7 +288,7 @@ class CI_Migration {
$this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class);
return FALSE;
}
- elseif ( ! is_callable(array($class, $method)))
+ elseif ( ! method_exists($class, $method) OR ! (new ReflectionMethod($class, $method))->isPublic())
{
$this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class);
return FALSE;
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 11d63fe50..20418c00a 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Pagination
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/pagination.html
+ * @link https://codeigniter.com/userguide3/libraries/pagination.html
*/
class CI_Pagination {
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index d3c6500ae..04476f1a2 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Parser
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/parser.html
+ * @link https://codeigniter.com/userguide3/libraries/parser.html
*/
class CI_Parser {
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 77af7b99b..5531f3366 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/general/profiling.html
+ * @link https://codeigniter.com/userguide3/general/profiling.html
*/
class CI_Profiler {
@@ -105,7 +105,7 @@ class CI_Profiler {
{
if ( ! isset($config[$section]))
{
- $this->_compile_{$section} = TRUE;
+ $this->{'_compile_'.$section} = TRUE;
}
}
@@ -135,7 +135,7 @@ class CI_Profiler {
{
if (in_array($method, $this->_available_sections))
{
- $this->_compile_{$method} = ($enable !== FALSE);
+ $this->{'_compile_'.$method} = ($enable !== FALSE);
}
}
}
@@ -486,13 +486,13 @@ class CI_Profiler {
{
$pre = '';
$pre_close = '';
-
+
if (is_array($val) OR is_object($val))
{
$val = print_r($val, TRUE);
-
+
$pre = '<pre>' ;
- $pre_close = '</pre>';
+ $pre_close = '</pre>';
}
$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
@@ -524,13 +524,13 @@ class CI_Profiler {
{
$pre = '';
$pre_close = '';
-
+
if (is_array($val) OR is_object($val))
{
$val = print_r($val, TRUE);
-
+
$pre = '<pre>' ;
- $pre_close = '</pre>';
+ $pre_close = '</pre>';
}
$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
@@ -554,7 +554,7 @@ class CI_Profiler {
foreach ($this->_available_sections as $section)
{
- if ($this->_compile_{$section} !== FALSE)
+ if ($this->{'_compile_'.$section} !== FALSE)
{
$func = '_compile_'.$section;
$output .= $this->{$func}();
diff --git a/system/libraries/Session/CI_Session_driver_interface.php b/system/libraries/Session/CI_Session_driver_interface.php
new file mode 100644
index 000000000..a854e92af
--- /dev/null
+++ b/system/libraries/Session/CI_Session_driver_interface.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP
+ *
+ * This content is released under the MIT License (MIT)
+ *
+ * Copyright (c) 2022, CodeIgniter Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @package CodeIgniter
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2022, CodeIgniter Foundation (https://codeigniter.com/)
+ * @license http://opensource.org/licenses/MIT MIT License
+ * @link https://codeigniter.com
+ * @since Version 3.0.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * CI_Session_driver_interface
+ *
+ * A compatibility typeless SessionHandlerInterface alias
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Sessions
+ * @author Andrey Andreev
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
+ */
+interface CI_Session_driver_interface {
+
+ public function open($save_path, $name);
+ public function close();
+ public function read($session_id);
+ public function write($session_id, $session_data);
+ public function destroy($session_id);
+ public function gc($maxlifetime);
+}
diff --git a/system/libraries/Session/OldSessionWrapper.php b/system/libraries/Session/OldSessionWrapper.php
new file mode 100644
index 000000000..5934b5218
--- /dev/null
+++ b/system/libraries/Session/OldSessionWrapper.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP
+ *
+ * This content is released under the MIT License (MIT)
+ *
+ * Copyright (c) 2022, CodeIgniter Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @package CodeIgniter
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2022, CodeIgniter Foundation (https://codeigniter.com/)
+ * @license http://opensource.org/licenses/MIT MIT License
+ * @link https://codeigniter.com
+ * @since Version 3.0.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * OldSessionWrapper
+ *
+ * PHP 8 Session handler compatibility wrapper, pre-PHP8 version
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Sessions
+ * @author Andrey Andreev
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
+ */
+class CI_SessionWrapper implements SessionHandlerInterface {
+
+ protected CI_Session_driver_interface $driver;
+
+ public function __construct(CI_Session_driver_interface $driver)
+ {
+ $this->driver = $driver;
+ }
+
+ public function open($save_path, $name)
+ {
+ return $this->driver->open($save_path, $name);
+ }
+
+ public function close()
+ {
+ return $this->driver->close();
+ }
+
+ public function read($id)
+ {
+ return $this->driver->read($id);
+ }
+
+ public function write($id, $data)
+ {
+ return $this->driver->write($id, $data);
+ }
+
+ public function destroy($id)
+ {
+ return $this->driver->destroy($id);
+ }
+
+ public function gc($maxlifetime)
+ {
+ return $this->driver->gc($maxlifetime);
+ }
+}
diff --git a/system/libraries/Session/PHP8SessionWrapper.php b/system/libraries/Session/PHP8SessionWrapper.php
new file mode 100644
index 000000000..c6dfaf7e0
--- /dev/null
+++ b/system/libraries/Session/PHP8SessionWrapper.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP
+ *
+ * This content is released under the MIT License (MIT)
+ *
+ * Copyright (c) 2022, CodeIgniter Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @package CodeIgniter
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2022, CodeIgniter Foundation (https://codeigniter.com/)
+ * @license http://opensource.org/licenses/MIT MIT License
+ * @link https://codeigniter.com
+ * @since Version 3.0.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * PHP8SessionWrapper
+ *
+ * PHP 8 Session handler compatibility wrapper
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Sessions
+ * @author Andrey Andreev
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
+ */
+class CI_SessionWrapper implements SessionHandlerInterface {
+
+ protected CI_Session_driver_interface $driver;
+
+ public function __construct(CI_Session_driver_interface $driver)
+ {
+ $this->driver = $driver;
+ }
+
+ public function open(string $save_path, string $name): bool
+ {
+ return $this->driver->open($save_path, $name);
+ }
+
+ public function close(): bool
+ {
+ return $this->driver->close();
+ }
+
+ #[\ReturnTypeWillChange]
+ public function read(string $id): mixed
+ {
+ return $this->driver->read($id);
+ }
+
+ public function write(string $id, string $data): bool
+ {
+ return $this->driver->write($id, $data);
+ }
+
+ public function destroy(string $id): bool
+ {
+ return $this->driver->destroy($id);
+ }
+
+ #[\ReturnTypeWillChange]
+ public function gc(int $maxlifetime): mixed
+ {
+ return $this->driver->gc($maxlifetime);
+ }
+}
diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php
index dfd0f432e..f370f7f19 100644
--- a/system/libraries/Session/Session.php
+++ b/system/libraries/Session/Session.php
@@ -6,7 +6,7 @@
*
* This content is released under the MIT License (MIT)
*
- * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
+ * Copyright (c) 2019 - 2022, CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
+ * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 2.0.0
@@ -44,7 +45,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Sessions
* @author Andrey Andreev
- * @link https://codeigniter.com/user_guide/libraries/sessions.html
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
*/
class CI_Session {
@@ -102,15 +103,24 @@ class CI_Session {
$this->_configure($params);
$this->_config['_sid_regexp'] = $this->_sid_regexp;
- $class = new $class($this->_config);
- if ($class instanceof SessionHandlerInterface)
+ $class = new $class($this->_config);
+ $wrapper = new CI_SessionWrapper($class);
+ if (is_php('5.4'))
{
session_set_save_handler($class, TRUE);
}
else
{
- log_message('error', "Session: Driver '".$this->_driver."' doesn't implement SessionHandlerInterface. Aborting.");
- return;
+ session_set_save_handler(
+ array($class, 'open'),
+ array($class, 'close'),
+ array($class, 'read'),
+ array($class, 'write'),
+ array($class, 'destroy'),
+ array($class, 'gc')
+ );
+
+ register_shutdown_function('session_write_close');
}
// Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers
@@ -144,15 +154,36 @@ class CI_Session {
// unless it is being currently created or regenerated
elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id())
{
- setcookie(
- $this->_config['cookie_name'],
- session_id(),
- (empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']),
- $this->_config['cookie_path'],
- $this->_config['cookie_domain'],
- $this->_config['cookie_secure'],
- TRUE
- );
+ $expires = empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime'];
+ if (is_php('7.3'))
+ {
+ setcookie(
+ $this->_config['cookie_name'],
+ session_id(),
+ array(
+ 'expires' => $expires,
+ 'path' => $this->_config['cookie_path'],
+ 'domain' => $this->_config['cookie_domain'],
+ 'secure' => $this->_config['cookie_secure'],
+ 'httponly' => TRUE,
+ 'samesite' => $this->_config['cookie_samesite']
+ )
+ );
+ }
+ else
+ {
+ $header = 'Set-Cookie: '.$this->_config['cookie_name'].'='.session_id();
+ $header .= empty($expires) ? '' : '; Expires='.gmdate('D, d-M-Y H:i:s T', $expires).'; Max-Age='.$this->_config['cookie_lifetime'];
+ $header .= '; Path='.$this->_config['cookie_path'];
+ $header .= ($this->_config['cookie_domain'] !== '' ? '; Domain='.$this->_config['cookie_domain'] : '');
+ $header .= ($this->_config['cookie_secure'] ? '; Secure' : '').'; HttpOnly; SameSite='.$this->_config['cookie_samesite'];
+ header($header);
+ }
+
+ if ( ! $this->_config['cookie_secure'] && $this->_config['cookie_samesite'] === 'None')
+ {
+ log_message('error', 'Session:', $this->_config['cookie_name'].' cookie sent with SameSite=None, but without Secure attribute.');
+ }
}
$this->_ci_init_vars();
@@ -174,6 +205,10 @@ class CI_Session {
*/
protected function _ci_load_classes($driver)
{
+ require_once(BASEPATH.'libraries/Session/CI_Session_driver_interface.php');
+ $wrapper = is_php('8.0') ? 'PHP8SessionWrapper' : 'OldSessionWrapper';
+ require_once(BASEPATH.'libraries/Session/'.$wrapper.'.php');
+
$prefix = config_item('subclass_prefix');
if ( ! class_exists('CI_Session_driver', FALSE))
@@ -267,13 +302,43 @@ class CI_Session {
isset($params['cookie_domain']) OR $params['cookie_domain'] = config_item('cookie_domain');
isset($params['cookie_secure']) OR $params['cookie_secure'] = (bool) config_item('cookie_secure');
- session_set_cookie_params(
- $params['cookie_lifetime'],
- $params['cookie_path'],
- $params['cookie_domain'],
- $params['cookie_secure'],
- TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons
- );
+ isset($params['cookie_samesite']) OR $params['cookie_samesite'] = config_item('sess_samesite');
+ if ( ! isset($params['cookie_samesite']) && is_php('7.3'))
+ {
+ $params['cookie_samesite'] = ini_get('session.cookie_samesite');
+ }
+
+ if (isset($params['cookie_samesite']))
+ {
+ $params['cookie_samesite'] = ucfirst(strtolower($params['cookie_samesite']));
+ in_array($params['cookie_samesite'], array('Lax', 'Strict', 'None'), TRUE) OR $params['cookie_samesite'] = 'Lax';
+ }
+ else
+ {
+ $params['cookie_samesite'] = 'Lax';
+ }
+
+ if (is_php('7.3'))
+ {
+ session_set_cookie_params(array(
+ 'lifetime' => $params['cookie_lifetime'],
+ 'path' => $params['cookie_path'],
+ 'domain' => $params['cookie_domain'],
+ 'secure' => $params['cookie_secure'],
+ 'httponly' => $params['cookie_httponly'],
+ 'samesite' => $params['cookie_samesite']
+ ));
+ }
+ else
+ {
+ session_set_cookie_params(
+ $params['cookie_lifetime'],
+ $params['cookie_path'],
+ $params['cookie_domain'],
+ $params['cookie_secure'],
+ TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons
+ );
+ }
if (empty($expiration))
{
@@ -396,9 +461,7 @@ class CI_Session {
{
$_SESSION['__ci_vars'][$key] = 'old';
}
- // Hacky, but 'old' will (implicitly) always be less than time() ;)
- // DO NOT move this above the 'new' check!
- elseif ($value < $current_time)
+ elseif ($value === 'old' || $value < $current_time)
{
unset($_SESSION[$key], $_SESSION['__ci_vars'][$key]);
}
@@ -706,7 +769,7 @@ class CI_Session {
*
* Legacy CI_Session compatibility method
*
- * @returns array
+ * @return array
*/
public function &get_userdata()
{
diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php
index 14ebdb09f..b1b1b073e 100644
--- a/system/libraries/Session/Session_driver.php
+++ b/system/libraries/Session/Session_driver.php
@@ -6,7 +6,7 @@
*
* This content is released under the MIT License (MIT)
*
- * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
+ * Copyright (c) 2019 - 2022, CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
+ * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
@@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Sessions
* @author Andrey Andreev
- * @link https://codeigniter.com/user_guide/libraries/sessions.html
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
*/
-abstract class CI_Session_driver implements SessionHandlerInterface {
+abstract class CI_Session_driver {
protected $_config;
@@ -139,14 +140,28 @@ abstract class CI_Session_driver implements SessionHandlerInterface {
*/
protected function _cookie_destroy()
{
+ if ( ! is_php('7.3'))
+ {
+ $header = 'Set-Cookie: '.$this->_config['cookie_name'].'=';
+ $header .= '; Expires='.gmdate('D, d-M-Y H:i:s T', 1).'; Max-Age=-1';
+ $header .= '; Path='.$this->_config['cookie_path'];
+ $header .= ($this->_config['cookie_domain'] !== '' ? '; Domain='.$this->_config['cookie_domain'] : '');
+ $header .= ($this->_config['cookie_secure'] ? '; Secure' : '').'; HttpOnly; SameSite='.$this->_config['cookie_samesite'];
+ header($header);
+ return;
+ }
+
return setcookie(
$this->_config['cookie_name'],
NULL,
- 1,
- $this->_config['cookie_path'],
- $this->_config['cookie_domain'],
- $this->_config['cookie_secure'],
- TRUE
+ array(
+ 'expires' => 1,
+ 'path' => $this->_config['cookie_path'],
+ 'domain' => $this->_config['cookie_domain'],
+ 'secure' => $this->_config['cookie_secure'],
+ 'httponly' => TRUE,
+ 'samesite' => $this->_config['cookie_samesite']
+ )
);
}
@@ -184,25 +199,4 @@ abstract class CI_Session_driver implements SessionHandlerInterface {
return TRUE;
}
-
- // ------------------------------------------------------------------------
-
- /**
- * Fail
- *
- * Drivers other than the 'files' one don't (need to) use the
- * session.save_path INI setting, but that leads to confusing
- * error messages emitted by PHP when open() or write() fail,
- * as the message contains session.save_path ...
- * To work around the problem, the drivers will call this method
- * so that the INI is set just in time for the error message to
- * be properly generated.
- *
- * @return mixed
- */
- protected function _fail()
- {
- ini_set('session.save_path', config_item('sess_save_path'));
- return $this->_failure;
- }
}
diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php
index 734fe624f..2f788a1a1 100644
--- a/system/libraries/Session/drivers/Session_database_driver.php
+++ b/system/libraries/Session/drivers/Session_database_driver.php
@@ -6,7 +6,7 @@
*
* This content is released under the MIT License (MIT)
*
- * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
+ * Copyright (c) 2019 - 2022, CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
+ * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
@@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Sessions
* @author Andrey Andreev
- * @link https://codeigniter.com/user_guide/libraries/sessions.html
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
*/
-class CI_Session_database_driver extends CI_Session_driver implements SessionHandlerInterface {
+class CI_Session_database_driver extends CI_Session_driver implements CI_Session_driver_interface {
/**
* DB object
@@ -130,7 +131,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
{
if (empty($this->_db->conn_id) && ! $this->_db->db_connect())
{
- return $this->_fail();
+ return $this->_failure;
}
$this->php5_validate_id();
@@ -150,48 +151,47 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
*/
public function read($session_id)
{
- if ($this->_get_lock($session_id) !== FALSE)
+ if ($this->_get_lock($session_id) === FALSE)
{
- // Prevent previous QB calls from messing with our queries
- $this->_db->reset_query();
-
- // Needed by write() to detect session_regenerate_id() calls
- $this->_session_id = $session_id;
+ return $this->_failure;
+ }
- $this->_db
- ->select('data')
- ->from($this->_config['save_path'])
- ->where('id', $session_id);
+ // Prevent previous QB calls from messing with our queries
+ $this->_db->reset_query();
- if ($this->_config['match_ip'])
- {
- $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']);
- }
+ // Needed by write() to detect session_regenerate_id() calls
+ $this->_session_id = $session_id;
- if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL)
- {
- // PHP7 will reuse the same SessionHandler object after
- // ID regeneration, so we need to explicitly set this to
- // FALSE instead of relying on the default ...
- $this->_row_exists = FALSE;
- $this->_fingerprint = md5('');
- return '';
- }
+ $this->_db
+ ->select('data')
+ ->from($this->_config['save_path'])
+ ->where('id', $session_id);
- // PostgreSQL's variant of a BLOB datatype is Bytea, which is a
- // PITA to work with, so we use base64-encoded data in a TEXT
- // field instead.
- $result = ($this->_platform === 'postgre')
- ? base64_decode(rtrim($result->data))
- : $result->data;
+ if ($this->_config['match_ip'])
+ {
+ $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']);
+ }
- $this->_fingerprint = md5($result);
- $this->_row_exists = TRUE;
- return $result;
+ if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL)
+ {
+ // PHP7 will reuse the same SessionHandler object after
+ // ID regeneration, so we need to explicitly set this to
+ // FALSE instead of relying on the default ...
+ $this->_row_exists = FALSE;
+ $this->_fingerprint = md5('');
+ return '';
}
- $this->_fingerprint = md5('');
- return '';
+ // PostgreSQL's variant of a BLOB datatype is Bytea, which is a
+ // PITA to work with, so we use base64-encoded data in a TEXT
+ // field instead.
+ $result = ($this->_platform === 'postgre')
+ ? base64_decode(rtrim($result->data))
+ : $result->data;
+
+ $this->_fingerprint = md5($result);
+ $this->_row_exists = TRUE;
+ return $result;
}
// ------------------------------------------------------------------------
@@ -215,7 +215,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
{
if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id))
{
- return $this->_fail();
+ return $this->_failure;
}
$this->_row_exists = FALSE;
@@ -223,7 +223,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
}
elseif ($this->_lock === FALSE)
{
- return $this->_fail();
+ return $this->_failure;
}
if ($this->_row_exists === FALSE)
@@ -242,7 +242,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
$this->_db->where('id', $session_id);
@@ -265,7 +265,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -280,7 +280,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
public function close()
{
return ($this->_lock && ! $this->_release_lock())
- ? $this->_fail()
+ ? $this->_failure
: $this->_success;
}
@@ -309,7 +309,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
if ( ! $this->_db->delete($this->_config['save_path']))
{
- return $this->_fail();
+ return $this->_failure;
}
}
@@ -319,7 +319,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -339,7 +339,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime)))
? $this->_success
- : $this->_fail();
+ : $this->_failure;
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php
index 467059434..4b7b9878b 100644
--- a/system/libraries/Session/drivers/Session_files_driver.php
+++ b/system/libraries/Session/drivers/Session_files_driver.php
@@ -6,7 +6,7 @@
*
* This content is released under the MIT License (MIT)
*
- * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
+ * Copyright (c) 2019 - 2022, CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
+ * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
@@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Sessions
* @author Andrey Andreev
- * @link https://codeigniter.com/user_guide/libraries/sessions.html
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
*/
-class CI_Session_files_driver extends CI_Session_driver implements SessionHandlerInterface {
+class CI_Session_files_driver extends CI_Session_driver implements CI_Session_driver_interface {
/**
* Save path
@@ -115,7 +116,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle
$this->_sid_regexp = $this->_config['_sid_regexp'];
- isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
+ isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload'));
}
// ------------------------------------------------------------------------
@@ -135,12 +136,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle
{
if ( ! mkdir($save_path, 0700, TRUE))
{
- throw new Exception("Session: Configured save path '".$this->_config['save_path']."' is not a directory, doesn't exist or cannot be created.");
+ log_message('error', "Session: Configured save path '".$this->_config['save_path']."' is not a directory, doesn't exist or cannot be created.");
+ return $this->_failure;
}
}
elseif ( ! is_writable($save_path))
{
- throw new Exception("Session: Configured save path '".$this->_config['save_path']."' is not writable by the PHP process.");
+ log_message('error', "Session: Configured save path '".$this->_config['save_path']."' is not writable by the PHP process.");
+ return $this->_failure;
}
$this->_config['save_path'] = $save_path;
@@ -194,6 +197,10 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle
$this->_fingerprint = md5('');
return '';
}
+
+ // Prevent possible data corruption
+ // See https://github.com/bcit-ci/CodeIgniter/issues/5857
+ clearstatcache(TRUE, $this->_file_path.$session_id);
}
// We shouldn't need this, but apparently we do ...
// See https://github.com/bcit-ci/CodeIgniter/issues/4039
diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php
index ab54f029f..d84a9df1d 100644
--- a/system/libraries/Session/drivers/Session_memcached_driver.php
+++ b/system/libraries/Session/drivers/Session_memcached_driver.php
@@ -6,7 +6,7 @@
*
* This content is released under the MIT License (MIT)
*
- * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
+ * Copyright (c) 2019 - 2022, CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
+ * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
@@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Sessions
* @author Andrey Andreev
- * @link https://codeigniter.com/user_guide/libraries/sessions.html
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
*/
-class CI_Session_memcached_driver extends CI_Session_driver implements SessionHandlerInterface {
+class CI_Session_memcached_driver extends CI_Session_driver implements CI_Session_driver_interface {
/**
* Memcached instance
@@ -117,7 +118,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
{
$this->_memcached = NULL;
log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']);
- return $this->_fail();
+ return $this->_failure;
}
foreach ($matches as $match)
@@ -142,7 +143,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
if (empty($server_list))
{
log_message('error', 'Session: Memcached server pool is empty.');
- return $this->_fail();
+ return $this->_failure;
}
$this->php5_validate_id();
@@ -172,7 +173,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
return $session_data;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -190,14 +191,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
{
if ( ! isset($this->_memcached, $this->_lock_key))
{
- return $this->_fail();
+ return $this->_failure;
}
// Was the ID regenerated?
elseif ($session_id !== $this->_session_id)
{
if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id))
{
- return $this->_fail();
+ return $this->_failure;
}
$this->_fingerprint = md5('');
@@ -215,7 +216,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
elseif (
$this->_memcached->touch($key, $this->_config['expiration'])
@@ -225,7 +226,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -244,14 +245,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
$this->_release_lock();
if ( ! $this->_memcached->quit())
{
- return $this->_fail();
+ return $this->_failure;
}
$this->_memcached = NULL;
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -273,7 +274,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php
index 07511e555..fae024bee 100644
--- a/system/libraries/Session/drivers/Session_redis_driver.php
+++ b/system/libraries/Session/drivers/Session_redis_driver.php
@@ -6,7 +6,7 @@
*
* This content is released under the MIT License (MIT)
*
- * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
+ * Copyright (c) 2019 - 2022, CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
+ * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
@@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Sessions
* @author Andrey Andreev
- * @link https://codeigniter.com/user_guide/libraries/sessions.html
+ * @link https://codeigniter.com/userguide3/libraries/sessions.html
*/
-class CI_Session_redis_driver extends CI_Session_driver implements SessionHandlerInterface {
+class CI_Session_redis_driver extends CI_Session_driver implements CI_Session_driver_interface {
/**
* phpRedis instance
@@ -76,6 +77,33 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
*/
protected $_key_exists = FALSE;
+ /**
+ * Name of setTimeout() method in phpRedis
+ *
+ * Due to some deprecated methods in phpRedis, we need to call the
+ * specific methods depending on the version of phpRedis.
+ *
+ * @var string
+ */
+ protected $_setTimeout_name;
+
+ /**
+ * Name of delete() method in phpRedis
+ *
+ * Due to some deprecated methods in phpRedis, we need to call the
+ * specific methods depending on the version of phpRedis.
+ *
+ * @var string
+ */
+ protected $_delete_name;
+
+ /**
+ * Success return value of ping() method in phpRedis
+ *
+ * @var mixed
+ */
+ protected $_ping_success;
+
// ------------------------------------------------------------------------
/**
@@ -88,6 +116,20 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
parent::__construct($params);
+ // Detect the names of some methods in phpRedis instance
+ if (version_compare(phpversion('redis'), '5', '>='))
+ {
+ $this->_setTimeout_name = 'expire';
+ $this->_delete_name = 'del';
+ $this->_ping_success = TRUE;
+ }
+ else
+ {
+ $this->_setTimeout_name = 'setTimeout';
+ $this->_delete_name = 'delete';
+ $this->_ping_success = '+PONG';
+ }
+
if (empty($this->_config['save_path']))
{
log_message('error', 'Session: No Redis save path configured.');
@@ -96,7 +138,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
$save_path = array('path' => $matches[1]);
}
- elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(?<options>\?.+)?#', $this->_config['save_path'], $matches))
+ elseif (preg_match('#(?:(?:tcp|tls)://)?([^:?]+)(?:\:(\d+))?(?<options>\?.+)?#', $this->_config['save_path'], $matches))
{
$save_path = array(
'host' => $matches[1],
@@ -144,7 +186,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
if (empty($this->_config['save_path']))
{
- return $this->_fail();
+ return $this->_failure;
}
$redis = new Redis();
@@ -169,17 +211,18 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
else
{
$this->_redis = $redis;
+ $this->php5_validate_id();
return $this->_success;
}
}
else
{
- log_message('error', 'Session: Unable to connect to Redis with the configured settings.');
+ $this->_redis = $redis;
+ $this->php5_validate_id();
+ return $this->_success;
}
- $this->php5_validate_id();
-
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -209,7 +252,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
return $session_data;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -227,21 +270,21 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
if ( ! isset($this->_redis, $this->_lock_key))
{
- return $this->_fail();
+ return $this->_failure;
}
// Was the ID regenerated?
elseif ($session_id !== $this->_session_id)
{
if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id))
{
- return $this->_fail();
+ return $this->_failure;
}
$this->_key_exists = FALSE;
$this->_session_id = $session_id;
}
- $this->_redis->setTimeout($this->_lock_key, 300);
+ $this->_redis->{$this->_setTimeout_name}($this->_lock_key, 300);
if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE)
{
if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration']))
@@ -251,12 +294,12 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
- return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration']))
+ return ($this->_redis->{$this->_setTimeout_name}($this->_key_prefix.$session_id, $this->_config['expiration']))
? $this->_success
- : $this->_fail();
+ : $this->_failure;
}
// ------------------------------------------------------------------------
@@ -273,12 +316,12 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
if (isset($this->_redis))
{
try {
- if ($this->_redis->ping() === '+PONG')
+ if ($this->_redis->ping() === $this->_ping_success)
{
$this->_release_lock();
if ($this->_redis->close() === FALSE)
{
- return $this->_fail();
+ return $this->_failure;
}
}
}
@@ -308,16 +351,16 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
if (isset($this->_redis, $this->_lock_key))
{
- if (($result = $this->_redis->delete($this->_key_prefix.$session_id)) !== 1)
+ if (($result = $this->_redis->{$this->_delete_name}($this->_key_prefix.$session_id)) !== 1)
{
- log_message('debug', 'Session: Redis::delete() expected to return 1, got '.var_export($result, TRUE).' instead.');
+ log_message('debug', 'Session: Redis::'.$this->_delete_name.'() expected to return 1, got '.var_export($result, TRUE).' instead.');
}
$this->_cookie_destroy();
return $this->_success;
}
- return $this->_fail();
+ return $this->_failure;
}
// ------------------------------------------------------------------------
@@ -369,7 +412,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
// correct session ID.
if ($this->_lock_key === $this->_key_prefix.$session_id.':lock')
{
- return $this->_redis->setTimeout($this->_lock_key, 300);
+ return $this->_redis->{$this->_setTimeout_name}($this->_lock_key, 300);
}
// 30 attempts to obtain a lock, in case another request already has it
@@ -383,11 +426,13 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
continue;
}
- $result = ($ttl === -2)
- ? $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300))
- : $this->_redis->setex($lock_key, 300, time());
-
- if ( ! $result)
+ if ($ttl === -2 && ! $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300)))
+ {
+ // Sleep for 1s to wait for lock releases.
+ sleep(1);
+ continue;
+ }
+ elseif ( ! $this->_redis->setex($lock_key, 300, time()))
{
log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id);
return FALSE;
@@ -425,7 +470,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
if (isset($this->_redis, $this->_lock_key) && $this->_lock)
{
- if ( ! $this->_redis->delete($this->_lock_key))
+ if ( ! $this->_redis->{$this->_delete_name}($this->_lock_key))
{
log_message('error', 'Session: Error while trying to free lock for '.$this->_lock_key);
return FALSE;
diff --git a/system/libraries/Session/drivers/index.html b/system/libraries/Session/drivers/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Session/drivers/index.html
+++ b/system/libraries/Session/drivers/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Session/index.html b/system/libraries/Session/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Session/index.html
+++ b/system/libraries/Session/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index 055512698..98258b63d 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category HTML Tables
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/table.html
+ * @link https://codeigniter.com/userguide3/libraries/table.html
*/
class CI_Table {
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index 07f066d01..75ccae8f8 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Trackbacks
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/trackback.html
+ * @link https://codeigniter.com/userguide3/libraries/trackback.html
*/
class CI_Trackback {
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index e67138c1a..d919d484a 100644
--- a/system/libraries/Typography.php
+++ b/system/libraries/Typography.php
@@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Helpers
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/typography.html
+ * @link https://codeigniter.com/userguide3/libraries/typography.html
*/
class CI_Typography {
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 631d583ba..55e3bfcb2 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category UnitTesting
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/unit_testing.html
+ * @link https://codeigniter.com/userguide3/libraries/unit_testing.html
*/
class CI_Unit_test {
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 8c891cff6..281ebef1a 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Uploads
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/file_uploading.html
+ * @link https://codeigniter.com/userguide3/libraries/file_uploading.html
*/
class CI_Upload {
@@ -867,7 +867,7 @@ class CI_Upload {
$this->file_type = 'image/jpeg';
}
- $img_mimes = array('image/gif', 'image/jpeg', 'image/png');
+ $img_mimes = array('image/gif', 'image/jpeg', 'image/png', 'image/webp');
return in_array($this->file_type, $img_mimes, TRUE);
}
@@ -901,7 +901,7 @@ class CI_Upload {
}
// Images get some additional checks
- if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png'), TRUE) && @getimagesize($this->file_temp) === FALSE)
+ if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png', 'webp'), TRUE) && @getimagesize($this->file_temp) === FALSE)
{
return FALSE;
}
@@ -1227,7 +1227,7 @@ class CI_Upload {
if (function_exists('finfo_file'))
{
$finfo = @finfo_open(FILEINFO_MIME);
- if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
+ if ($finfo !== FALSE) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
{
$mime = @finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index a70511fc3..c144db7a8 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category User Agent
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/user_agent.html
+ * @link https://codeigniter.com/userguide3/libraries/user_agent.html
*/
class CI_User_agent {
@@ -498,7 +498,7 @@ class CI_User_agent {
else
{
$referer_host = @parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
- $own_host = parse_url(config_item('base_url'), PHP_URL_HOST);
+ $own_host = parse_url((string) config_item('base_url'), PHP_URL_HOST);
$this->referer = ($referer_host && $referer_host !== $own_host);
}
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 4e8c303c7..11d4400fe 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -51,7 +51,7 @@ if ( ! function_exists('xml_parser_create'))
* @subpackage Libraries
* @category XML-RPC
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html
+ * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html
*/
class CI_Xmlrpc {
@@ -559,7 +559,7 @@ class CI_Xmlrpc {
*
* @category XML-RPC
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html
+ * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html
*/
class XML_RPC_Client extends CI_Xmlrpc
{
@@ -780,7 +780,7 @@ class XML_RPC_Client extends CI_Xmlrpc
*
* @category XML-RPC
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html
+ * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html
*/
class XML_RPC_Response
{
@@ -1028,7 +1028,7 @@ class XML_RPC_Response
*
* @category XML-RPC
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html
+ * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html
*/
class XML_RPC_Message extends CI_Xmlrpc
{
@@ -1647,7 +1647,7 @@ class XML_RPC_Message extends CI_Xmlrpc
*
* @category XML-RPC
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html
+ * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html
*/
class XML_RPC_Values extends CI_Xmlrpc
{
@@ -1912,7 +1912,7 @@ class XML_RPC_Values extends CI_Xmlrpc
*/
public function iso8601_encode($time, $utc = FALSE)
{
- return ($utc) ? strftime('%Y%m%dT%H:%i:%s', $time) : gmstrftime('%Y%m%dT%H:%i:%s', $time);
+ return ($utc) ? date('Ymd\TH:i:s', $time) : gmdate('Ymd\TH:i:s', $time);
}
} // END XML_RPC_Values Class
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index e70b80397..e20bf4836 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -56,7 +56,7 @@ if ( ! class_exists('CI_Xmlrpc', FALSE))
* @subpackage Libraries
* @category XML-RPC
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html
+ * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html
*/
class CI_Xmlrpcs extends CI_Xmlrpc {
@@ -348,7 +348,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc {
return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
}
}
- elseif (($objectCall && ! is_callable(array($method_parts[0], $method_parts[1])))
+ elseif (($objectCall && ( ! method_exists($method_parts[0], $method_parts[1]) OR ! (new ReflectionMethod($method_parts[0], $method_parts[1]))->isPublic()))
OR ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))
)
{
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 094f4c802..f744493a9 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @subpackage Libraries
* @category Encryption
* @author EllisLab Dev Team
- * @link https://codeigniter.com/user_guide/libraries/zip.html
+ * @link https://codeigniter.com/userguide3/libraries/zip.html
*/
class CI_Zip {
@@ -119,7 +119,7 @@ class CI_Zip {
*/
public function __construct()
{
- isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
+ isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload'));
$this->now = time();
log_message('info', 'Zip Compression Class Initialized');
@@ -406,13 +406,14 @@ class CI_Zip {
return FALSE;
}
- return $this->zipdata
- .$this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00"
+ // @see https://github.com/bcit-ci/CodeIgniter/issues/5864
+ $footer = $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00"
.pack('v', $this->entries) // total # of entries "on this disk"
.pack('v', $this->entries) // total # of entries overall
.pack('V', self::strlen($this->directory)) // size of central dir
.pack('V', self::strlen($this->zipdata)) // offset to start of central dir
."\x00\x00"; // .zip file comment length
+ return $this->zipdata.$footer;
}
// --------------------------------------------------------------------
diff --git a/system/libraries/index.html b/system/libraries/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/index.html
+++ b/system/libraries/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>