From d09ee2788da8a235c50a83fafa81b93047992311 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 29 Dec 2018 16:16:49 +0100 Subject: [PATCH] Update to CodeIgniter 3.19 --- system/core/Benchmark.php | 4 +- system/core/CodeIgniter.php | 36 +- system/core/Common.php | 54 +- system/core/Config.php | 13 +- system/core/Controller.php | 4 +- system/core/Exceptions.php | 7 +- system/core/Hooks.php | 4 +- system/core/Input.php | 54 +- system/core/Lang.php | 8 +- system/core/Loader.php | 188 +++---- system/core/Log.php | 59 +- system/core/Model.php | 12 +- system/core/Output.php | 174 +++--- system/core/Router.php | 4 +- system/core/Security.php | 143 +++-- system/core/URI.php | 4 +- system/core/Utf8.php | 4 +- system/core/compat/hash.php | 23 +- system/core/compat/mbstring.php | 6 +- system/core/compat/password.php | 42 +- system/core/compat/standard.php | 215 +------- system/database/DB.php | 4 +- system/database/DB_cache.php | 6 +- system/database/DB_driver.php | 29 +- system/database/DB_forge.php | 22 +- system/database/DB_query_builder.php | 176 +++--- system/database/DB_result.php | 15 +- system/database/DB_utility.php | 4 +- .../database/drivers/cubrid/cubrid_driver.php | 8 +- .../database/drivers/cubrid/cubrid_forge.php | 7 +- .../database/drivers/cubrid/cubrid_result.php | 4 +- .../drivers/cubrid/cubrid_utility.php | 4 +- .../database/drivers/ibase/ibase_driver.php | 23 +- system/database/drivers/ibase/ibase_forge.php | 8 +- .../database/drivers/ibase/ibase_result.php | 4 +- .../database/drivers/ibase/ibase_utility.php | 4 +- .../database/drivers/mssql/mssql_driver.php | 11 +- system/database/drivers/mssql/mssql_forge.php | 9 +- .../database/drivers/mssql/mssql_result.php | 4 +- .../database/drivers/mssql/mssql_utility.php | 4 +- .../database/drivers/mysql/mysql_driver.php | 9 +- system/database/drivers/mysql/mysql_forge.php | 4 +- .../database/drivers/mysql/mysql_result.php | 4 +- .../database/drivers/mysql/mysql_utility.php | 4 +- .../database/drivers/mysqli/mysqli_driver.php | 18 +- .../database/drivers/mysqli/mysqli_forge.php | 4 +- .../database/drivers/mysqli/mysqli_result.php | 54 +- .../drivers/mysqli/mysqli_utility.php | 8 +- system/database/drivers/oci8/oci8_driver.php | 43 +- system/database/drivers/oci8/oci8_forge.php | 46 +- system/database/drivers/oci8/oci8_result.php | 4 +- system/database/drivers/oci8/oci8_utility.php | 4 +- system/database/drivers/odbc/odbc_driver.php | 173 +++--- system/database/drivers/odbc/odbc_forge.php | 4 +- system/database/drivers/odbc/odbc_result.php | 4 +- system/database/drivers/odbc/odbc_utility.php | 4 +- system/database/drivers/pdo/pdo_driver.php | 59 +- system/database/drivers/pdo/pdo_forge.php | 4 +- system/database/drivers/pdo/pdo_result.php | 4 +- system/database/drivers/pdo/pdo_utility.php | 4 +- .../drivers/pdo/subdrivers/pdo_4d_driver.php | 4 +- .../drivers/pdo/subdrivers/pdo_4d_forge.php | 4 +- .../pdo/subdrivers/pdo_cubrid_driver.php | 45 +- .../pdo/subdrivers/pdo_cubrid_forge.php | 7 +- .../pdo/subdrivers/pdo_dblib_driver.php | 31 +- .../pdo/subdrivers/pdo_dblib_forge.php | 9 +- .../pdo/subdrivers/pdo_firebird_driver.php | 20 +- .../pdo/subdrivers/pdo_firebird_forge.php | 6 +- .../drivers/pdo/subdrivers/pdo_ibm_driver.php | 4 +- .../drivers/pdo/subdrivers/pdo_ibm_forge.php | 4 +- .../pdo/subdrivers/pdo_informix_driver.php | 4 +- .../pdo/subdrivers/pdo_informix_forge.php | 4 +- .../pdo/subdrivers/pdo_mysql_driver.php | 72 ++- .../pdo/subdrivers/pdo_mysql_forge.php | 4 +- .../drivers/pdo/subdrivers/pdo_oci_driver.php | 4 +- .../drivers/pdo/subdrivers/pdo_oci_forge.php | 47 +- .../pdo/subdrivers/pdo_odbc_driver.php | 87 +-- .../drivers/pdo/subdrivers/pdo_odbc_forge.php | 4 +- .../pdo/subdrivers/pdo_pgsql_driver.php | 14 +- .../pdo/subdrivers/pdo_pgsql_forge.php | 6 +- .../pdo/subdrivers/pdo_sqlite_driver.php | 6 +- .../pdo/subdrivers/pdo_sqlite_forge.php | 8 +- .../pdo/subdrivers/pdo_sqlsrv_driver.php | 8 +- .../pdo/subdrivers/pdo_sqlsrv_forge.php | 9 +- .../drivers/postgre/postgre_driver.php | 29 +- .../drivers/postgre/postgre_forge.php | 6 +- .../drivers/postgre/postgre_result.php | 4 +- .../drivers/postgre/postgre_utility.php | 4 +- .../database/drivers/sqlite/sqlite_driver.php | 4 +- .../database/drivers/sqlite/sqlite_forge.php | 8 +- .../database/drivers/sqlite/sqlite_result.php | 4 +- .../drivers/sqlite/sqlite_utility.php | 4 +- .../drivers/sqlite3/sqlite3_driver.php | 8 +- .../drivers/sqlite3/sqlite3_forge.php | 8 +- .../drivers/sqlite3/sqlite3_result.php | 4 +- .../drivers/sqlite3/sqlite3_utility.php | 4 +- .../database/drivers/sqlsrv/sqlsrv_driver.php | 11 +- .../database/drivers/sqlsrv/sqlsrv_forge.php | 9 +- .../database/drivers/sqlsrv/sqlsrv_result.php | 4 +- .../drivers/sqlsrv/sqlsrv_utility.php | 4 +- system/helpers/array_helper.php | 4 +- system/helpers/captcha_helper.php | 15 +- system/helpers/cookie_helper.php | 6 +- system/helpers/date_helper.php | 88 +-- system/helpers/directory_helper.php | 4 +- system/helpers/download_helper.php | 4 +- system/helpers/email_helper.php | 4 +- system/helpers/file_helper.php | 12 +- system/helpers/form_helper.php | 57 +- system/helpers/html_helper.php | 12 +- system/helpers/inflector_helper.php | 38 +- system/helpers/language_helper.php | 4 +- system/helpers/number_helper.php | 4 +- system/helpers/path_helper.php | 6 +- system/helpers/security_helper.php | 4 +- system/helpers/smiley_helper.php | 4 +- system/helpers/string_helper.php | 8 +- system/helpers/text_helper.php | 13 +- system/helpers/typography_helper.php | 4 +- system/helpers/url_helper.php | 8 +- system/helpers/xml_helper.php | 4 +- system/libraries/Cache/Cache.php | 4 +- system/libraries/Cache/drivers/Cache_apc.php | 54 +- .../libraries/Cache/drivers/Cache_dummy.php | 4 +- system/libraries/Cache/drivers/Cache_file.php | 12 +- .../Cache/drivers/Cache_memcached.php | 22 +- .../libraries/Cache/drivers/Cache_redis.php | 4 +- .../Cache/drivers/Cache_wincache.php | 4 +- system/libraries/Calendar.php | 4 +- system/libraries/Cart.php | 4 +- system/libraries/Driver.php | 4 +- system/libraries/Email.php | 517 +++++++++++------- system/libraries/Encrypt.php | 63 ++- system/libraries/Encryption.php | 54 +- system/libraries/Form_validation.php | 173 +++--- system/libraries/Ftp.php | 6 +- system/libraries/Image_lib.php | 101 ++-- system/libraries/Javascript.php | 4 +- system/libraries/Javascript/Jquery.php | 4 +- system/libraries/Migration.php | 21 +- system/libraries/Pagination.php | 13 +- system/libraries/Parser.php | 4 +- system/libraries/Profiler.php | 26 +- system/libraries/Session/Session.php | 97 +++- .../Session/SessionHandlerInterface.php | 4 +- system/libraries/Session/Session_driver.php | 21 +- .../drivers/Session_database_driver.php | 41 +- .../Session/drivers/Session_files_driver.php | 83 ++- .../drivers/Session_memcached_driver.php | 71 ++- .../Session/drivers/Session_redis_driver.php | 59 +- system/libraries/Table.php | 7 +- system/libraries/Trackback.php | 6 +- system/libraries/Typography.php | 6 +- system/libraries/Unit_test.php | 7 +- system/libraries/Upload.php | 52 +- system/libraries/User_agent.php | 10 +- system/libraries/Xmlrpc.php | 51 +- system/libraries/Xmlrpcs.php | 32 +- system/libraries/Zip.php | 78 ++- 159 files changed, 2508 insertions(+), 1910 deletions(-) diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php index b1d74f7..d6e1336 100644 --- a/system/core/Benchmark.php +++ b/system/core/Benchmark.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 3eb3e05..7b1dcc2 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -55,7 +55,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @var string * */ - define('CI_VERSION', '3.0.6'); + const CI_VERSION = '3.1.9'; /* * ------------------------------------------------------ @@ -67,7 +67,10 @@ defined('BASEPATH') OR exit('No direct script access allowed'); require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); } - require_once(APPPATH.'config/constants.php'); + if (file_exists(APPPATH.'config/constants.php')) + { + require_once(APPPATH.'config/constants.php'); + } /* * ------------------------------------------------------ @@ -416,14 +419,29 @@ if ( ! is_php('5.4')) $params = array($method, array_slice($URI->rsegments, 2)); $method = '_remap'; } - // WARNING: It appears that there are issues with is_callable() even in PHP 5.2! - // Furthermore, there are bug reports and feature/change requests related to it - // that make it unreliable to use in this context. Please, DO NOT change this - // work-around until a better alternative is available. - elseif ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE)) + elseif ( ! method_exists($class, $method)) { $e404 = TRUE; } + /** + * DO NOT CHANGE THIS, NOTHING ELSE WORKS! + * + * - method_exists() returns true for non-public methods, which passes the previous elseif + * - is_callable() returns false for PHP 4-style constructors, even if there's a __construct() + * - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited + * - People will only complain if this doesn't work, even though it is documented that it shouldn't. + * + * ReflectionMethod::isConstructor() is the ONLY reliable check, + * knowing which method will be executed as a constructor. + */ + elseif ( ! is_callable(array($class, $method))) + { + $reflection = new ReflectionMethod($class, $method); + if ( ! $reflection->isPublic() OR $reflection->isConstructor()) + { + $e404 = TRUE; + } + } } if ($e404) diff --git a/system/core/Common.php b/system/core/Common.php index b87ce4d..6d60f23 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -135,7 +135,7 @@ if ( ! function_exists('load_class')) * * @param string the class name being requested * @param string the directory where the class should be found - * @param string an optional argument to pass to the class constructor + * @param mixed an optional argument to pass to the class constructor * @return object */ function &load_class($class, $directory = 'libraries', $param = NULL) @@ -319,17 +319,13 @@ if ( ! function_exists('get_mimes')) if (empty($_mimes)) { + $_mimes = file_exists(APPPATH.'config/mimes.php') + ? include(APPPATH.'config/mimes.php') + : array(); + if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) { - $_mimes = include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); - } - elseif (file_exists(APPPATH.'config/mimes.php')) - { - $_mimes = include(APPPATH.'config/mimes.php'); - } - else - { - $_mimes = array(); + $_mimes = array_merge($_mimes, include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')); } } @@ -355,7 +351,7 @@ if ( ! function_exists('is_https')) { return TRUE; } - elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') + elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') { return TRUE; } @@ -410,11 +406,6 @@ if ( ! function_exists('show_error')) if ($status_code < 100) { $exit_status = $status_code + 9; // 9 is EXIT__AUTO_MIN - if ($exit_status > 125) // 125 is EXIT__AUTO_MAX - { - $exit_status = 1; // EXIT_ERROR - } - $status_code = 500; } else @@ -544,13 +535,18 @@ if ( ! function_exists('set_status_header')) 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 422 => 'Unprocessable Entity', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported' + 505 => 'HTTP Version Not Supported', + 511 => 'Network Authentication Required', ); if (isset($stati[$code])) @@ -566,12 +562,12 @@ if ( ! function_exists('set_status_header')) if (strpos(PHP_SAPI, 'cgi') === 0) { header('Status: '.$code.' '.$text, TRUE); + return; } - else - { - $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; - header($server_protocol.' '.$code.' '.$text, TRUE, $code); - } + + $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2'), TRUE)) + ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; + header($server_protocol.' '.$code.' '.$text, TRUE, $code); } } @@ -598,7 +594,7 @@ if ( ! function_exists('_error_handler')) */ function _error_handler($severity, $message, $filepath, $line) { - $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); + $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); // When an error occurred, set the status header to '500 Internal Server Error' // to indicate to the client something went wrong. @@ -656,6 +652,7 @@ if ( ! function_exists('_exception_handler')) $_error =& load_class('Exceptions', 'core'); $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine()); + is_cli() OR set_status_header(500); // Should we display the error? if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) { @@ -716,8 +713,9 @@ if ( ! function_exists('remove_invisible_characters')) // carriage return (dec 13) and horizontal tab (dec 09) if ($url_encoded) { - $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 - $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31 + $non_displayables[] = '/%0[0-8bcef]/i'; // url encoded 00-08, 11, 12, 14, 15 + $non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31 + $non_displayables[] = '/%7f/i'; // url encoded 127 } $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 @@ -821,7 +819,7 @@ if ( ! function_exists('function_usable')) * terminate script execution if a disabled function is executed. * * The above described behavior turned out to be a bug in Suhosin, - * but even though a fix was commited for 0.9.34 on 2012-02-12, + * but even though a fix was committed for 0.9.34 on 2012-02-12, * that version is yet to be released. This function will therefore * be just temporary, but would probably be kept for a few years. * diff --git a/system/core/Config.php b/system/core/Config.php index ca6fb37..8136dd2 100644 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -319,7 +319,7 @@ class CI_Config { } } - return $base_url.ltrim($this->_uri_string($uri), '/'); + return $base_url.$this->_uri_string($uri); } // ------------------------------------------------------------- @@ -337,11 +337,8 @@ class CI_Config { { if ($this->item('enable_query_strings') === FALSE) { - if (is_array($uri)) - { - $uri = implode('/', $uri); - } - return trim($uri, '/'); + is_array($uri) && $uri = implode('/', $uri); + return ltrim($uri, '/'); } elseif (is_array($uri)) { diff --git a/system/core/Controller.php b/system/core/Controller.php index 83b3df2..ec9aa2a 100644 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index a1c6a19..5a78376 100644 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -207,7 +207,6 @@ class CI_Exceptions { } else { - set_status_header(500); $templates_path .= 'html'.DIRECTORY_SEPARATOR; } @@ -232,7 +231,7 @@ class CI_Exceptions { * @param string $message Error message * @param string $filepath File path * @param int $line Line number - * @return string Error page output + * @return void */ public function show_php_error($severity, $message, $filepath, $line) { diff --git a/system/core/Hooks.php b/system/core/Hooks.php index 856795c..82c68b1 100644 --- a/system/core/Hooks.php +++ b/system/core/Hooks.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/core/Input.php b/system/core/Input.php index a7c9ecd..143babf 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -137,7 +137,7 @@ class CI_Input { */ public function __construct() { - $this->_allow_get_array = (config_item('allow_get_array') === TRUE); + $this->_allow_get_array = (config_item('allow_get_array') !== FALSE); $this->_enable_xss = (config_item('global_xss_filtering') === TRUE); $this->_enable_csrf = (config_item('csrf_protection') === TRUE); $this->_standardize_newlines = (bool) config_item('standardize_newlines'); @@ -359,7 +359,7 @@ class CI_Input { * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) * @return void */ - public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) + public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL) { if (is_array($name)) { @@ -388,15 +388,13 @@ class CI_Input { $path = config_item('cookie_path'); } - if ($secure === FALSE && config_item('cookie_secure') === TRUE) - { - $secure = config_item('cookie_secure'); - } + $secure = ($secure === NULL && config_item('cookie_secure') !== NULL) + ? (bool) config_item('cookie_secure') + : (bool) $secure; - if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE) - { - $httponly = config_item('cookie_httponly'); - } + $httponly = ($httponly === NULL && config_item('cookie_httponly') !== NULL) + ? (bool) config_item('cookie_httponly') + : (bool) $httponly; if ( ! is_numeric($expire)) { @@ -519,9 +517,9 @@ class CI_Input { if ($separator === ':') { $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); - for ($i = 0; $i < 8; $i++) + for ($j = 0; $j < 8; $j++) { - $netaddr[$i] = intval($netaddr[$i], 16); + $netaddr[$j] = intval($netaddr[$j], 16); } } else @@ -760,30 +758,32 @@ class CI_Input { // If header is already defined, return it immediately if ( ! empty($this->headers)) { - return $this->headers; + return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // In Apache, you can simply call apache_request_headers() if (function_exists('apache_request_headers')) { - return $this->headers = apache_request_headers(); + $this->headers = apache_request_headers(); } - - $this->headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE'); - - foreach ($_SERVER as $key => $val) + else { - if (sscanf($key, 'HTTP_%s', $header) === 1) - { - // take SOME_HEADER and turn it into Some-Header - $header = str_replace('_', ' ', strtolower($header)); - $header = str_replace(' ', '-', ucwords($header)); + isset($_SERVER['CONTENT_TYPE']) && $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE']; - $this->headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean); + foreach ($_SERVER as $key => $val) + { + if (sscanf($key, 'HTTP_%s', $header) === 1) + { + // take SOME_HEADER and turn it into Some-Header + $header = str_replace('_', ' ', strtolower($header)); + $header = str_replace(' ', '-', ucwords($header)); + + $this->headers[$header] = $_SERVER[$key]; + } } } - return $this->headers; + return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // -------------------------------------------------------------------- diff --git a/system/core/Lang.php b/system/core/Lang.php index ca7825c..39fdd06 100644 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -78,7 +78,7 @@ class CI_Lang { * Load a language file * * @param mixed $langfile Language file name - * @param string $idiom Language name (en, etc.) + * @param string $idiom Language name (english, etc.) * @param bool $return Whether to return the loaded array of translations * @param bool $add_suffix Whether to add suffix to $langfile * @param string $alt_path Alternative path to look for the language file @@ -109,7 +109,7 @@ class CI_Lang { if (empty($idiom) OR ! preg_match('/^[a-z_-]+$/i', $idiom)) { $config =& get_config(); - $idiom = empty($config['language']) ? 'en' : $config['language']; + $idiom = empty($config['language']) ? 'english' : $config['language']; } if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom) diff --git a/system/core/Loader.php b/system/core/Loader.php index c742ae7..c84aff3 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -182,7 +182,7 @@ class CI_Loader { * Loads and instantiates libraries. * Designed to be called from application controllers. * - * @param string $library Library name + * @param mixed $library Library name * @param array $params Optional parameters to pass to the library class constructor * @param string $object_name An optional object name to assign to * @return object @@ -226,7 +226,7 @@ class CI_Loader { * * Loads and instantiates models. * - * @param string $model Model name + * @param mixed $model Model name * @param string $name An optional object name to assign to * @param bool $db_conn An optional database connection configuration to initialize * @return object @@ -303,6 +303,8 @@ class CI_Loader { { throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model"); } + + log_message('info', 'CI_Model class loaded'); } elseif ( ! class_exists('CI_Model', FALSE)) { @@ -317,6 +319,8 @@ class CI_Loader { { throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); } + + log_message('info', config_item('subclass_prefix').'Model class loaded'); } } @@ -350,7 +354,9 @@ class CI_Loader { } $this->_ci_models[] = $name; - $CI->$name = new $model(); + $model = new $model(); + $CI->$name = $model; + log_message('info', 'Model "'.get_class($model).'" initialized'); return $this; } @@ -486,7 +492,7 @@ class CI_Loader { */ public function view($view, $vars = array(), $return = FALSE) { - return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); + return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return)); } // -------------------------------------------------------------------- @@ -519,19 +525,13 @@ class CI_Loader { */ public function vars($vars, $val = '') { - if (is_string($vars)) - { - $vars = array($vars => $val); - } + $vars = is_string($vars) + ? array($vars => $val) + : $this->_ci_prepare_view_vars($vars); - $vars = $this->_ci_object_to_array($vars); - - if (is_array($vars) && count($vars) > 0) + foreach ($vars as $key => $val) { - foreach ($vars as $key => $val) - { - $this->_ci_cached_vars[$key] = $val; - } + $this->_ci_cached_vars[$key] = $val; } return $this; @@ -591,15 +591,21 @@ class CI_Loader { */ public function helper($helpers = array()) { - foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper) + is_array($helpers) OR $helpers = array($helpers); + foreach ($helpers as &$helper) { + $filename = basename($helper); + $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); + $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper'; + $helper = $filepath.$filename; + if (isset($this->_ci_helpers[$helper])) { continue; } // Is this a helper extension request? - $ext_helper = config_item('subclass_prefix').$helper; + $ext_helper = config_item('subclass_prefix').$filename; $ext_loaded = FALSE; foreach ($this->_ci_helper_paths as $path) { @@ -934,18 +940,7 @@ class CI_Loader { * the two types and cache them so that views that are embedded within * other views can have access to these variables. */ - if (is_array($_ci_vars)) - { - foreach (array_keys($_ci_vars) as $key) - { - if (strncmp($key, '_ci_', 4) === 0) - { - unset($_ci_vars[$key]); - } - } - - $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); - } + empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); extract($this->_ci_cached_vars); /* @@ -1048,6 +1043,26 @@ class CI_Loader { return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); } + // Safety: Was the class already loaded by a previous call? + if (class_exists($class, FALSE)) + { + $property = $object_name; + if (empty($property)) + { + $property = strtolower($class); + isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; + } + + $CI =& get_instance(); + if (isset($CI->$property)) + { + log_message('debug', $class.' class already loaded. Second attempt ignored.'); + return; + } + + return $this->_ci_init_library($class, '', $params, $object_name); + } + // Let's search for the requested library file and load it. foreach ($this->_ci_library_paths as $path) { @@ -1058,27 +1073,8 @@ class CI_Loader { } $filepath = $path.'libraries/'.$subdir.$class.'.php'; - - // Safety: Was the class already loaded by a previous call? - if (class_exists($class, FALSE)) - { - // Before we deem this to be a duplicate request, let's see - // if a custom object name is being supplied. If so, we'll - // return a new instance of the object - if ($object_name !== NULL) - { - $CI =& get_instance(); - if ( ! isset($CI->$object_name)) - { - return $this->_ci_init_library($class, '', $params, $object_name); - } - } - - log_message('debug', $class.' class already loaded. Second attempt ignored.'); - return; - } // Does the file exist? No? Bummer... - elseif ( ! file_exists($filepath)) + if ( ! file_exists($filepath)) { continue; } @@ -1106,7 +1102,7 @@ class CI_Loader { * @used-by CI_Loader::_ci_load_library() * @uses CI_Loader::_ci_init_library() * - * @param string $library Library name to load + * @param string $library_name Library name to load * @param string $file_path Path to the library filename, relative to libraries/ * @param mixed $params Optional parameters to pass to the class constructor * @param string $object_name Optional object name to assign to @@ -1123,16 +1119,17 @@ class CI_Loader { $prefix = config_item('subclass_prefix'); } - // Before we deem this to be a duplicate request, let's see - // if a custom object name is being supplied. If so, we'll - // return a new instance of the object - if ($object_name !== NULL) + $property = $object_name; + if (empty($property)) { - $CI =& get_instance(); - if ( ! isset($CI->$object_name)) - { - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } + $property = strtolower($library_name); + isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; + } + + $CI =& get_instance(); + if ( ! isset($CI->$property)) + { + return $this->_ci_init_library($library_name, $prefix, $params, $object_name); } log_message('debug', $library_name.' class already loaded. Second attempt ignored.'); @@ -1154,10 +1151,8 @@ class CI_Loader { { return $this->_ci_init_library($library_name, $prefix, $params, $object_name); } - else - { - log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name); - } + + log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name); } } @@ -1175,10 +1170,8 @@ class CI_Loader { $prefix = config_item('subclass_prefix'); break; } - else - { - log_message('debug', $path.' exists, but does not declare '.$subclass); - } + + log_message('debug', $path.' exists, but does not declare '.$subclass); } } @@ -1376,17 +1369,32 @@ class CI_Loader { // -------------------------------------------------------------------- /** - * CI Object to Array translator + * Prepare variables for _ci_vars, to be later extract()-ed inside views * - * Takes an object as input and converts the class variables to - * an associative array with key/value pairs. + * Converts objects to associative arrays and filters-out internal + * variable names (i.e. keys prefixed with '_ci_'). * - * @param object $object Object data to translate + * @param mixed $vars * @return array */ - protected function _ci_object_to_array($object) + protected function _ci_prepare_view_vars($vars) { - return is_object($object) ? get_object_vars($object) : $object; + if ( ! is_array($vars)) + { + $vars = is_object($vars) + ? get_object_vars($vars) + : array(); + } + + foreach (array_keys($vars) as $key) + { + if (strncmp($key, '_ci_', 4) === 0) + { + unset($vars[$key]); + } + } + + return $vars; } // -------------------------------------------------------------------- @@ -1404,34 +1412,4 @@ class CI_Loader { $CI =& get_instance(); return $CI->$component; } - - // -------------------------------------------------------------------- - - /** - * Prep filename - * - * This function prepares filenames of various items to - * make their loading more reliable. - * - * @param string|string[] $filename Filename(s) - * @param string $extension Filename extension - * @return array - */ - protected function _ci_prep_filename($filename, $extension) - { - if ( ! is_array($filename)) - { - return array(strtolower(str_replace(array($extension, '.php'), '', $filename).$extension)); - } - else - { - foreach ($filename as $key => $val) - { - $filename[$key] = strtolower(str_replace(array($extension, '.php'), '', $val).$extension); - } - - return $filename; - } - } - } diff --git a/system/core/Log.php b/system/core/Log.php index 1abdaa0..a2b464c 100644 --- a/system/core/Log.php +++ b/system/core/Log.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -104,6 +104,13 @@ class CI_Log { */ protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4); + /** + * mbstring.func_overload flag + * + * @var bool + */ + protected static $func_overload; + // -------------------------------------------------------------------- /** @@ -115,6 +122,8 @@ class CI_Log { { $config =& get_config(); + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + $this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/'; $this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '') ? ltrim($config['log_file_extension'], '.') : 'php'; @@ -208,9 +217,9 @@ class CI_Log { $message .= $this->_format_line($level, $date, $msg); - for ($written = 0, $length = strlen($message); $written < $length; $written += $result) + for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result) { - if (($result = fwrite($fp, substr($message, $written))) === FALSE) + if (($result = fwrite($fp, self::substr($message, $written))) === FALSE) { break; } @@ -237,11 +246,51 @@ class CI_Log { * * @param string $level The error level * @param string $date Formatted date string - * @param string $msg The log message + * @param string $message The log message * @return string Formatted log line with a new line character '\n' at the end */ protected function _format_line($level, $date, $message) { return $level.' - '.$date.' --> '.$message."\n"; } + + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_overload) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/system/core/Model.php b/system/core/Model.php index 941881a..dd11dd2 100644 --- a/system/core/Model.php +++ b/system/core/Model.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -51,14 +51,10 @@ class CI_Model { /** * Class constructor * + * @link https://github.com/bcit-ci/CodeIgniter/issues/5332 * @return void */ - public function __construct() - { - log_message('info', 'Model Class Initialized'); - } - - // -------------------------------------------------------------------- + public function __construct() {} /** * __get magic diff --git a/system/core/Output.php b/system/core/Output.php index ec9c21b..3cda062 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -122,6 +122,13 @@ class CI_Output { */ public $parse_exec_vars = TRUE; + /** + * mbstring.func_overload flag + * + * @var bool + */ + protected static $func_overload; + /** * Class constructor * @@ -138,6 +145,8 @@ class CI_Output { && extension_loaded('zlib') ); + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + // Get mime types for later $this->mimes =& get_mimes(); @@ -285,7 +294,7 @@ class CI_Output { /** * Get Header * - * @param string $header_name + * @param string $header * @return string */ public function get_header($header) @@ -302,11 +311,12 @@ class CI_Output { return NULL; } - for ($i = 0, $c = count($headers); $i < $c; $i++) + // Count backwards, in order to get the last matching header + for ($c = count($headers) - 1; $c > -1; $c--) { - if (strncasecmp($header, $headers[$i], $l = strlen($header)) === 0) + if (strncasecmp($header, $headers[$c], $l = self::strlen($header)) === 0) { - return trim(substr($headers[$i], $l+1)); + return trim(self::substr($headers[$c], $l+1)); } } @@ -480,13 +490,13 @@ class CI_Output { if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { header('Content-Encoding: gzip'); - header('Content-Length: '.strlen($output)); + header('Content-Length: '.self::strlen($output)); } else { // User agent doesn't support gzip compression, // so we'll have to decompress our cache - $output = gzinflate(substr($output, 10, -8)); + $output = gzinflate(self::substr($output, 10, -8)); } } @@ -576,62 +586,59 @@ class CI_Output { return; } - if (flock($fp, LOCK_EX)) - { - // If output compression is enabled, compress the cache - // itself, so that we don't have to do that each time - // we're serving it - if ($this->_compress_output === TRUE) - { - $output = gzencode($output); - - if ($this->get_header('content-type') === NULL) - { - $this->set_content_type($this->mime_type); - } - } - - $expire = time() + ($this->cache_expiration * 60); - - // Put together our serialized info. - $cache_info = serialize(array( - 'expire' => $expire, - 'headers' => $this->headers - )); - - $output = $cache_info.'ENDCI--->'.$output; - - for ($written = 0, $length = strlen($output); $written < $length; $written += $result) - { - if (($result = fwrite($fp, substr($output, $written))) === FALSE) - { - break; - } - } - - flock($fp, LOCK_UN); - } - else + if ( ! flock($fp, LOCK_EX)) { log_message('error', 'Unable to secure a file lock for file at: '.$cache_path); + fclose($fp); return; } + // If output compression is enabled, compress the cache + // itself, so that we don't have to do that each time + // we're serving it + if ($this->_compress_output === TRUE) + { + $output = gzencode($output); + + if ($this->get_header('content-type') === NULL) + { + $this->set_content_type($this->mime_type); + } + } + + $expire = time() + ($this->cache_expiration * 60); + + // Put together our serialized info. + $cache_info = serialize(array( + 'expire' => $expire, + 'headers' => $this->headers + )); + + $output = $cache_info.'ENDCI--->'.$output; + + for ($written = 0, $length = self::strlen($output); $written < $length; $written += $result) + { + if (($result = fwrite($fp, self::substr($output, $written))) === FALSE) + { + break; + } + } + + flock($fp, LOCK_UN); fclose($fp); - if (is_int($result)) - { - chmod($cache_path, 0640); - log_message('debug', 'Cache file written: '.$cache_path); - - // Send HTTP cache-control headers to browser to match file cache settings. - $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); - } - else + if ( ! is_int($result)) { @unlink($cache_path); log_message('error', 'Unable to write the complete cache content at: '.$cache_path); + return; } + + chmod($cache_path, 0640); + log_message('debug', 'Cache file written: '.$cache_path); + + // Send HTTP cache-control headers to browser to match file cache settings. + $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); } // -------------------------------------------------------------------- @@ -698,11 +705,9 @@ class CI_Output { log_message('debug', 'Cache file has expired. File deleted.'); return FALSE; } - else - { - // Or else send the HTTP cache control headers. - $this->set_cache_header($last_modified, $expire); - } + + // Send the HTTP cache control headers + $this->set_cache_header($last_modified, $expire); // Add headers from cache file. foreach ($cache_info['headers'] as $header) @@ -711,7 +716,7 @@ class CI_Output { } // Display the cache - $this->_display(substr($cache, strlen($match[0]))); + $this->_display(self::substr($cache, self::strlen($match[0]))); log_message('debug', 'Cache file is current. Sending it to browser.'); return TRUE; } @@ -788,13 +793,50 @@ class CI_Output { $this->set_status_header(304); exit; } - else - { - header('Pragma: public'); - header('Cache-Control: max-age='.$max_age.', public'); - header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); - header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); - } + + header('Pragma: public'); + header('Cache-Control: max-age='.$max_age.', public'); + header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); + header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); } + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_overload) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/system/core/Router.php b/system/core/Router.php index 045d366..7b92f70 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/core/Security.php b/system/core/Security.php index d5305d1..31926b4 100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -133,15 +133,18 @@ class CI_Security { * @var array */ protected $_never_allowed_str = array( - 'document.cookie' => '[removed]', - 'document.write' => '[removed]', - '.parentNode' => '[removed]', - '.innerHTML' => '[removed]', - '-moz-binding' => '[removed]', - '' => '-->', - ' '<![CDATA[', - '' => '<comment>' + 'document.cookie' => '[removed]', + '(document).cookie' => '[removed]', + 'document.write' => '[removed]', + '(document).write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[', + '' => '<comment>', + '<%' => '<%' ); /** @@ -151,7 +154,7 @@ class CI_Security { */ protected $_never_allowed_regex = array( 'javascript\s*:', - '(document|(document\.)?window)\.(location|on\w*)', + '(\(?document\)?|\(?window\)?(\.document)?)\.(location|on\w*)', 'expression\s*(\(|&\#40;)', // CSS and IE 'vbscript\s*:', // IE, surprise! 'wscript\s*:', // IE @@ -223,14 +226,11 @@ class CI_Security { } } - // Do the tokens exist in both the _POST and _COOKIE arrays? - if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) - OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match? - { - $this->csrf_show_error(); - } + // Check CSRF token validity, but don't error on mismatch just yet - we'll want to regenerate + $valid = isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) + && hash_equals($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]); - // We kill this since we're done and we don't want to polute the _POST array + // We kill this since we're done and we don't want to pollute the _POST array unset($_POST[$this->_csrf_token_name]); // Regenerate on every submission? @@ -244,6 +244,11 @@ class CI_Security { $this->_csrf_set_hash(); $this->csrf_set_cookie(); + if ($valid !== TRUE) + { + $this->csrf_show_error(); + } + log_message('info', 'CSRF token verified'); return $this; } @@ -351,9 +356,9 @@ class CI_Security { // Is the string an array? if (is_array($str)) { - while (list($key) = each($str)) + foreach ($str as $key => &$value) { - $str[$key] = $this->xss_clean($str[$key]); + $str[$key] = $this->xss_clean($value); } return $str; @@ -371,11 +376,17 @@ class CI_Security { * * Note: Use rawurldecode() so it does not remove plus signs */ - do + if (stripos($str, '%') !== false) { - $str = rawurldecode($str); + do + { + $oldstr = $str; + $str = rawurldecode($str); + $str = preg_replace_callback('#%(?:\s*[0-9a-f]){2,}#i', array($this, '_urldecodespaces'), $str); + } + while ($oldstr !== $str); + unset($oldstr); } - while (preg_match('/%[0-9a-f]{2,}/i', $str)); /* * Convert character entities to ASCII @@ -466,7 +477,7 @@ class CI_Security { if (preg_match('/]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); + $str = preg_replace_callback('#]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); } if (preg_match('//*\s*)(?[a-z0-9]+)(?=[^a-z0-9]|$)' // tag start and name, followed by a non-tag character + .'<((?/*\s*)((?[a-z0-9]+)(?=[^a-z0-9]|$)|.+)' // tag start and name, followed by a non-tag character .'[^\s\042\047a-z0-9>/=]*' // a valid attribute character immediately after the tag would count as a separator // optional attributes .'(?(?:[\s\042\047/=]*' // non-attribute characters, excluding > (tag close) for obvious reasons @@ -533,6 +544,14 @@ class CI_Security { $str ); + // Same thing, but for "tag functions" (e.g. eval`some code`) + // See https://github.com/bcit-ci/CodeIgniter/issues/5420 + $str = preg_replace( + '#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)`(.*?)`#si', + '\\1\\2`\\3`', + $str + ); + // Final clean up // This adds a bit of extra precaution in case // something got through the above filters @@ -669,6 +688,22 @@ class CI_Security { ? ENT_COMPAT | ENT_HTML5 : ENT_COMPAT; + if ( ! isset($_entities)) + { + $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flag, $charset)); + + // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 + // entities to the array manually + if ($flag === ENT_COMPAT) + { + $_entities[':'] = ':'; + $_entities['('] = '('; + $_entities[')'] = ')'; + $_entities["\n"] = ' '; + $_entities["\t"] = ' '; + } + } + do { $str_compare = $str; @@ -676,27 +711,6 @@ class CI_Security { // Decode standard entities, avoiding false positives if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) { - if ( ! isset($_entities)) - { - $_entities = array_map( - 'strtolower', - is_php('5.3.4') - ? get_html_translation_table(HTML_ENTITIES, $flag, $charset) - : get_html_translation_table(HTML_ENTITIES, $flag) - ); - - // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 - // entities to the array manually - if ($flag === ENT_COMPAT) - { - $_entities[':'] = ':'; - $_entities['('] = '('; - $_entities[')'] = ')'; - $_entities["\n"] = '&newline;'; - $_entities["\t"] = '&tab;'; - } - } - $replace = array(); $matches = array_unique(array_map('strtolower', $matches[0])); foreach ($matches as &$match) @@ -707,7 +721,7 @@ class CI_Security { } } - $str = str_ireplace(array_keys($replace), array_values($replace), $str); + $str = str_replace(array_keys($replace), array_values($replace), $str); } // Decode numeric & UTF16 two byte entities @@ -716,6 +730,11 @@ class CI_Security { $flag, $charset ); + + if ($flag === ENT_COMPAT) + { + $str = str_replace(array_values($_entities), array_keys($_entities), $str); + } } while ($str_compare !== $str); return $str; @@ -774,6 +793,24 @@ class CI_Security { // ---------------------------------------------------------------- + /** + * URL-decode taking spaces into account + * + * @see https://github.com/bcit-ci/CodeIgniter/issues/4877 + * @param array $matches + * @return string + */ + protected function _urldecodespaces($matches) + { + $input = $matches[0]; + $nospaces = preg_replace('#\s+#', '', $input); + return ($nospaces === $input) + ? $input + : rawurldecode($nospaces); + } + + // ---------------------------------------------------------------- + /** * Compact Exploded Words * @@ -803,7 +840,7 @@ class CI_Security { protected function _sanitize_naughty_html($matches) { static $naughty_tags = array( - 'alert', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound', + 'alert', 'area', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound', 'blink', 'body', 'embed', 'expression', 'form', 'frameset', 'frame', 'head', 'html', 'ilayer', 'iframe', 'input', 'button', 'select', 'isindex', 'layer', 'link', 'meta', 'keygen', 'object', 'plaintext', 'style', 'script', 'textarea', 'title', 'math', 'video', 'svg', 'xml', 'xss' @@ -826,7 +863,7 @@ class CI_Security { // For other tags, see if their attributes are "evil" and strip those elseif (isset($matches['attributes'])) { - // We'll store the already fitlered attributes here + // We'll store the already filtered attributes here $attributes = array(); // Attribute-catching pattern @@ -842,7 +879,7 @@ class CI_Security { // Each iteration filters a single attribute do { - // Strip any non-alpha characters that may preceed an attribute. + // Strip any non-alpha characters that may precede an attribute. // Browsers often parse these incorrectly and that has been a // of numerous XSS issues we've had. $matches['attributes'] = preg_replace('#^[^a-z]+#i', '', $matches['attributes']); @@ -900,7 +937,7 @@ class CI_Security { return str_replace( $match[1], preg_replace( - '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) ), @@ -928,7 +965,7 @@ class CI_Security { return str_replace( $match[1], preg_replace( - '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) ), diff --git a/system/core/URI.php b/system/core/URI.php index 544f6c8..574ade6 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/core/Utf8.php b/system/core/Utf8.php index f2f42e6..7e02177 100644 --- a/system/core/Utf8.php +++ b/system/core/Utf8.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 diff --git a/system/core/compat/hash.php b/system/core/compat/hash.php index 6854e4c..68a8129 100644 --- a/system/core/compat/hash.php +++ b/system/core/compat/hash.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -119,7 +119,7 @@ if ( ! function_exists('hash_pbkdf2')) */ function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = FALSE) { - if ( ! in_array($algo, hash_algos(), TRUE)) + if ( ! in_array(strtolower($algo), hash_algos(), TRUE)) { trigger_error('hash_pbkdf2(): Unknown hashing algorithm: '.$algo, E_USER_WARNING); return FALSE; @@ -173,7 +173,9 @@ if ( ! function_exists('hash_pbkdf2')) return FALSE; } - $hash_length = strlen(hash($algo, NULL, TRUE)); + $hash_length = defined('MB_OVERLOAD_STRING') + ? mb_strlen(hash($algo, NULL, TRUE), '8bit') + : strlen(hash($algo, NULL, TRUE)); empty($length) && $length = $hash_length; // Pre-hash password inputs longer than the algorithm's block size @@ -221,14 +223,14 @@ if ( ! function_exists('hash_pbkdf2')) 'whirlpool' => 64 ); - if (isset($block_sizes[$algo]) && strlen($password) > $block_sizes[$algo]) + if (isset($block_sizes[$algo], $password[$block_sizes[$algo]])) { $password = hash($algo, $password, TRUE); } $hash = ''; // Note: Blocks are NOT 0-indexed - for ($bc = ceil($length / $hash_length), $bi = 1; $bi <= $bc; $bi++) + for ($bc = (int) ceil($length / $hash_length), $bi = 1; $bi <= $bc; $bi++) { $key = $derived_key = hash_hmac($algo, $salt.pack('N', $bi), $password, TRUE); for ($i = 1; $i < $iterations; $i++) @@ -240,6 +242,13 @@ if ( ! function_exists('hash_pbkdf2')) } // This is not RFC-compatible, but we're aiming for natural PHP compatibility - return substr($raw_output ? $hash : bin2hex($hash), 0, $length); + if ( ! $raw_output) + { + $hash = bin2hex($hash); + } + + return defined('MB_OVERLOAD_STRING') + ? mb_substr($hash, 0, $length, '8bit') + : substr($hash, 0, $length); } } diff --git a/system/core/compat/mbstring.php b/system/core/compat/mbstring.php index 554d100..9f6c24e 100644 --- a/system/core/compat/mbstring.php +++ b/system/core/compat/mbstring.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -68,7 +68,7 @@ if ( ! function_exists('mb_strlen')) * @link http://php.net/mb_strlen * @param string $str * @param string $encoding - * @return string + * @return int */ function mb_strlen($str, $encoding = NULL) { diff --git a/system/core/compat/password.php b/system/core/compat/password.php index f0c22c7..89a77c4 100644 --- a/system/core/compat/password.php +++ b/system/core/compat/password.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); // ------------------------------------------------------------------------ -if (is_php('5.5') OR ! is_php('5.3.7') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1 OR defined('HHVM_VERSION')) +if (is_php('5.5') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1 OR defined('HHVM_VERSION')) { return; } @@ -94,8 +94,8 @@ if ( ! function_exists('password_hash')) */ function password_hash($password, $algo, array $options = array()) { - static $func_override; - isset($func_override) OR $func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); + static $func_overload; + isset($func_overload) OR $func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); if ($algo !== 1) { @@ -109,21 +109,29 @@ if ( ! function_exists('password_hash')) return NULL; } - if (isset($options['salt']) && ($saltlen = ($func_override ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))) < 22) + if (isset($options['salt']) && ($saltlen = ($func_overload ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))) < 22) { trigger_error('password_hash(): Provided salt is too short: '.$saltlen.' expecting 22', E_USER_WARNING); return NULL; } elseif ( ! isset($options['salt'])) { - if (defined('MCRYPT_DEV_URANDOM')) + if (function_exists('random_bytes')) + { + try + { + $options['salt'] = random_bytes(16); + } + catch (Exception $e) + { + log_message('error', 'compat/password: Error while trying to use random_bytes(): '.$e->getMessage()); + return FALSE; + } + } + elseif (defined('MCRYPT_DEV_URANDOM')) { $options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); } - elseif (function_exists('openssl_random_pseudo_bytes')) - { - $options['salt'] = openssl_random_pseudo_bytes(16); - } elseif (DIRECTORY_SEPARATOR === '/' && (is_readable($dev = '/dev/arandom') OR is_readable($dev = '/dev/urandom'))) { if (($fp = fopen($dev, 'rb')) === FALSE) @@ -136,7 +144,7 @@ if ( ! function_exists('password_hash')) is_php('5.4') && stream_set_chunk_size($fp, 16); $options['salt'] = ''; - for ($read = 0; $read < 16; $read = ($func_override) ? mb_strlen($options['salt'], '8bit') : strlen($options['salt'])) + for ($read = 0; $read < 16; $read = ($func_overload) ? mb_strlen($options['salt'], '8bit') : strlen($options['salt'])) { if (($read = fread($fp, 16 - $read)) === FALSE) { @@ -148,6 +156,16 @@ if ( ! function_exists('password_hash')) fclose($fp); } + elseif (function_exists('openssl_random_pseudo_bytes')) + { + $is_secure = NULL; + $options['salt'] = openssl_random_pseudo_bytes(16, $is_secure); + if ($is_secure !== TRUE) + { + log_message('error', 'compat/password: openssl_random_pseudo_bytes() set the $cryto_strong flag to FALSE'); + return FALSE; + } + } else { log_message('error', 'compat/password: No CSPRNG available.'); diff --git a/system/core/compat/standard.php b/system/core/compat/standard.php index 47d47ae..24f3abc 100644 --- a/system/core/compat/standard.php +++ b/system/core/compat/standard.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -62,7 +62,7 @@ if ( ! function_exists('array_column')) * array_column() * * @link http://php.net/array_column - * @param string $array + * @param array $array * @param mixed $column_key * @param mixed $index_key * @return array @@ -153,7 +153,7 @@ if ( ! function_exists('hex2bin')) */ function hex2bin($data) { - if (in_array($type = gettype($data), array('array', 'double', 'object'), TRUE)) + if (in_array($type = gettype($data), array('array', 'double', 'object', 'resource'), TRUE)) { if ($type === 'object' && method_exists($data, '__toString')) { @@ -180,210 +180,3 @@ if ( ! function_exists('hex2bin')) return pack('H*', $data); } } - -// ------------------------------------------------------------------------ - -if (is_php('5.3')) -{ - return; -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('array_replace')) -{ - /** - * array_replace() - * - * @link http://php.net/array_replace - * @return array - */ - function array_replace() - { - $arrays = func_get_args(); - - if (($c = count($arrays)) === 0) - { - trigger_error('array_replace() expects at least 1 parameter, 0 given', E_USER_WARNING); - return NULL; - } - elseif ($c === 1) - { - if ( ! is_array($arrays[0])) - { - trigger_error('array_replace(): Argument #1 is not an array', E_USER_WARNING); - return NULL; - } - - return $arrays[0]; - } - - $array = array_shift($arrays); - $c--; - - for ($i = 0; $i < $c; $i++) - { - if ( ! is_array($arrays[$i])) - { - trigger_error('array_replace(): Argument #'.($i + 2).' is not an array', E_USER_WARNING); - return NULL; - } - elseif (empty($arrays[$i])) - { - continue; - } - - foreach (array_keys($arrays[$i]) as $key) - { - $array[$key] = $arrays[$i][$key]; - } - } - - return $array; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('array_replace_recursive')) -{ - /** - * array_replace_recursive() - * - * @link http://php.net/array_replace_recursive - * @return array - */ - function array_replace_recursive() - { - $arrays = func_get_args(); - - if (($c = count($arrays)) === 0) - { - trigger_error('array_replace_recursive() expects at least 1 parameter, 0 given', E_USER_WARNING); - return NULL; - } - elseif ($c === 1) - { - if ( ! is_array($arrays[0])) - { - trigger_error('array_replace_recursive(): Argument #1 is not an array', E_USER_WARNING); - return NULL; - } - - return $arrays[0]; - } - - $array = array_shift($arrays); - $c--; - - for ($i = 0; $i < $c; $i++) - { - if ( ! is_array($arrays[$i])) - { - trigger_error('array_replace_recursive(): Argument #'.($i + 2).' is not an array', E_USER_WARNING); - return NULL; - } - elseif (empty($arrays[$i])) - { - continue; - } - - foreach (array_keys($arrays[$i]) as $key) - { - $array[$key] = (is_array($arrays[$i][$key]) && isset($array[$key]) && is_array($array[$key])) - ? array_replace_recursive($array[$key], $arrays[$i][$key]) - : $arrays[$i][$key]; - } - } - - return $array; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('quoted_printable_encode')) -{ - /** - * quoted_printable_encode() - * - * @link http://php.net/quoted_printable_encode - * @param string $str - * @return string - */ - function quoted_printable_encode($str) - { - if (strlen($str) === 0) - { - return ''; - } - elseif (in_array($type = gettype($str), array('array', 'object'), TRUE)) - { - if ($type === 'object' && method_exists($str, '__toString')) - { - $str = (string) $str; - } - else - { - trigger_error('quoted_printable_encode() expects parameter 1 to be string, '.$type.' given', E_USER_WARNING); - return NULL; - } - } - - if (function_exists('imap_8bit')) - { - return imap_8bit($str); - } - - $i = $lp = 0; - $output = ''; - $hex = '0123456789ABCDEF'; - $length = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')) - ? mb_strlen($str, '8bit') - : strlen($str); - - while ($length--) - { - if ((($c = $str[$i++]) === "\015") && isset($str[$i]) && ($str[$i] === "\012") && $length > 0) - { - $output .= "\015".$str[$i++]; - $length--; - $lp = 0; - continue; - } - - if ( - ctype_cntrl($c) - OR (ord($c) === 0x7f) - OR (ord($c) & 0x80) - OR ($c === '=') - OR ($c === ' ' && isset($str[$i]) && $str[$i] === "\015") - ) - { - if ( - (($lp += 3) > 75 && ord($c) <= 0x7f) - OR (ord($c) > 0x7f && ord($c) <= 0xdf && ($lp + 3) > 75) - OR (ord($c) > 0xdf && ord($c) <= 0xef && ($lp + 6) > 75) - OR (ord($c) > 0xef && ord($c) <= 0xf4 && ($lp + 9) > 75) - ) - { - $output .= "=\015\012"; - $lp = 3; - } - - $output .= '='.$hex[ord($c) >> 4].$hex[ord($c) & 0xf]; - continue; - } - - if ((++$lp) > 75) - { - $output .= "=\015\012"; - $lp = 1; - } - - $output .= $c; - } - - return $output; - } -} diff --git a/system/database/DB.php b/system/database/DB.php index b4b7767..f58c2e8 100644 --- a/system/database/DB.php +++ b/system/database/DB.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php index 8855cc1..56b7356 100644 --- a/system/database/DB_cache.php +++ b/system/database/DB_cache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -143,7 +143,7 @@ class CI_DB_Cache { $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2); $filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql); - if (FALSE === ($cachedata = @file_get_contents($filepath))) + if ( ! is_file($filepath) OR FALSE === ($cachedata = file_get_contents($filepath))) { return FALSE; } diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 848516a..f8956f0 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -916,6 +916,7 @@ abstract class CI_DB_driver { if ($this->_trans_begin()) { + $this->_trans_status = TRUE; $this->_trans_depth++; return TRUE; } @@ -980,7 +981,7 @@ abstract class CI_DB_driver { */ public function compile_binds($sql, $binds) { - if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) + if (empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) { return $sql; } @@ -1000,7 +1001,7 @@ abstract class CI_DB_driver { $ml = strlen($this->bind_marker); // Make sure not to replace a chunk inside a string that happens to match the bind marker - if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) + if ($c = preg_match_all("/'[^']*'|\"[^\"]*\"/i", $sql, $matches)) { $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', str_replace($matches[0], @@ -1044,7 +1045,7 @@ abstract class CI_DB_driver { */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', $sql); + return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX|MERGE)\s/i', $sql); } // -------------------------------------------------------------------- @@ -1173,14 +1174,14 @@ abstract class CI_DB_driver { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string */ protected function _escape_str($str) { - return str_replace("'", "''", remove_invisible_characters($str)); + return str_replace("'", "''", remove_invisible_characters($str, FALSE)); } // -------------------------------------------------------------------- @@ -1527,7 +1528,7 @@ abstract class CI_DB_driver { return 'UPDATE '.$table.' SET '.implode(', ', $valstr) .$this->_compile_wh('qb_where') .$this->_compile_order_by() - .($this->qb_limit ? ' LIMIT '.$this->qb_limit : ''); + .($this->qb_limit !== FALSE ? ' LIMIT '.$this->qb_limit : ''); } // -------------------------------------------------------------------- @@ -1925,15 +1926,19 @@ abstract class CI_DB_driver { $i++; } + // dbprefix may've already been applied, with or without the identifier escaped + $ec = '(?'.preg_quote(is_array($this->_escape_char) ? $this->_escape_char[0] : $this->_escape_char).')?'; + isset($ec[0]) && $ec .= '?'; // Just in case someone has disabled escaping by forcing an empty escape character + // Verify table prefix and replace if necessary - if ($this->swap_pre !== '' && strpos($parts[$i], $this->swap_pre) === 0) + if ($this->swap_pre !== '' && preg_match('#^'.$ec.preg_quote($this->swap_pre).'#', $parts[$i])) { - $parts[$i] = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $parts[$i]); + $parts[$i] = preg_replace('#^'.$ec.preg_quote($this->swap_pre).'(\S+?)#', '\\1'.$this->dbprefix.'\\2', $parts[$i]); } // We only add the table prefix if it does not already exist - elseif (strpos($parts[$i], $this->dbprefix) !== 0) + else { - $parts[$i] = $this->dbprefix.$parts[$i]; + preg_match('#^'.$ec.preg_quote($this->dbprefix).'#', $parts[$i]) OR $parts[$i] = $this->dbprefix.$parts[$i]; } // Put the parts back together diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php index 826aa1e..d3057dc 100644 --- a/system/database/DB_forge.php +++ b/system/database/DB_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -184,7 +184,7 @@ abstract class CI_DB_forge { { return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; } - elseif ( ! $this->db->query(sprintf($this->_create_database, $db_name, $this->db->char_set, $this->db->dbcollat))) + elseif ( ! $this->db->query(sprintf($this->_create_database, $this->db->escape_identifiers($db_name), $this->db->char_set, $this->db->dbcollat))) { return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; } @@ -211,7 +211,7 @@ abstract class CI_DB_forge { { return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; } - elseif ( ! $this->db->query(sprintf($this->_drop_database, $db_name))) + elseif ( ! $this->db->query(sprintf($this->_drop_database, $this->db->escape_identifiers($db_name)))) { return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; } @@ -348,7 +348,7 @@ abstract class CI_DB_forge { if (($result = $this->db->query($sql)) !== FALSE) { - empty($this->db->data_cache['table_names']) OR $this->db->data_cache['table_names'][] = $table; + isset($this->db->data_cache['table_names']) && $this->db->data_cache['table_names'][] = $table; // Most databases don't support creating indexes from within the CREATE TABLE statement if ( ! empty($this->keys)) @@ -382,10 +382,8 @@ abstract class CI_DB_forge { { return TRUE; } - else - { - $if_not_exists = FALSE; - } + + $if_not_exists = FALSE; } $sql = ($if_not_exists) @@ -488,7 +486,7 @@ abstract class CI_DB_forge { * * @param string $table Table name * @param bool $if_exists Whether to add an IF EXISTS condition - * @return string + * @return mixed (Returns a platform-specific DROP table string, or TRUE to indicate there's nothing to do) */ protected function _drop_table($table, $if_exists) { @@ -979,8 +977,8 @@ abstract class CI_DB_forge { /** * Process indexes * - * @param string $table - * @return string + * @param string $table Table name + * @return string[] list of SQL statements */ protected function _process_indexes($table) { diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index c862d93..3d0c329 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -149,6 +149,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver { */ protected $qb_set = array(); + /** + * QB data set for update_batch() + * + * @var array + */ + protected $qb_set_ub = array(); + /** * QB aliased tables list * @@ -207,6 +214,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver { */ protected $qb_cache_join = array(); + /** + * QB Cache aliased tables list + * + * @var array + */ + protected $qb_cache_aliased_tables = array(); + /** * QB Cache WHERE data * @@ -666,7 +680,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { if ($escape === TRUE) { - $v = ' '.$this->escape($v); + $v = $this->escape($v); } if ( ! $this->_has_operator($k)) @@ -679,15 +693,16 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // value appears not to have been set, assign the test to IS NULL $k .= ' IS NULL'; } - elseif (preg_match('/\s*(!?=|<>|IS(?:\s+NOT)?)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) + elseif (preg_match('/\s*(!?=|<>|\sIS(?:\s+NOT)?\s)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) { $k = substr($k, 0, $match[0][1]).($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL'); } - $this->{$qb_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape); + ${$qb_key} = array('condition' => $prefix.$k, 'value' => $v, 'escape' => $escape); + $this->{$qb_key}[] = ${$qb_key}; if ($this->qb_caching === TRUE) { - $this->{$qb_cache_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape); + $this->{$qb_cache_key}[] = ${$qb_key}; $this->qb_cache_exists[] = substr($qb_key, 3); } @@ -820,6 +835,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $where_in = array( 'condition' => $prefix.$key.$not.' IN('.implode(', ', $where_in).')', + 'value' => NULL, 'escape' => $escape ); @@ -948,33 +964,34 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $v = $this->escape_like_str($v); } - if ($side === 'none') + switch ($side) { - $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}'"; - } - elseif ($side === 'before') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}'"; - } - elseif ($side === 'after') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}%'"; - } - else - { - $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}%'"; + case 'none': + $v = "'{$v}'"; + break; + case 'before': + $v = "'%{$v}'"; + break; + case 'after': + $v = "'{$v}%'"; + break; + case 'both': + default: + $v = "'%{$v}%'"; + break; } // some platforms require an escape sequence definition for LIKE wildcards if ($escape === TRUE && $this->_like_escape_str !== '') { - $like_statement .= sprintf($this->_like_escape_str, $this->_like_escape_chr); + $v .= sprintf($this->_like_escape_str, $this->_like_escape_chr); } - $this->qb_where[] = array('condition' => $like_statement, 'escape' => $escape); + $qb_where = array('condition' => "{$prefix} {$k} {$not} LIKE {$v}", 'value' => NULL, 'escape' => $escape); + $this->qb_where[] = $qb_where; if ($this->qb_caching === TRUE) { - $this->qb_cache_where[] = array('condition' => $like_statement, 'escape' => $escape); + $this->qb_cache_where[] = $qb_where; $this->qb_cache_exists[] = 'where'; } } @@ -999,6 +1016,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type; $where = array( 'condition' => $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (', + 'value' => NULL, 'escape' => FALSE ); @@ -1059,6 +1077,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $this->qb_where_group_started = FALSE; $where = array( 'condition' => str_repeat(' ', $this->qb_where_group_count--).')', + 'value' => NULL, 'escape' => FALSE ); @@ -1271,7 +1290,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { */ protected function _limit($sql) { - return $sql.' LIMIT '.($this->qb_offset ? $this->qb_offset.', ' : '').$this->qb_limit; + return $sql.' LIMIT '.($this->qb_offset ? $this->qb_offset.', ' : '').(int) $this->qb_limit; } // -------------------------------------------------------------------- @@ -1389,13 +1408,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // ORDER BY usage is often problematic here (most notably // on Microsoft SQL Server) and ultimately unnecessary // for selecting COUNT(*) ... - if ( ! empty($this->qb_orderby)) - { - $orderby = $this->qb_orderby; - $this->qb_orderby = NULL; - } + $qb_orderby = $this->qb_orderby; + $qb_cache_orderby = $this->qb_cache_orderby; + $this->qb_orderby = $this->qb_cache_orderby = array(); - $result = ($this->qb_distinct === TRUE) + $result = ($this->qb_distinct === TRUE OR ! empty($this->qb_groupby) OR ! empty($this->qb_cache_groupby) OR $this->qb_limit OR $this->qb_offset) ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results") : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows'))); @@ -1403,10 +1420,10 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { $this->_reset_select(); } - // If we've previously reset the qb_orderby values, get them back - elseif ( ! isset($this->qb_orderby)) + else { - $this->qb_orderby = $orderby; + $this->qb_orderby = $qb_orderby; + $this->qb_cache_orderby = $qb_cache_orderby; } if ($result->num_rows() === 0) @@ -1421,7 +1438,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // -------------------------------------------------------------------- /** - * Get_Where + * get_where() * * Allows the where clause, limit and offset to be added directly * @@ -1498,8 +1515,10 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $affected_rows = 0; for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) { - $this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size))); - $affected_rows += $this->affected_rows(); + if ($this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size)))) + { + $affected_rows += $this->affected_rows(); + } } $this->_reset_write(); @@ -1544,7 +1563,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { is_bool($escape) OR $escape = $this->_protect_identifiers; - $keys = array_keys($this->_object_to_array(current($key))); + $keys = array_keys($this->_object_to_array(reset($key))); sort($keys); foreach ($key as $row) @@ -1884,7 +1903,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { if ($set === NULL) { - if (empty($this->qb_set)) + if (empty($this->qb_set_ub)) { return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; } @@ -1911,10 +1930,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // Batch this baby $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) + for ($i = 0, $total = count($this->qb_set_ub); $i < $total; $i += $batch_size) { - $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, $batch_size), $this->protect_identifiers($index))); - $affected_rows += $this->affected_rows(); + if ($this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set_ub, $i, $batch_size), $index))) + { + $affected_rows += $this->affected_rows(); + } + $this->qb_where = array(); } @@ -1939,13 +1961,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $ids = array(); foreach ($values as $key => $val) { - $ids[] = $val[$index]; + $ids[] = $val[$index]['value']; foreach (array_keys($val) as $field) { if ($field !== $index) { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; + $final[$val[$field]['field']][] = 'WHEN '.$val[$index]['field'].' = '.$val[$index]['value'].' THEN '.$val[$field]['value']; } } } @@ -1958,7 +1980,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { .'ELSE '.$k.' END, '; } - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); + $this->where($val[$index]['field'].' IN('.implode(',', $ids).')', NULL, FALSE); return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); } @@ -1995,7 +2017,10 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $index_set = TRUE; } - $clean[$this->protect_identifiers($k2, FALSE, $escape)] = ($escape === FALSE) ? $v2 : $this->escape($v2); + $clean[$k2] = array( + 'field' => $this->protect_identifiers($k2, FALSE, $escape), + 'value' => ($escape === FALSE ? $v2 : $this->escape($v2)) + ); } if ($index_set === FALSE) @@ -2003,7 +2028,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { return $this->display_error('db_batch_missing_index'); } - $this->qb_set[] = $clean; + $this->qb_set_ub[] = $clean; } return $this; @@ -2190,7 +2215,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { protected function _delete($table) { return 'DELETE FROM '.$table.$this->_compile_wh('qb_where') - .($this->qb_limit ? ' LIMIT '.$this->qb_limit : ''); + .($this->qb_limit !== FALSE ? ' LIMIT '.$this->qb_limit : ''); } // -------------------------------------------------------------------- @@ -2266,9 +2291,14 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $table = trim(strrchr($table, ' ')); // Store the alias, if it doesn't already exist - if ( ! in_array($table, $this->qb_aliased_tables)) + if ( ! in_array($table, $this->qb_aliased_tables, TRUE)) { $this->qb_aliased_tables[] = $table; + if ($this->qb_caching === TRUE && ! in_array($table, $this->qb_cache_aliased_tables, TRUE)) + { + $this->qb_cache_aliased_tables[] = $table; + $this->qb_cache_exists[] = 'aliased_tables'; + } } } } @@ -2335,7 +2365,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { .$this->_compile_order_by(); // ORDER BY // LIMIT - if ($this->qb_limit) + if ($this->qb_limit !== FALSE OR $this->qb_offset) { return $this->_limit($sql."\n"); } @@ -2370,7 +2400,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { } elseif ($this->{$qb_key}[$i]['escape'] === FALSE) { - $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition']; + $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'].(isset($this->{$qb_key}[$i]['value']) ? ' '.$this->{$qb_key}[$i]['value'] : ''); continue; } @@ -2409,7 +2439,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { .' '.trim($matches[3]).$matches[4].$matches[5]; } - $this->{$qb_key}[$i] = implode('', $conditions); + $this->{$qb_key}[$i] = implode('', $conditions).(isset($this->{$qb_key}[$i]['value']) ? ' '.$this->{$qb_key}[$i]['value'] : ''); } return ($qb_key === 'qb_having' ? "\nHAVING " : "\nWHERE ") @@ -2426,7 +2456,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * * Escapes identifiers in GROUP BY statements at execution time. * - * Required so that aliases are tracked properly, regardless of wether + * Required so that aliases are tracked properly, regardless of whether * group_by() is called prior to from(), join() and dbprefix is added * only if needed. * @@ -2462,7 +2492,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * * Escapes identifiers in ORDER BY statements at execution time. * - * Required so that aliases are tracked properly, regardless of wether + * Required so that aliases are tracked properly, regardless of whether * order_by() is called prior to from(), join() and dbprefix is added * only if needed. * @@ -2470,26 +2500,27 @@ abstract class CI_DB_query_builder extends CI_DB_driver { */ protected function _compile_order_by() { - if (is_array($this->qb_orderby) && count($this->qb_orderby) > 0) + if (empty($this->qb_orderby)) { - for ($i = 0, $c = count($this->qb_orderby); $i < $c; $i++) - { - if ($this->qb_orderby[$i]['escape'] !== FALSE && ! $this->_is_literal($this->qb_orderby[$i]['field'])) - { - $this->qb_orderby[$i]['field'] = $this->protect_identifiers($this->qb_orderby[$i]['field']); - } + return ''; + } - $this->qb_orderby[$i] = $this->qb_orderby[$i]['field'].$this->qb_orderby[$i]['direction']; + for ($i = 0, $c = count($this->qb_orderby); $i < $c; $i++) + { + if (is_string($this->qb_orderby[$i])) + { + continue; } - return $this->qb_orderby = "\nORDER BY ".implode(', ', $this->qb_orderby); - } - elseif (is_string($this->qb_orderby)) - { - return $this->qb_orderby; + if ($this->qb_orderby[$i]['escape'] !== FALSE && ! $this->_is_literal($this->qb_orderby[$i]['field'])) + { + $this->qb_orderby[$i]['field'] = $this->protect_identifiers($this->qb_orderby[$i]['field']); + } + + $this->qb_orderby[$i] = $this->qb_orderby[$i]['field'].$this->qb_orderby[$i]['direction']; } - return ''; + return "\nORDER BY ".implode(', ', $this->qb_orderby); } // -------------------------------------------------------------------- @@ -2610,7 +2641,8 @@ abstract class CI_DB_query_builder extends CI_DB_driver { 'qb_cache_orderby' => array(), 'qb_cache_set' => array(), 'qb_cache_exists' => array(), - 'qb_cache_no_escape' => array() + 'qb_cache_no_escape' => array(), + 'qb_cache_aliased_tables' => array() )); return $this; @@ -2661,13 +2693,6 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $this->qb_no_escape = $qb_no_escape; } } - - // If we are "protecting identifiers" we need to examine the "from" - // portion of the query to determine if there are any aliases - if ($this->_protect_identifiers === TRUE && count($this->qb_cache_from) > 0) - { - $this->_track_aliases($this->qb_from); - } } // -------------------------------------------------------------------- @@ -2770,6 +2795,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { $this->_reset_run(array( 'qb_set' => array(), + 'qb_set_ub' => array(), 'qb_from' => array(), 'qb_join' => array(), 'qb_where' => array(), diff --git a/system/database/DB_result.php b/system/database/DB_result.php index d9d1fcc..a5a4ca2 100644 --- a/system/database/DB_result.php +++ b/system/database/DB_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -163,10 +163,8 @@ class CI_DB_result { { return $this->result_object(); } - else - { - return $this->custom_result_object($type); - } + + return $this->custom_result_object($type); } // -------------------------------------------------------------------- @@ -336,7 +334,8 @@ class CI_DB_result { if ($type === 'object') return $this->row_object($n); elseif ($type === 'array') return $this->row_array($n); - else return $this->custom_row_object($n, $type); + + return $this->custom_row_object($n, $type); } // -------------------------------------------------------------------- @@ -660,7 +659,7 @@ class CI_DB_result { */ protected function _fetch_object($class_name = 'stdClass') { - return array(); + return new $class_name(); } } diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php index 7052828..8680176 100644 --- a/system/database/DB_utility.php +++ b/system/database/DB_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php index 77f591c..9d6afea 100644 --- a/system/database/drivers/cubrid/cubrid_driver.php +++ b/system/database/drivers/cubrid/cubrid_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 @@ -250,7 +250,7 @@ class CI_DB_cubrid_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string @@ -361,7 +361,7 @@ class CI_DB_cubrid_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php index 8262beb..95e7ca1 100644 --- a/system/database/drivers/cubrid/cubrid_forge.php +++ b/system/database/drivers/cubrid/cubrid_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 @@ -178,6 +178,9 @@ class CI_DB_cubrid_forge extends CI_DB_forge { $attributes['TYPE'] = 'INTEGER'; $attributes['UNSIGNED'] = FALSE; return; + case 'LONGTEXT': + $attributes['TYPE'] = 'STRING'; + return; default: return; } } diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php index 9cccb25..a71b1a2 100644 --- a/system/database/drivers/cubrid/cubrid_result.php +++ b/system/database/drivers/cubrid/cubrid_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php index 942fa3b..eb906ae 100644 --- a/system/database/drivers/cubrid/cubrid_utility.php +++ b/system/database/drivers/cubrid/cubrid_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php index c1055c1..fd866ff 100644 --- a/system/database/drivers/ibase/ibase_driver.php +++ b/system/database/drivers/ibase/ibase_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -294,7 +294,7 @@ class CI_DB_ibase_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ @@ -383,6 +383,23 @@ class CI_DB_ibase_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * Insert batch statement + * + * Generates a platform-specific insert string from the supplied data. + * + * @param string $table Table name + * @param array $keys INSERT keys + * @param array $values INSERT values + * @return string|bool + */ + protected function _insert_batch($table, $keys, $values) + { + return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; + } + + // -------------------------------------------------------------------- + /** * Close DB Connection * diff --git a/system/database/drivers/ibase/ibase_forge.php b/system/database/drivers/ibase/ibase_forge.php index 9c358c3..77aa4ae 100644 --- a/system/database/drivers/ibase/ibase_forge.php +++ b/system/database/drivers/ibase/ibase_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -91,7 +91,7 @@ class CI_DB_ibase_forge extends CI_DB_forge { * Create database * * @param string $db_name - * @return string + * @return bool */ public function create_database($db_name) { @@ -111,7 +111,7 @@ class CI_DB_ibase_forge extends CI_DB_forge { * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { if ( ! ibase_drop_db($this->conn_id)) { diff --git a/system/database/drivers/ibase/ibase_result.php b/system/database/drivers/ibase/ibase_result.php index f3c21fc..b548f32 100644 --- a/system/database/drivers/ibase/ibase_result.php +++ b/system/database/drivers/ibase/ibase_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/ibase/ibase_utility.php b/system/database/drivers/ibase/ibase_utility.php index 619ebad..a1e5d69 100644 --- a/system/database/drivers/ibase/ibase_utility.php +++ b/system/database/drivers/ibase/ibase_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php index d40d67a..b2b17d0 100644 --- a/system/database/drivers/mssql/mssql_driver.php +++ b/system/database/drivers/mssql/mssql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -158,6 +158,7 @@ class CI_DB_mssql_driver extends CI_DB { if (mssql_select_db('['.$database.']', $this->conn_id)) { $this->database = $database; + $this->data_cache = array(); return TRUE; } @@ -351,7 +352,7 @@ class CI_DB_mssql_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ @@ -452,7 +453,7 @@ class CI_DB_mssql_driver extends CI_DB { $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results - if (count($this->qb_select) === 0) + if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE) { $select = '*'; // Inevitable } @@ -499,7 +500,7 @@ class CI_DB_mssql_driver extends CI_DB { return parent::_insert_batch($table, $keys, $values); } - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; + return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php index 24d1fc2..9a3e3eb 100644 --- a/system/database/drivers/mssql/mssql_forge.php +++ b/system/database/drivers/mssql/mssql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -113,6 +113,11 @@ class CI_DB_mssql_forge extends CI_DB_forge { */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php index b62bf75..8e1f416 100644 --- a/system/database/drivers/mssql/mssql_result.php +++ b/system/database/drivers/mssql/mssql_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php index cd23be8..90b7107 100644 --- a/system/database/drivers/mssql/mssql_utility.php +++ b/system/database/drivers/mssql/mssql_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php index 78b1d70..05a3283 100644 --- a/system/database/drivers/mysql/mysql_driver.php +++ b/system/database/drivers/mysql/mysql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -208,6 +208,7 @@ class CI_DB_mysql_driver extends CI_DB { if (mysql_select_db($database, $this->conn_id)) { $this->database = $database; + $this->data_cache = array(); return TRUE; } @@ -336,7 +337,7 @@ class CI_DB_mysql_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string @@ -447,7 +448,7 @@ class CI_DB_mysql_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php index fa84be3..f8a998b 100644 --- a/system/database/drivers/mysql/mysql_forge.php +++ b/system/database/drivers/mysql/mysql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php index 20cade2..07d5187 100644 --- a/system/database/drivers/mysql/mysql_result.php +++ b/system/database/drivers/mysql/mysql_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php index 4c1f239..ae3c26c 100644 --- a/system/database/drivers/mysql/mysql_utility.php +++ b/system/database/drivers/mysql/mysql_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index 06c3418..7cec29e 100644 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -125,8 +125,7 @@ class CI_DB_mysqli_driver extends CI_DB { } else { - // Persistent connection support was added in PHP 5.3.0 - $hostname = ($persistent === TRUE && is_php('5.3')) + $hostname = ($persistent === TRUE) ? 'p:'.$this->hostname : $this->hostname; $port = empty($this->port) ? NULL : $this->port; $socket = NULL; @@ -184,7 +183,7 @@ class CI_DB_mysqli_driver extends CI_DB { // https://bugs.php.net/bug.php?id=68344 elseif (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')) { - $this->_mysqli->options(MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT, TRUE); + $client_flags |= MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT; } } @@ -211,7 +210,7 @@ class CI_DB_mysqli_driver extends CI_DB { $this->_mysqli->close(); $message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!'; log_message('error', $message); - return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; + return ($this->db_debug) ? $this->display_error($message, '', TRUE) : FALSE; } return $this->_mysqli; @@ -256,6 +255,7 @@ class CI_DB_mysqli_driver extends CI_DB { if ($this->conn_id->select_db($database)) { $this->database = $database; + $this->data_cache = array(); return TRUE; } @@ -381,7 +381,7 @@ class CI_DB_mysqli_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string @@ -501,8 +501,8 @@ class CI_DB_mysqli_driver extends CI_DB { if ( ! empty($this->_mysqli->connect_errno)) { return array( - 'code' => $this->_mysqli->connect_errno, - 'message' => is_php('5.2.9') ? $this->_mysqli->connect_error : mysqli_connect_error() + 'code' => $this->_mysqli->connect_errno, + 'message' => $this->_mysqli->connect_error ); } diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php index c17f729..dd77edc 100644 --- a/system/database/drivers/mysqli/mysqli_forge.php +++ b/system/database/drivers/mysqli/mysqli_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php index 0ce0741..bac0737 100644 --- a/system/database/drivers/mysqli/mysqli_result.php +++ b/system/database/drivers/mysqli/mysqli_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -112,9 +112,9 @@ class CI_DB_mysqli_result extends CI_DB_result { { $retval[$i] = new stdClass(); $retval[$i]->name = $field_data[$i]->name; - $retval[$i]->type = $field_data[$i]->type; + $retval[$i]->type = static::_get_field_type($field_data[$i]->type); $retval[$i]->max_length = $field_data[$i]->max_length; - $retval[$i]->primary_key = (int) ($field_data[$i]->flags & 2); + $retval[$i]->primary_key = (int) ($field_data[$i]->flags & MYSQLI_PRI_KEY_FLAG); $retval[$i]->default = $field_data[$i]->def; } @@ -123,6 +123,52 @@ class CI_DB_mysqli_result extends CI_DB_result { // -------------------------------------------------------------------- + /** + * Get field type + * + * Extracts field type info from the bitflags returned by + * mysqli_result::fetch_fields() + * + * @used-by CI_DB_mysqli_result::field_data() + * @param int $type + * @return string + */ + private static function _get_field_type($type) + { + static $map; + isset($map) OR $map = array( + MYSQLI_TYPE_DECIMAL => 'decimal', + MYSQLI_TYPE_BIT => 'bit', + MYSQLI_TYPE_TINY => 'tinyint', + MYSQLI_TYPE_SHORT => 'smallint', + MYSQLI_TYPE_INT24 => 'mediumint', + MYSQLI_TYPE_LONG => 'int', + MYSQLI_TYPE_LONGLONG => 'bigint', + MYSQLI_TYPE_FLOAT => 'float', + MYSQLI_TYPE_DOUBLE => 'double', + MYSQLI_TYPE_TIMESTAMP => 'timestamp', + MYSQLI_TYPE_DATE => 'date', + MYSQLI_TYPE_TIME => 'time', + MYSQLI_TYPE_DATETIME => 'datetime', + MYSQLI_TYPE_YEAR => 'year', + MYSQLI_TYPE_NEWDATE => 'date', + MYSQLI_TYPE_INTERVAL => 'interval', + MYSQLI_TYPE_ENUM => 'enum', + MYSQLI_TYPE_SET => 'set', + MYSQLI_TYPE_TINY_BLOB => 'tinyblob', + MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob', + MYSQLI_TYPE_BLOB => 'blob', + MYSQLI_TYPE_LONG_BLOB => 'longblob', + MYSQLI_TYPE_STRING => 'char', + MYSQLI_TYPE_VAR_STRING => 'varchar', + MYSQLI_TYPE_GEOMETRY => 'geometry' + ); + + return isset($map[$type]) ? $map[$type] : $type; + } + + // -------------------------------------------------------------------- + /** * Free the result * diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php index 79d9f36..332da60 100644 --- a/system/database/drivers/mysqli/mysqli_utility.php +++ b/system/database/drivers/mysqli/mysqli_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -155,9 +155,7 @@ class CI_DB_mysqli_utility extends CI_DB_utility { while ($field = $query->result_id->fetch_field()) { // Most versions of MySQL store timestamp as a string - $is_int[$i] = in_array(strtolower($field->type), - array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), - TRUE); + $is_int[$i] = in_array($field->type, array(MYSQLI_TYPE_TINY, MYSQLI_TYPE_SHORT, MYSQLI_TYPE_INT24, MYSQLI_TYPE_LONG), TRUE); // Create a string of field names $field_str .= $this->db->escape_identifiers($field->name).', '; diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php index 59f0e84..b90db4b 100644 --- a/system/database/drivers/oci8/oci8_driver.php +++ b/system/database/drivers/oci8/oci8_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.4.1 @@ -97,7 +97,7 @@ class CI_DB_oci8_driver extends CI_DB { * * @var bool */ - public $limit_used; + public $limit_used = FALSE; // -------------------------------------------------------------------- @@ -386,7 +386,7 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _trans_begin() { - $this->commit_mode = is_php('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT; + $this->commit_mode = OCI_NO_AUTO_COMMIT; return TRUE; } @@ -553,29 +553,35 @@ class CI_DB_oci8_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ public function error() { - /* oci_error() returns an array that already contains the - * 'code' and 'message' keys, so we can just return it. - */ + // oci_error() returns an array that already contains + // 'code' and 'message' keys, but it can return false + // if there was no error .... if (is_resource($this->curs_id)) { - return oci_error($this->curs_id); + $error = oci_error($this->curs_id); } elseif (is_resource($this->stmt_id)) { - return oci_error($this->stmt_id); + $error = oci_error($this->stmt_id); } elseif (is_resource($this->conn_id)) { - return oci_error($this->conn_id); + $error = oci_error($this->conn_id); + } + else + { + $error = oci_error(); } - return oci_error(); + return is_array($error) + ? $error + : array('code' => '', 'message' => ''); } // -------------------------------------------------------------------- @@ -679,4 +685,17 @@ class CI_DB_oci8_driver extends CI_DB { oci_close($this->conn_id); } + // -------------------------------------------------------------------- + + /** + * We need to reset our $limit_used hack flag, so it doesn't propagate + * to subsequent queries. + * + * @return void + */ + protected function _reset_select() + { + $this->limit_used = FALSE; + parent::_reset_select(); + } } diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php index 1ca559a..0011bb0 100644 --- a/system/database/drivers/oci8/oci8_forge.php +++ b/system/database/drivers/oci8/oci8_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.4.1 @@ -53,6 +53,13 @@ class CI_DB_oci8_forge extends CI_DB_forge { */ protected $_create_database = FALSE; + /** + * CREATE TABLE IF statement + * + * @var string + */ + protected $_create_table_if = FALSE; + /** * DROP DATABASE statement * @@ -117,8 +124,10 @@ class CI_DB_oci8_forge extends CI_DB_forge { if ($alter_type === 'MODIFY' && ! empty($field[$i]['new_name'])) { $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' '.$this->db->escape_identifiers($field[$i]['new_name']); + .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); } + + $field[$i] = "\n\t".$field[$i]['_literal']; } } @@ -129,7 +138,7 @@ class CI_DB_oci8_forge extends CI_DB_forge { // RENAME COLUMN must be executed after MODIFY array_unshift($sqls, $sql); - return $sql; + return $sqls; } // -------------------------------------------------------------------- @@ -146,4 +155,33 @@ class CI_DB_oci8_forge extends CI_DB_forge { // Not supported - sequences and triggers must be used instead } + // -------------------------------------------------------------------- + + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * @return void + */ + protected function _attr_type(&$attributes) + { + switch (strtoupper($attributes['TYPE'])) + { + case 'TINYINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'MEDIUMINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'INT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'BIGINT': + $attributes['TYPE'] = 'NUMBER'; + return; + default: return; + } + } } diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php index fc860ea..1c4196f 100644 --- a/system/database/drivers/oci8/oci8_result.php +++ b/system/database/drivers/oci8/oci8_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.4.1 diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php index ebe49c4..574ff68 100644 --- a/system/database/drivers/oci8/oci8_utility.php +++ b/system/database/drivers/oci8/oci8_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.4.1 diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php index 19b7b74..c853903 100644 --- a/system/database/drivers/odbc/odbc_driver.php +++ b/system/database/drivers/odbc/odbc_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @author EllisLab Dev Team * @link https://codeigniter.com/user_guide/database/ */ -class CI_DB_odbc_driver extends CI_DB { +class CI_DB_odbc_driver extends CI_DB_driver { /** * Database driver @@ -93,6 +93,22 @@ class CI_DB_odbc_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * ODBC result ID resource returned from odbc_prepare() + * + * @var resource + */ + private $odbc_result; + + /** + * Values to use with odbc_execute() for prepared statements + * + * @var array + */ + private $binds = array(); + + // -------------------------------------------------------------------- + /** * Class constructor * @@ -127,6 +143,74 @@ class CI_DB_odbc_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * Compile Bindings + * + * @param string $sql SQL statement + * @param array $binds An array of values to bind + * @return string + */ + public function compile_binds($sql, $binds) + { + if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) + { + return $sql; + } + elseif ( ! is_array($binds)) + { + $binds = array($binds); + $bind_count = 1; + } + else + { + // Make sure we're using numeric keys + $binds = array_values($binds); + $bind_count = count($binds); + } + + // We'll need the marker length later + $ml = strlen($this->bind_marker); + + // Make sure not to replace a chunk inside a string that happens to match the bind marker + if ($c = preg_match_all("/'[^']*'|\"[^\"]*\"/i", $sql, $matches)) + { + $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', + str_replace($matches[0], + str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]), + $sql, $c), + $matches, PREG_OFFSET_CAPTURE); + + // Bind values' count must match the count of markers in the query + if ($bind_count !== $c) + { + return $sql; + } + } + elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) + { + return $sql; + } + + if ($this->bind_marker !== '?') + { + do + { + $c--; + $sql = substr_replace($sql, '?', $matches[0][$c][1], $ml); + } + while ($c !== 0); + } + + if (FALSE !== ($this->odbc_result = odbc_prepare($this->conn_id, $sql))) + { + $this->binds = array_values($binds); + } + + return $sql; + } + + // -------------------------------------------------------------------- + /** * Execute the query * @@ -135,7 +219,25 @@ class CI_DB_odbc_driver extends CI_DB { */ protected function _execute($sql) { - return odbc_exec($this->conn_id, $sql); + if ( ! isset($this->odbc_result)) + { + return odbc_exec($this->conn_id, $sql); + } + elseif ($this->odbc_result === FALSE) + { + return FALSE; + } + + if (TRUE === ($success = odbc_execute($this->odbc_result, $this->binds))) + { + // For queries that return result sets, return the result_id resource on success + $this->is_write_type($sql) OR $success = $this->odbc_result; + } + + $this->odbc_result = NULL; + $this->binds = array(); + + return $success; } // -------------------------------------------------------------------- @@ -196,7 +298,7 @@ class CI_DB_odbc_driver extends CI_DB { */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -207,14 +309,14 @@ class CI_DB_odbc_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string */ protected function _escape_str($str) { - return remove_invisible_characters($str); + $this->display_error('db_unsupported_feature'); } // -------------------------------------------------------------------- @@ -238,7 +340,7 @@ class CI_DB_odbc_driver extends CI_DB { */ public function insert_id() { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; + return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; } // -------------------------------------------------------------------- @@ -300,7 +402,7 @@ class CI_DB_odbc_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ @@ -311,58 +413,6 @@ class CI_DB_odbc_driver extends CI_DB { // -------------------------------------------------------------------- - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - /** * Close DB Connection * @@ -372,5 +422,4 @@ class CI_DB_odbc_driver extends CI_DB { { odbc_close($this->conn_id); } - } diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php index bac30be..761e81f 100644 --- a/system/database/drivers/odbc/odbc_forge.php +++ b/system/database/drivers/odbc/odbc_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php index 110d6ab..f7c3aec 100644 --- a/system/database/drivers/odbc/odbc_result.php +++ b/system/database/drivers/odbc/odbc_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php index 2e34496..2a33428 100644 --- a/system/database/drivers/odbc/odbc_utility.php +++ b/system/database/drivers/odbc/odbc_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php index c6f84e0..c99bb06 100644 --- a/system/database/drivers/pdo/pdo_driver.php +++ b/system/database/drivers/pdo/pdo_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 @@ -126,7 +126,10 @@ class CI_DB_pdo_driver extends CI_DB { */ public function db_connect($persistent = FALSE) { - $this->options[PDO::ATTR_PERSISTENT] = $persistent; + if ($persistent === TRUE) + { + $this->options[PDO::ATTR_PERSISTENT] = TRUE; + } try { @@ -220,7 +223,7 @@ class CI_DB_pdo_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string @@ -282,7 +285,7 @@ class CI_DB_pdo_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ @@ -307,52 +310,6 @@ class CI_DB_pdo_driver extends CI_DB { // -------------------------------------------------------------------- - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = CASE '."\n"; - - foreach ($v as $row) - { - $cases .= $row."\n"; - } - - $cases .= 'ELSE '.$k.' END, '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - /** * Truncate statement * diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php index 2595f7b..c77a849 100644 --- a/system/database/drivers/pdo/pdo_forge.php +++ b/system/database/drivers/pdo/pdo_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php index d1809be..3a821fb 100644 --- a/system/database/drivers/pdo/pdo_result.php +++ b/system/database/drivers/pdo/pdo_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php index 384661b..9091ea5 100644 --- a/system/database/drivers/pdo/pdo_utility.php +++ b/system/database/drivers/pdo/pdo_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php index 3dedfd9..bbb675d 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php index 41994f9..7135aa1 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php index 8377798..3189aab 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -170,47 +170,6 @@ class CI_DB_pdo_cubrid_driver extends CI_DB_pdo_driver { // -------------------------------------------------------------------- - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k." = CASE \n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - /** * Truncate statement * diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php index 5f85406..624ce51 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -178,6 +178,9 @@ class CI_DB_pdo_cubrid_forge extends CI_DB_pdo_forge { $attributes['TYPE'] = 'INTEGER'; $attributes['UNSIGNED'] = FALSE; return; + case 'LONGTEXT': + $attributes['TYPE'] = 'STRING'; + return; default: return; } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php index 84695ee..d04f8b3 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -126,7 +126,12 @@ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver { */ public function db_connect($persistent = FALSE) { - $this->conn_id = parent::db_connect($persistent); + if ($persistent === TRUE) + { + log_message('debug', "dblib driver doesn't support persistent connections"); + } + + $this->conn_id = parent::db_connect(FALSE); if ( ! is_object($this->conn_id)) { @@ -279,7 +284,7 @@ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver { $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results - if (count($this->qb_select) === 0) + if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE) { $select = '*'; // Inevitable } @@ -326,7 +331,23 @@ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver { return parent::_insert_batch($table, $keys, $values); } - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; + return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; } + // -------------------------------------------------------------------- + + /** + * Database version number + * + * @return string + */ + public function version() + { + if (isset($this->data_cache['version'])) + { + return $this->data_cache['version']; + } + + return $this->data_cache['version'] = $this->conn_id->query("SELECT SERVERPROPERTY('ProductVersion') AS ver")->fetchColumn(0); + } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php index d5dd9aa..0216b59 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -111,6 +111,11 @@ class CI_DB_pdo_dblib_forge extends CI_DB_pdo_forge { */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php index 96dcc5e..eec5bf2 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -260,4 +260,20 @@ class CI_DB_pdo_firebird_driver extends CI_DB_pdo_driver { return preg_replace('`SELECT`i', 'SELECT '.$select, $sql); } + // -------------------------------------------------------------------- + + /** + * Insert batch statement + * + * Generates a platform-specific insert string from the supplied data. + * + * @param string $table Table name + * @param array $keys INSERT keys + * @param array $values INSERT values + * @return string|bool + */ + protected function _insert_batch($table, $keys, $values) + { + return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; + } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php index 256fa14..2a5fa64 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -97,7 +97,7 @@ class CI_DB_pdo_firebird_forge extends CI_DB_pdo_forge { * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { if ( ! ibase_drop_db($this->conn_id)) { diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php index 2366c40..43400a4 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php index a2dbfc2..f1bd2c3 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php index d40d17a..e44dcb8 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php index 5af39b1..e4202c2 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php index 70f2bfd..e172145 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -106,7 +106,7 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { empty($this->database) OR $this->dsn .= ';dbname='.$this->database; empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE && is_php('5.3.6')) + elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE) { $this->dsn .= ';charset='.$this->char_set; } @@ -122,17 +122,6 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { */ public function db_connect($persistent = FALSE) { - /* Prior to PHP 5.3.6, even if the charset was supplied in the DSN - * on connect - it was ignored. This is a work-around for the issue. - * - * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php - */ - if ( ! is_php('5.3.6') && ! empty($this->char_set)) - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set - .(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat); - } - if (isset($this->stricton)) { if ($this->stricton) @@ -169,8 +158,7 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { $this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE; } - // SSL support was added to PDO_MYSQL in PHP 5.3.7 - if (is_array($this->encrypt) && is_php('5.3.7')) + if (is_array($this->encrypt)) { $ssl = array(); empty($this->encrypt['ssl_key']) OR $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key']; @@ -194,7 +182,7 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { { $message = 'PDO_MYSQL was configured for an SSL connection, but got an unencrypted connection instead!'; log_message('error', $message); - return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; + return ($this->db_debug) ? $this->display_error($message, '', TRUE) : FALSE; } return $pdo; @@ -218,6 +206,56 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { if (FALSE !== $this->simple_query('USE '.$this->escape_identifiers($database))) { $this->database = $database; + $this->data_cache = array(); + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return bool + */ + protected function _trans_begin() + { + $this->conn_id->setAttribute(PDO::ATTR_AUTOCOMMIT, FALSE); + return $this->conn_id->beginTransaction(); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return bool + */ + protected function _trans_commit() + { + if ($this->conn_id->commit()) + { + $this->conn_id->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return bool + */ + protected function _trans_rollback() + { + if ($this->conn_id->rollBack()) + { + $this->conn_id->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); return TRUE; } diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php index 9d04a8a..629e0a9 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php index dd1d31c..fef7a9a 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php index d0b7be8..ad26561 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -53,6 +53,13 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { */ protected $_create_database = FALSE; + /** + * CREATE TABLE IF statement + * + * @var string + */ + protected $_create_table_if = FALSE; + /** * DROP DATABASE statement * @@ -60,13 +67,6 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { */ protected $_drop_database = FALSE; - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - /** * UNSIGNED support * @@ -117,7 +117,7 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { if ($alter_type === 'MODIFY' && ! empty($field[$i]['new_name'])) { $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' '.$this->db->escape_identifiers($field[$i]['new_name']); + .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); } } } @@ -146,4 +146,31 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { // Not supported - sequences and triggers must be used instead } + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * @return void + */ + protected function _attr_type(&$attributes) + { + switch (strtoupper($attributes['TYPE'])) + { + case 'TINYINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'MEDIUMINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'INT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'BIGINT': + $attributes['TYPE'] = 'NUMBER'; + return; + default: return; + } + } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php index 3334488..4890988 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -160,6 +160,19 @@ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver { // -------------------------------------------------------------------- + /** + * Platform-dependent string escape + * + * @param string + * @return string + */ + protected function _escape_str($str) + { + $this->display_error('db_unsupported_feature'); + } + + // -------------------------------------------------------------------- + /** * Determines if a query is a "write" type. * @@ -168,7 +181,7 @@ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver { */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -213,72 +226,4 @@ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver { { return 'SELECT column_name FROM information_schema.columns WHERE table_name = '.$this->escape($table); } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string the table name - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$this->qb_limit.' ', $sql); - } - } diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php index 7c65daa..02b6a2a 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php index ee8f763..33c8f1e 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -154,7 +154,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -326,13 +326,13 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { $ids = array(); foreach ($values as $key => $val) { - $ids[] = $val[$index]; + $ids[] = $val[$index]['value']; foreach (array_keys($val) as $field) { if ($field !== $index) { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; + $final[$val[$field]['field']][] = 'WHEN '.$val[$index]['value'].' THEN '.$val[$field]['value']; } } } @@ -340,12 +340,12 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { $cases = ''; foreach ($final as $k => $v) { - $cases .= $k.' = (CASE '.$index."\n" + $cases .= $k.' = (CASE '.$val[$index]['field']."\n" .implode("\n", $v)."\n" .'ELSE '.$k.' END), '; } - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); + $this->where($val[$index]['field'].' IN('.implode(',', $ids).')', NULL, FALSE); return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); } diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php index 214b6f5..e5bfee6 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -168,7 +168,7 @@ class CI_DB_pdo_pgsql_forge extends CI_DB_pdo_forge { */ protected function _attr_type(&$attributes) { - // Reset field lenghts for data types that don't support it + // Reset field lengths for data types that don't support it if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== FALSE) { $attributes['CONSTRAINT'] = NULL; diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php index 6269013..93871a9 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -66,7 +66,7 @@ class CI_DB_pdo_sqlite_driver extends CI_DB_pdo_driver { * * @var array */ - protected $_random_keyword = ' RANDOM()'; + protected $_random_keyword = array('RANDOM()', 'RANDOM()'); // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php index f6f9bb4..67fe6ee 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -101,7 +101,7 @@ class CI_DB_pdo_sqlite_forge extends CI_DB_pdo_forge { * @param string $db_name (ignored) * @return bool */ - public function create_database($db_name = '') + public function create_database($db_name) { // In SQLite, a database is created when you connect to the database. // We'll return TRUE so that an error isn't generated @@ -116,7 +116,7 @@ class CI_DB_pdo_sqlite_forge extends CI_DB_pdo_forge { * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { // In SQLite, a database is dropped when we delete a file if (file_exists($this->db->database)) diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php index dfccb7d..db10029 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -316,7 +316,7 @@ class CI_DB_pdo_sqlsrv_driver extends CI_DB_pdo_driver { $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results - if (count($this->qb_select) === 0) + if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE) { $select = '*'; // Inevitable } @@ -363,7 +363,7 @@ class CI_DB_pdo_sqlsrv_driver extends CI_DB_pdo_driver { return parent::_insert_batch($table, $keys, $values); } - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; + return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php index 602f895..4c9dbe6 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -111,6 +111,11 @@ class CI_DB_pdo_sqlsrv_forge extends CI_DB_pdo_forge { */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index 58d4451..5779c87 100644 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -130,9 +130,9 @@ class CI_DB_postgre_driver extends CI_DB { */ foreach (array('connect_timeout', 'options', 'sslmode', 'service') as $key) { - if (isset($this->$key) && is_string($this->key) && $this->key !== '') + if (isset($this->$key) && is_string($this->$key) && $this->$key !== '') { - $this->dsn .= $key."='".$this->key."' "; + $this->dsn .= $key."='".$this->$key."' "; } } @@ -224,8 +224,8 @@ class CI_DB_postgre_driver extends CI_DB { * and so we'll have to fall back to running a query in * order to get it. */ - return isset($pg_version['server']) - ? $this->data_cache['version'] = $pg_version['server'] + return (isset($pg_version['server']) && preg_match('#^(\d+\.\d+)#', $pg_version['server'], $match)) + ? $this->data_cache['version'] = $match[1] : parent::version(); } @@ -288,7 +288,7 @@ class CI_DB_postgre_driver extends CI_DB { */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -299,7 +299,7 @@ class CI_DB_postgre_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string @@ -354,8 +354,7 @@ class CI_DB_postgre_driver extends CI_DB { */ public function insert_id() { - $v = pg_version($this->conn_id); - $v = isset($v['server']) ? $v['server'] : 0; // 'server' key is only available since PosgreSQL 7.4 + $v = $this->version(); $table = (func_num_args() > 0) ? func_get_arg(0) : NULL; $column = (func_num_args() > 1) ? func_get_arg(1) : NULL; @@ -471,7 +470,7 @@ class CI_DB_postgre_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ @@ -550,13 +549,13 @@ class CI_DB_postgre_driver extends CI_DB { $ids = array(); foreach ($values as $key => $val) { - $ids[] = $val[$index]; + $ids[] = $val[$index]['value']; foreach (array_keys($val) as $field) { if ($field !== $index) { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; + $final[$val[$field]['field']][] = 'WHEN '.$val[$index]['value'].' THEN '.$val[$field]['value']; } } } @@ -564,12 +563,12 @@ class CI_DB_postgre_driver extends CI_DB { $cases = ''; foreach ($final as $k => $v) { - $cases .= $k.' = (CASE '.$index."\n" + $cases .= $k.' = (CASE '.$val[$index]['field']."\n" .implode("\n", $v)."\n" .'ELSE '.$k.' END), '; } - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); + $this->where($val[$index]['field'].' IN('.implode(',', $ids).')', NULL, FALSE); return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); } diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php index 8d985ba..cf90325 100644 --- a/system/database/drivers/postgre/postgre_forge.php +++ b/system/database/drivers/postgre/postgre_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -163,7 +163,7 @@ class CI_DB_postgre_forge extends CI_DB_forge { */ protected function _attr_type(&$attributes) { - // Reset field lenghts for data types that don't support it + // Reset field lengths for data types that don't support it if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== FALSE) { $attributes['CONSTRAINT'] = NULL; diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php index 354bb08..daf3306 100644 --- a/system/database/drivers/postgre/postgre_result.php +++ b/system/database/drivers/postgre/postgre_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php index bb5e6e0..3af225f 100644 --- a/system/database/drivers/postgre/postgre_utility.php +++ b/system/database/drivers/postgre/postgre_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php index 16b8c29..a061229 100644 --- a/system/database/drivers/sqlite/sqlite_driver.php +++ b/system/database/drivers/sqlite/sqlite_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php index 8a16594..10d5fe6 100644 --- a/system/database/drivers/sqlite/sqlite_forge.php +++ b/system/database/drivers/sqlite/sqlite_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -75,7 +75,7 @@ class CI_DB_sqlite_forge extends CI_DB_forge { * @param string $db_name (ignored) * @return bool */ - public function create_database($db_name = '') + public function create_database($db_name) { // In SQLite, a database is created when you connect to the database. // We'll return TRUE so that an error isn't generated @@ -90,7 +90,7 @@ class CI_DB_sqlite_forge extends CI_DB_forge { * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { if ( ! file_exists($this->db->database) OR ! @unlink($this->db->database)) { diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php index d40b98a..59516b0 100644 --- a/system/database/drivers/sqlite/sqlite_result.php +++ b/system/database/drivers/sqlite/sqlite_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php index 59c46f9..57f685e 100644 --- a/system/database/drivers/sqlite/sqlite_utility.php +++ b/system/database/drivers/sqlite/sqlite_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php index 9743499..41d9d48 100644 --- a/system/database/drivers/sqlite3/sqlite3_driver.php +++ b/system/database/drivers/sqlite3/sqlite3_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -168,7 +168,7 @@ class CI_DB_sqlite3_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Platform-dependant string escape + * Platform-dependent string escape * * @param string * @return string @@ -291,7 +291,7 @@ class CI_DB_sqlite3_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php index 43cbe33..48c5efc 100644 --- a/system/database/drivers/sqlite3/sqlite3_forge.php +++ b/system/database/drivers/sqlite3/sqlite3_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -87,7 +87,7 @@ class CI_DB_sqlite3_forge extends CI_DB_forge { * @param string $db_name * @return bool */ - public function create_database($db_name = '') + public function create_database($db_name) { // In SQLite, a database is created when you connect to the database. // We'll return TRUE so that an error isn't generated @@ -102,7 +102,7 @@ class CI_DB_sqlite3_forge extends CI_DB_forge { * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { // In SQLite, a database is dropped when we delete a file if (file_exists($this->db->database)) diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php index aa559ee..a143fd7 100644 --- a/system/database/drivers/sqlite3/sqlite3_result.php +++ b/system/database/drivers/sqlite3/sqlite3_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php index b47c086..c829c1f 100644 --- a/system/database/drivers/sqlite3/sqlite3_utility.php +++ b/system/database/drivers/sqlite3/sqlite3_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php index 0cd9ce1..05d35a4 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_driver.php +++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.3 @@ -171,6 +171,7 @@ class CI_DB_sqlsrv_driver extends CI_DB { if ($this->_execute('USE '.$this->escape_identifiers($database))) { $this->database = $database; + $this->data_cache = array(); return TRUE; } @@ -357,7 +358,7 @@ class CI_DB_sqlsrv_driver extends CI_DB { * Error * * Returns an array containing code and message of the last - * database error that has occured. + * database error that has occurred. * * @return array */ @@ -477,7 +478,7 @@ class CI_DB_sqlsrv_driver extends CI_DB { $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results - if (count($this->qb_select) === 0) + if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE) { $select = '*'; // Inevitable } @@ -524,7 +525,7 @@ class CI_DB_sqlsrv_driver extends CI_DB { return parent::_insert_batch($table, $keys, $values); } - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; + return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php index f915dad..01547e8 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_forge.php +++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.3 @@ -111,6 +111,11 @@ class CI_DB_sqlsrv_forge extends CI_DB_forge { */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php index fde7264..1d0272f 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_result.php +++ b/system/database/drivers/sqlsrv/sqlsrv_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.3 diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php index 726fe3e..001107d 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_utility.php +++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.3 diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php index 3fdccf9..3d4a496 100644 --- a/system/helpers/array_helper.php +++ b/system/helpers/array_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 3c1e006..a67b72b 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -54,10 +54,10 @@ if ( ! function_exists('create_captcha')) /** * Create CAPTCHA * - * @param array $data data for the CAPTCHA - * @param string $img_path path to create the image in - * @param string $img_url URL to the CAPTCHA image folder - * @param string $font_path server path to font + * @param array $data Data for the CAPTCHA + * @param string $img_path Path to create the image in (deprecated) + * @param string $img_url URL to the CAPTCHA image folder (deprecated) + * @param string $font_path Server path to font (deprecated) * @return string */ function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '') @@ -110,7 +110,8 @@ if ( ! function_exists('create_captcha')) $current_dir = @opendir($img_path); while ($filename = @readdir($current_dir)) { - if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now) + if (in_array(substr($filename, -4), array('.jpg', '.png')) + && (str_replace(array('.jpg', '.png'), '', $filename) + $expiration) < $now) { @unlink($img_path.$filename); } diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php index ca43244..eccd2f3 100644 --- a/system/helpers/cookie_helper.php +++ b/system/helpers/cookie_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -67,7 +67,7 @@ if ( ! function_exists('set_cookie')) * @param bool true makes the cookie accessible via http(s) only (no javascript) * @return void */ - function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) + function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL) { // Set the config file options get_instance()->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly); diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php index c43209f..eca1fc0 100644 --- a/system/helpers/date_helper.php +++ b/system/helpers/date_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -496,6 +496,7 @@ if ( ! function_exists('nice_date')) * Turns many "reasonably-date-like" strings into something * that is actually useful. This only works for dates after unix epoch. * + * @deprecated 3.1.3 Use DateTime::createFromFormat($input_format, $input)->format($output_format); * @param string The terribly formatted date-like string * @param string Date format to return (same as php date function) * @return string @@ -529,9 +530,9 @@ if ( ! function_exists('nice_date')) } // Date Like: YYYYMMDD - if (preg_match('/^(\d{2})\d{2}(\d{4})$/i', $bad_date, $matches)) + if (preg_match('/^\d{8}$/i', $bad_date, $matches)) { - return date($format, strtotime($matches[1].'/01/'.$matches[2])); + return DateTime::createFromFormat('Ymd', $bad_date)->format($format); } // Date Like: MM-DD-YYYY __or__ M-D-YYYY (or anything in between) @@ -707,87 +708,32 @@ if ( ! function_exists('date_range')) $range = array(); - /* NOTE: Even though the DateTime object has many useful features, it appears that - * it doesn't always handle properly timezones, when timestamps are passed - * directly to its constructor. Neither of the following gave proper results: - * - * new DateTime('') - * new DateTime('', '') - * - * --- available in PHP 5.3: - * - * DateTime::createFromFormat('', '') - * DateTime::createFromFormat('', '', 'setTimestamp($unix_start); - if (is_php('5.3')) - { - $from->setTimestamp($unix_start); - if ($is_unix) - { - $arg = new DateTime(); - $arg->setTimestamp($mixed); - } - else - { - $arg = (int) $mixed; - } - - $period = new DatePeriod($from, new DateInterval('P1D'), $arg); - foreach ($period as $date) - { - $range[] = $date->format($format); - } - - /* If a period end date was passed to the DatePeriod constructor, it might not - * be in our results. Not sure if this is a bug or it's just possible because - * the end date might actually be less than 24 hours away from the previously - * generated DateTime object, but either way - we have to append it manually. - */ - if ( ! is_int($arg) && $range[count($range) - 1] !== $arg->format($format)) - { - $range[] = $arg->format($format); - } - - return $range; - } - - $from->setDate(date('Y', $unix_start), date('n', $unix_start), date('j', $unix_start)); - $from->setTime(date('G', $unix_start), date('i', $unix_start), date('s', $unix_start)); if ($is_unix) { $arg = new DateTime(); - $arg->setDate(date('Y', $mixed), date('n', $mixed), date('j', $mixed)); - $arg->setTime(date('G', $mixed), date('i', $mixed), date('s', $mixed)); + $arg->setTimestamp($mixed); } else { $arg = (int) $mixed; } - $range[] = $from->format($format); - if (is_int($arg)) // Day intervals + $period = new DatePeriod($from, new DateInterval('P1D'), $arg); + foreach ($period as $date) { - do - { - $from->modify('+1 day'); - $range[] = $from->format($format); - } - while (--$arg > 0); + $range[] = $date->format($format); } - else // end date UNIX timestamp - { - for ($from->modify('+1 day'), $end_check = $arg->format('Ymd'); $from->format('Ymd') < $end_check; $from->modify('+1 day')) - { - $range[] = $from->format($format); - } - // Our loop only appended dates prior to our end date + /* If a period end date was passed to the DatePeriod constructor, it might not + * be in our results. Not sure if this is a bug or it's just possible because + * the end date might actually be less than 24 hours away from the previously + * generated DateTime object, but either way - we have to append it manually. + */ + if ( ! is_int($arg) && $range[count($range) - 1] !== $arg->format($format)) + { $range[] = $arg->format($format); } diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php index cdc4c16..0d3f205 100644 --- a/system/helpers/directory_helper.php +++ b/system/helpers/directory_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index a6463df..a9bea94 100644 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php index 35944fc..f851f72 100644 --- a/system/helpers/email_helper.php +++ b/system/helpers/email_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index 0d8d1d0..90e4c90 100644 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -138,13 +138,15 @@ if ( ! function_exists('delete_files')) { if ($filename !== '.' && $filename !== '..') { - if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.') + $filepath = $path.DIRECTORY_SEPARATOR.$filename; + + if (is_dir($filepath) && $filename[0] !== '.' && ! is_link($filepath)) { - delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $htdocs, $_level + 1); + delete_files($filepath, $del_dir, $htdocs, $_level + 1); } elseif ($htdocs !== TRUE OR ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) { - @unlink($path.DIRECTORY_SEPARATOR.$filename); + @unlink($filepath); } } } diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 3e10395..8746045 100644 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -90,20 +90,49 @@ if ( ! function_exists('form_open')) $form = '
\n"; - // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites - if ($CI->config->item('csrf_protection') === TRUE && strpos($action, $CI->config->base_url()) !== FALSE && ! stripos($form, 'method="get"')) - { - $hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash(); - } - if (is_array($hidden)) { foreach ($hidden as $name => $value) { - $form .= ''."\n"; + $form .= ''."\n"; } } + // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites + if ($CI->config->item('csrf_protection') === TRUE && strpos($action, $CI->config->base_url()) !== FALSE && ! stripos($form, 'method="get"')) + { + // Prepend/append random-length "white noise" around the CSRF + // token input, as a form of protection against BREACH attacks + if (FALSE !== ($noise = $CI->security->get_random_bytes(1))) + { + list(, $noise) = unpack('c', $noise); + } + else + { + $noise = mt_rand(-128, 127); + } + + // Prepend if $noise has a negative value, append if positive, do nothing for zero + $prepend = $append = ''; + if ($noise < 0) + { + $prepend = str_repeat(" ", abs($noise)); + } + elseif ($noise > 0) + { + $append = str_repeat(" ", $noise); + } + + $form .= sprintf( + '%s%s%s', + $prepend, + $CI->security->get_csrf_token_name(), + $CI->security->get_csrf_hash(), + $append, + "\n" + ); + } + return $form; } } @@ -568,7 +597,7 @@ if ( ! function_exists('form_label')) * * @param string The text to appear onscreen * @param string The id the label applies to - * @param string Additional attributes + * @param mixed Additional attributes * @return string */ function form_label($label_text = '', $id = '', $attributes = array()) @@ -581,13 +610,7 @@ if ( ! function_exists('form_label')) $label .= ' for="'.$id.'"'; } - if (is_array($attributes) && count($attributes) > 0) - { - foreach ($attributes as $key => $val) - { - $label .= ' '.$key.'="'.$val.'"'; - } - } + $label .= _attributes_to_string($attributes); return $label.'>'.$label_text.''; } diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php index fdc463f..260afe9 100644 --- a/system/helpers/html_helper.php +++ b/system/helpers/html_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -192,7 +192,7 @@ if ( ! function_exists('img')) foreach ($src as $k => $v) { - if ($k === 'src' && ! preg_match('#^([a-z]+:)?//#i', $v)) + if ($k === 'src' && ! preg_match('#^(data:[a-z,;])|(([a-z]+:)?(?config->slash_item('base_url').$v.'"'; + $img .= ' src="'.get_instance()->config->base_url($v).'"'; } } else @@ -292,7 +292,7 @@ if ( ! function_exists('link_tag')) } else { - $link .= 'href="'.$CI->config->slash_item('base_url').$v.'" '; + $link .= 'href="'.$CI->config->base_url($v).'" '; } } else @@ -313,7 +313,7 @@ if ( ! function_exists('link_tag')) } else { - $link .= 'href="'.$CI->config->slash_item('base_url').$href.'" '; + $link .= 'href="'.$CI->config->base_url($href).'" '; } $link .= 'rel="'.$rel.'" type="'.$type.'" '; diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php index c064d8d..8354d83 100644 --- a/system/helpers/inflector_helper.php +++ b/system/helpers/inflector_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -95,6 +95,7 @@ if ( ! function_exists('singular')) '/(s)tatuses$/' => '\1\2tatus', '/(c)hildren$/' => '\1\2hild', '/(n)ews$/' => '\1\2ews', + '/(quiz)zes$/' => '\1', '/([^us])s$/' => '\1' ); @@ -238,8 +239,37 @@ if ( ! function_exists('is_countable')) return ! in_array( strtolower($word), array( - 'equipment', 'information', 'rice', 'money', - 'species', 'series', 'fish', 'meta' + 'audio', + 'bison', + 'chassis', + 'compensation', + 'coreopsis', + 'data', + 'deer', + 'education', + 'emoji', + 'equipment', + 'fish', + 'furniture', + 'gold', + 'information', + 'knowledge', + 'love', + 'rain', + 'money', + 'moose', + 'nutrition', + 'offspring', + 'plankton', + 'pokemon', + 'police', + 'rice', + 'series', + 'sheep', + 'species', + 'swine', + 'traffic', + 'wheat' ) ); } diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php index 3721164..f1dc815 100644 --- a/system/helpers/language_helper.php +++ b/system/helpers/language_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php index e7810c7..00e6451 100644 --- a/system/helpers/number_helper.php +++ b/system/helpers/number_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php index 838ece9..697f6bd 100644 --- a/system/helpers/path_helper.php +++ b/system/helpers/path_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -61,7 +61,7 @@ if ( ! function_exists('set_realpath')) function set_realpath($path, $check_existance = FALSE) { // Security check to make sure the path is NOT a URL. No remote file inclusion! - if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp)#i', $path) OR filter_var($path, FILTER_VALIDATE_IP) === $path ) + if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp|php:\/\/)#i', $path) OR filter_var($path, FILTER_VALIDATE_IP) === $path) { show_error('The path you submitted must be a local server path, not a URL'); } diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php index 4eb6388..fb55385 100644 --- a/system/helpers/security_helper.php +++ b/system/helpers/security_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php index 688ca24..b7f1d2e 100644 --- a/system/helpers/smiley_helper.php +++ b/system/helpers/smiley_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php index db531fa..3aa92fa 100644 --- a/system/helpers/string_helper.php +++ b/system/helpers/string_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -195,9 +195,7 @@ if ( ! function_exists('reduce_multiples')) if ( ! function_exists('random_string')) { /** - * Create a Random String - * - * Useful for generating passwords or hashes. + * Create a "Random" String * * @param string type of random string. basic, alpha, alnum, numeric, nozero, unique, md5, encrypt and sha1 * @param int number of characters diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php index 4f9210f..3e2dca8 100644 --- a/system/helpers/text_helper.php +++ b/system/helpers/text_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -102,7 +102,7 @@ if ( ! function_exists('character_limiter')) } // a bit complicated, but faster than preg_replace with \s+ - $str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\x0B", "\x0C"), ' ', $str)); + $str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\v", "\f"), ' ', $str)); if (mb_strlen($str) <= $n) { @@ -138,7 +138,10 @@ if ( ! function_exists('ascii_to_entities')) function ascii_to_entities($str) { $out = ''; - for ($i = 0, $s = strlen($str) - 1, $count = 1, $temp = array(); $i <= $s; $i++) + $length = defined('MB_OVERLOAD_STRING') + ? mb_strlen($str, '8bit') - 1 + : strlen($str) - 1; + for ($i = 0, $count = 1, $temp = array(); $i <= $length; $i++) { $ordinal = ord($str[$i]); @@ -176,7 +179,7 @@ if ( ! function_exists('ascii_to_entities')) $temp = array(); } // If this is the last iteration, just output whatever we have - elseif ($i === $s) + elseif ($i === $length) { $out .= '&#'.implode(';', $temp).';'; } diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php index 928cb6d..e97c83b 100644 --- a/system/helpers/typography_helper.php +++ b/system/helpers/typography_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index fd7b5e1..a22c4c2 100644 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -393,10 +393,10 @@ if ( ! function_exists('auto_link')) function auto_link($str, $type = 'both', $popup = FALSE) { // Find and replace any URLs. - if ($type !== 'email' && preg_match_all('#(\w*://|www\.)[^\s()<>;]+\w#i', $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) + if ($type !== 'email' && preg_match_all('#(\w*://|www\.)[a-z0-9]+(-+[a-z0-9]+)*(\.[a-z0-9]+(-+[a-z0-9]+)*)+(/([^\s()<>;]+\w)?/?)?#i', $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) { // Set our target HTML if using popup links. - $target = ($popup) ? ' target="_blank"' : ''; + $target = ($popup) ? ' target="_blank" rel="noopener"' : ''; // We process the links in reverse order (last -> first) so that // the returned string offsets from preg_match_all() are not diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php index 3489da9..68fb9d7 100644 --- a/system/helpers/xml_helper.php +++ b/system/helpers/xml_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php index 349af15..f13c024 100644 --- a/system/libraries/Cache/Cache.php +++ b/system/libraries/Cache/Cache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php index 07ea8f4..b42a832 100644 --- a/system/libraries/Cache/drivers/Cache_apc.php +++ b/system/libraries/Cache/drivers/Cache_apc.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 @@ -80,14 +80,7 @@ class CI_Cache_apc extends CI_Driver { $success = FALSE; $data = apc_fetch($id, $success); - if ($success === TRUE) - { - return is_array($data) - ? unserialize($data[0]) - : $data; - } - - return FALSE; + return ($success === TRUE) ? $data : FALSE; } // ------------------------------------------------------------------------ @@ -97,19 +90,13 @@ class CI_Cache_apc extends CI_Driver { * * @param string $id Cache ID * @param mixed $data Data to store - * @param int $ttol Length of time (in seconds) to cache the data - * @param bool $raw Whether to store the raw value + * @param int $ttl Length of time (in seconds) to cache the data + * @param bool $raw Whether to store the raw value (unused) * @return bool TRUE on success, FALSE on failure */ public function save($id, $data, $ttl = 60, $raw = FALSE) { - $ttl = (int) $ttl; - - return apc_store( - $id, - ($raw === TRUE ? $data : array(serialize($data), time(), $ttl)), - $ttl - ); + return apc_store($id, $data, (int) $ttl); } // ------------------------------------------------------------------------ @@ -188,21 +175,30 @@ class CI_Cache_apc extends CI_Driver { */ public function get_metadata($id) { - $success = FALSE; - $stored = apc_fetch($id, $success); - - if ($success === FALSE OR count($stored) !== 3) + $cache_info = apc_cache_info('user', FALSE); + if (empty($cache_info) OR empty($cache_info['cache_list'])) { return FALSE; } - list($data, $time, $ttl) = $stored; + foreach ($cache_info['cache_list'] as &$entry) + { + if ($entry['info'] !== $id) + { + continue; + } - return array( - 'expire' => $time + $ttl, - 'mtime' => $time, - 'data' => unserialize($data) - ); + $success = FALSE; + $metadata = array( + 'expire' => ($entry['ttl'] ? $entry['mtime'] + $entry['ttl'] : 0), + 'mtime' => $entry['ttl'], + 'data' => apc_fetch($id, $success) + ); + + return ($success === TRUE) ? $metadata : FALSE; + } + + return FALSE; } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php index 4323a68..bbaf96f 100644 --- a/system/libraries/Cache/drivers/Cache_dummy.php +++ b/system/libraries/Cache/drivers/Cache_dummy.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0 diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php index e1ce16a..4f38303 100644 --- a/system/libraries/Cache/drivers/Cache_file.php +++ b/system/libraries/Cache/drivers/Cache_file.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0 @@ -120,7 +120,7 @@ class CI_Cache_file extends CI_Driver { */ public function delete($id) { - return file_exists($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE; + return is_file($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE; } // ------------------------------------------------------------------------ @@ -216,7 +216,7 @@ class CI_Cache_file extends CI_Driver { */ public function get_metadata($id) { - if ( ! file_exists($this->_cache_path.$id)) + if ( ! is_file($this->_cache_path.$id)) { return FALSE; } @@ -227,13 +227,13 @@ class CI_Cache_file extends CI_Driver { { $mtime = filemtime($this->_cache_path.$id); - if ( ! isset($data['ttl'])) + if ( ! isset($data['ttl'], $data['time'])) { return FALSE; } return array( - 'expire' => $mtime + $data['ttl'], + 'expire' => $data['time'] + $data['ttl'], 'mtime' => $mtime ); } diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php index 6dee1e8..9dfee47 100644 --- a/system/libraries/Cache/drivers/Cache_memcached.php +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0 @@ -110,7 +110,7 @@ class CI_Cache_memcached extends CI_Driver { if ($this->_memcached instanceof Memcache) { - // Third parameter is persistance and defaults to TRUE. + // Third parameter is persistence and defaults to TRUE. $this->_memcached->addServer( $cache_server['hostname'], $cache_server['port'], @@ -198,7 +198,12 @@ class CI_Cache_memcached extends CI_Driver { */ public function increment($id, $offset = 1) { - return $this->_memcached->increment($id, $offset); + if (($result = $this->_memcached->increment($id, $offset)) === FALSE) + { + return $this->_memcached->add($id, $offset) ? $offset : FALSE; + } + + return $result; } // ------------------------------------------------------------------------ @@ -212,7 +217,12 @@ class CI_Cache_memcached extends CI_Driver { */ public function decrement($id, $offset = 1) { - return $this->_memcached->decrement($id, $offset); + if (($result = $this->_memcached->decrement($id, $offset)) === FALSE) + { + return $this->_memcached->add($id, 0) ? 0 : FALSE; + } + + return $result; } // ------------------------------------------------------------------------ @@ -295,7 +305,7 @@ class CI_Cache_memcached extends CI_Driver { { $this->_memcached->close(); } - elseif ($this->_memcached instanceof Memcached) + elseif ($this->_memcached instanceof Memcached && method_exists($this->_memcached, 'quit')) { $this->_memcached->quit(); } diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php index d4d95eb..bfd6204 100644 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php index d6a0d4f..b4279bb 100644 --- a/system/libraries/Cache/drivers/Cache_wincache.php +++ b/system/libraries/Cache/drivers/Cache_wincache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php index 1f8ef81..450350c 100644 --- a/system/libraries/Calendar.php +++ b/system/libraries/Calendar.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php index 44d87e0..4c51e7a 100644 --- a/system/libraries/Cart.php +++ b/system/libraries/Cart.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php index 38c6aef..7dd66ec 100644 --- a/system/libraries/Driver.php +++ b/system/libraries/Driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Email.php b/system/libraries/Email.php index ed6f737..cd74d6d 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -147,14 +147,7 @@ class CI_Email { * * @var string */ - public $charset = 'utf-8'; - - /** - * Multipart message - * - * @var string 'mixed' (in the body) or 'related' (separate) - */ - public $multipart = 'mixed'; // "mixed" (in the body) or "related" (separate) + public $charset = 'UTF-8'; /** * Alternative message (for HTML messages only) @@ -260,20 +253,6 @@ class CI_Email { */ protected $_finalbody = ''; - /** - * multipart/alternative boundary - * - * @var string - */ - protected $_alt_boundary = ''; - - /** - * Attachment boundary - * - * @var string - */ - protected $_atc_boundary = ''; - /** * Final headers to send * @@ -395,6 +374,13 @@ class CI_Email { 5 => '5 (Lowest)' ); + /** + * mbstring.func_overload flag + * + * @var bool + */ + protected static $func_overload; + // -------------------------------------------------------------------- /** @@ -408,47 +394,26 @@ class CI_Email { public function __construct(array $config = array()) { $this->charset = config_item('charset'); - - if (count($config) > 0) - { - $this->initialize($config); - } - else - { - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - } - + $this->initialize($config); $this->_safe_mode = ( ! is_php('5.4') && ini_get('safe_mode')); - $this->charset = strtoupper($this->charset); + + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); log_message('info', 'Email Class Initialized'); } // -------------------------------------------------------------------- - /** - * Destructor - Releases Resources - * - * @return void - */ - public function __destruct() - { - if (is_resource($this->_smtp_connect)) - { - $this->_send_command('quit'); - } - } - - // -------------------------------------------------------------------- - /** * Initialize preferences * - * @param array + * @param array $config * @return CI_Email */ - public function initialize($config = array()) + public function initialize(array $config = array()) { + $this->clear(); + foreach ($config as $key => $val) { if (isset($this->$key)) @@ -465,9 +430,9 @@ class CI_Email { } } } - $this->clear(); - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); + $this->charset = strtoupper($this->charset); + $this->_smtp_auth = isset($this->smtp_user[0], $this->smtp_pass[0]); return $this; } @@ -493,7 +458,6 @@ class CI_Email { $this->_headers = array(); $this->_debug_msg = array(); - $this->set_header('User-Agent', $this->useragent); $this->set_header('Date', $this->_set_date()); if ($clear_attachments !== FALSE) @@ -766,7 +730,8 @@ class CI_Email { 'name' => array($file, $newname), 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters 'type' => $mime, - 'content' => chunk_split(base64_encode($file_content)) + 'content' => chunk_split(base64_encode($file_content)), + 'multipart' => 'mixed' ); return $this; @@ -784,15 +749,11 @@ class CI_Email { */ public function attachment_cid($filename) { - if ($this->multipart !== 'related') - { - $this->multipart = 'related'; // Thunderbird need this for inline images - } - for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) { if ($this->_attachments[$i]['name'][0] === $filename) { + $this->_attachments[$i]['multipart'] = 'related'; $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); return $this->_attachments[$i]['cid']; } @@ -936,19 +897,6 @@ class CI_Email { // -------------------------------------------------------------------- - /** - * Set Message Boundary - * - * @return void - */ - protected function _set_boundaries() - { - $this->_alt_boundary = 'B_ALT_'.uniqid(''); // multipart/alternative - $this->_atc_boundary = 'B_ATC_'.uniqid(''); // attachment boundary - } - - // -------------------------------------------------------------------- - /** * Get the Message ID * @@ -965,18 +913,13 @@ class CI_Email { /** * Get Mail Protocol * - * @param bool * @return mixed */ - protected function _get_protocol($return = TRUE) + protected function _get_protocol() { $this->protocol = strtolower($this->protocol); in_array($this->protocol, $this->_protocols, TRUE) OR $this->protocol = 'mail'; - - if ($return === TRUE) - { - return $this->protocol; - } + return $this->protocol; } // -------------------------------------------------------------------- @@ -984,25 +927,21 @@ class CI_Email { /** * Get Mail Encoding * - * @param bool * @return string */ - protected function _get_encoding($return = TRUE) + protected function _get_encoding() { in_array($this->_encoding, $this->_bit_depths) OR $this->_encoding = '8bit'; foreach ($this->_base_charsets as $charset) { - if (strpos($charset, $this->charset) === 0) + if (strpos($this->charset, $charset) === 0) { $this->_encoding = '7bit'; } } - if ($return === TRUE) - { - return $this->_encoding; - } + return $this->_encoding; } // -------------------------------------------------------------------- @@ -1016,16 +955,14 @@ class CI_Email { { if ($this->mailtype === 'html') { - return (count($this->_attachments) === 0) ? 'html' : 'html-attach'; + return empty($this->_attachments) ? 'html' : 'html-attach'; } - elseif ($this->mailtype === 'text' && count($this->_attachments) > 0) + elseif ($this->mailtype === 'text' && ! empty($this->_attachments)) { return 'plain-attach'; } - else - { - return 'plain'; - } + + return 'plain'; } // -------------------------------------------------------------------- @@ -1095,9 +1032,17 @@ class CI_Email { */ public function valid_email($email) { - if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@')) + if (function_exists('idn_to_ascii') && strpos($email, '@')) { - $email = substr($email, 0, ++$atpos).idn_to_ascii(substr($email, $atpos)); + list($account, $domain) = explode('@', $email, 2); + $domain = defined('INTL_IDNA_VARIANT_UTS46') + ? idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) + : idn_to_ascii($domain); + + if ($domain !== FALSE) + { + $email = $account.'@'.$domain; + } } return (bool) filter_var($email, FILTER_VALIDATE_EMAIL); @@ -1214,7 +1159,7 @@ class CI_Email { { // Is the line within the allowed character count? // If so we'll join it to the output and continue - if (mb_strlen($line) <= $charlim) + if (self::strlen($line) <= $charlim) { $output .= $line.$this->newline; continue; @@ -1230,10 +1175,10 @@ class CI_Email { } // Trim the word down - $temp .= mb_substr($line, 0, $charlim - 1); - $line = mb_substr($line, $charlim - 1); + $temp .= self::substr($line, 0, $charlim - 1); + $line = self::substr($line, $charlim - 1); } - while (mb_strlen($line) > $charlim); + while (self::strlen($line) > $charlim); // If $temp contains data it means we had to split up an over-length // word into smaller chunks so we'll add it back to our current line @@ -1262,10 +1207,11 @@ class CI_Email { /** * Build final headers * - * @return string + * @return void */ protected function _build_headers() { + $this->set_header('User-Agent', $this->useragent); $this->set_header('X-Sender', $this->clean_email($this->_headers['From'])); $this->set_header('X-Mailer', $this->useragent); $this->set_header('X-Priority', $this->_priorities[$this->priority]); @@ -1324,7 +1270,6 @@ class CI_Email { $this->_body = $this->word_wrap($this->_body); } - $this->_set_boundaries(); $this->_write_headers(); $hdr = ($this->_get_protocol() === 'mail') ? $this->newline : ''; @@ -1332,7 +1277,7 @@ class CI_Email { switch ($this->_get_content_type()) { - case 'plain' : + case 'plain': $hdr .= 'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding(); @@ -1349,7 +1294,7 @@ class CI_Email { return; - case 'html' : + case 'html': if ($this->send_multipart === FALSE) { @@ -1358,14 +1303,16 @@ class CI_Email { } else { - $hdr .= 'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'; + $boundary = uniqid('B_ALT_'); + $hdr .= 'Content-Type: multipart/alternative; boundary="'.$boundary.'"'; $body .= $this->_get_mime_message().$this->newline.$this->newline - .'--'.$this->_alt_boundary.$this->newline + .'--'.$boundary.$this->newline .'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline - .$this->_get_alt_message().$this->newline.$this->newline.'--'.$this->_alt_boundary.$this->newline + .$this->_get_alt_message().$this->newline.$this->newline + .'--'.$boundary.$this->newline .'Content-Type: text/html; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline; @@ -1384,14 +1331,15 @@ class CI_Email { if ($this->send_multipart !== FALSE) { - $this->_finalbody .= '--'.$this->_alt_boundary.'--'; + $this->_finalbody .= '--'.$boundary.'--'; } return; - case 'plain-attach' : + case 'plain-attach': - $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'; + $boundary = uniqid('B_ATC_'); + $hdr .= 'Content-Type: multipart/mixed; boundary="'.$boundary.'"'; if ($this->_get_protocol() === 'mail') { @@ -1400,59 +1348,83 @@ class CI_Email { $body .= $this->_get_mime_message().$this->newline .$this->newline - .'--'.$this->_atc_boundary.$this->newline + .'--'.$boundary.$this->newline .'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline .$this->newline .$this->_body.$this->newline.$this->newline; - break; - case 'html-attach' : + $this->_append_attachments($body, $boundary); - $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'; + break; + case 'html-attach': + + $alt_boundary = uniqid('B_ALT_'); + $last_boundary = NULL; + + if ($this->_attachments_have_multipart('mixed')) + { + $atc_boundary = uniqid('B_ATC_'); + $hdr .= 'Content-Type: multipart/mixed; boundary="'.$atc_boundary.'"'; + $last_boundary = $atc_boundary; + } + + if ($this->_attachments_have_multipart('related')) + { + $rel_boundary = uniqid('B_REL_'); + $rel_boundary_header = 'Content-Type: multipart/related; boundary="'.$rel_boundary.'"'; + + if (isset($last_boundary)) + { + $body .= '--'.$last_boundary.$this->newline.$rel_boundary_header; + } + else + { + $hdr .= $rel_boundary_header; + } + + $last_boundary = $rel_boundary; + } if ($this->_get_protocol() === 'mail') { $this->_header_str .= $hdr; } + self::strlen($body) && $body .= $this->newline.$this->newline; $body .= $this->_get_mime_message().$this->newline.$this->newline - .'--'.$this->_atc_boundary.$this->newline + .'--'.$last_boundary.$this->newline - .'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'.$this->newline.$this->newline - .'--'.$this->_alt_boundary.$this->newline + .'Content-Type: multipart/alternative; boundary="'.$alt_boundary.'"'.$this->newline.$this->newline + .'--'.$alt_boundary.$this->newline .'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline - .$this->_get_alt_message().$this->newline.$this->newline.'--'.$this->_alt_boundary.$this->newline + .$this->_get_alt_message().$this->newline.$this->newline + .'--'.$alt_boundary.$this->newline .'Content-Type: text/html; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline .$this->_prep_quoted_printable($this->_body).$this->newline.$this->newline - .'--'.$this->_alt_boundary.'--'.$this->newline.$this->newline; + .'--'.$alt_boundary.'--'.$this->newline.$this->newline; - break; + if ( ! empty($rel_boundary)) + { + $body .= $this->newline.$this->newline; + $this->_append_attachments($body, $rel_boundary, 'related'); + } + + // multipart/mixed attachments + if ( ! empty($atc_boundary)) + { + $body .= $this->newline.$this->newline; + $this->_append_attachments($body, $atc_boundary, 'mixed'); + } + + break; } - $attachment = array(); - for ($i = 0, $c = count($this->_attachments), $z = 0; $i < $c; $i++) - { - $filename = $this->_attachments[$i]['name'][0]; - $basename = ($this->_attachments[$i]['name'][1] === NULL) - ? basename($filename) : $this->_attachments[$i]['name'][1]; - - $attachment[$z++] = '--'.$this->_atc_boundary.$this->newline - .'Content-type: '.$this->_attachments[$i]['type'].'; ' - .'name="'.$basename.'"'.$this->newline - .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline - .'Content-Transfer-Encoding: base64'.$this->newline - .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline); - - $attachment[$z++] = $this->_attachments[$i]['content']; - } - - $body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--'; $this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr.$this->newline.$this->newline.$body; @@ -1462,6 +1434,58 @@ class CI_Email { // -------------------------------------------------------------------- + protected function _attachments_have_multipart($type) + { + foreach ($this->_attachments as &$attachment) + { + if ($attachment['multipart'] === $type) + { + return TRUE; + } + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Prepares attachment string + * + * @param string $body Message body to append to + * @param string $boundary Multipart boundary + * @param string $multipart When provided, only attachments of this type will be processed + * @return string + */ + protected function _append_attachments(&$body, $boundary, $multipart = null) + { + for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) + { + if (isset($multipart) && $this->_attachments[$i]['multipart'] !== $multipart) + { + continue; + } + + $name = isset($this->_attachments[$i]['name'][1]) + ? $this->_attachments[$i]['name'][1] + : basename($this->_attachments[$i]['name'][0]); + + $body .= '--'.$boundary.$this->newline + .'Content-Type: '.$this->_attachments[$i]['type'].'; name="'.$name.'"'.$this->newline + .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline + .'Content-Transfer-Encoding: base64'.$this->newline + .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline) + .$this->newline + .$this->_attachments[$i]['content'].$this->newline; + } + + // $name won't be set if no attachments were appended, + // and therefore a boundary wouldn't be necessary + empty($name) OR $body .= '--'.$boundary.'--'; + } + + // -------------------------------------------------------------------- + /** * Prep Quoted Printable * @@ -1497,14 +1521,7 @@ class CI_Email { // which only works with "\n". if ($this->crlf === "\r\n") { - if (is_php('5.3')) - { - return quoted_printable_encode($str); - } - elseif (function_exists('imap_8bit')) - { - return imap_8bit($str); - } + return quoted_printable_encode($str); } // Reduce multiple spaces & remove nulls @@ -1521,7 +1538,7 @@ class CI_Email { foreach (explode("\n", $str) as $line) { - $length = strlen($line); + $length = self::strlen($line); $temp = ''; // Loop through each character in the line to add soft-wrap @@ -1556,7 +1573,7 @@ class CI_Email { // If we're at the character limit, add the line to the output, // reset our temp variable, and keep on chuggin' - if ((strlen($temp) + strlen($char)) >= 76) + if ((self::strlen($temp) + self::strlen($char)) >= 76) { $output .= $temp.$escape.$this->crlf; $temp = ''; @@ -1571,7 +1588,7 @@ class CI_Email { } // get rid of extra CRLF tacked onto the end - return substr($output, 0, strlen($this->crlf) * -1); + return self::substr($output, 0, self::strlen($this->crlf) * -1); } // -------------------------------------------------------------------- @@ -1613,7 +1630,7 @@ class CI_Email { // iconv_mime_encode() will always put a header field name. // We've passed it an empty one, but it still prepends our // encoded string with ': ', so we need to strip it. - return substr($output, 2); + return self::substr($output, 2); } $chars = iconv_strlen($str, 'UTF-8'); @@ -1625,10 +1642,10 @@ class CI_Email { } // We might already have this set for UTF-8 - isset($chars) OR $chars = strlen($str); + isset($chars) OR $chars = self::strlen($str); $output = '=?'.$this->charset.'?Q?'; - for ($i = 0, $length = strlen($output); $i < $chars; $i++) + for ($i = 0, $length = self::strlen($output); $i < $chars; $i++) { $chr = ($this->charset === 'UTF-8' && ICONV_ENABLED === TRUE) ? '='.implode('=', str_split(strtoupper(bin2hex(iconv_substr($str, $i, 1, $this->charset))), 2)) @@ -1636,11 +1653,11 @@ class CI_Email { // RFC 2045 sets a limit of 76 characters per line. // We'll append ?= to the end of each line though. - if ($length + ($l = strlen($chr)) > 74) + if ($length + ($l = self::strlen($chr)) > 74) { $output .= '?='.$this->crlf // EOL .' =?'.$this->charset.'?Q?'.$chr; // New line - $length = 6 + strlen($this->charset) + $l; // Reset the length for the new line + $length = 6 + self::strlen($this->charset) + $l; // Reset the length for the new line } else { @@ -1733,14 +1750,14 @@ class CI_Email { if ($i === $float) { - $chunk[] = substr($set, 1); + $chunk[] = self::substr($set, 1); $float += $this->bcc_batch_size; $set = ''; } if ($i === $c-1) { - $chunk[] = substr($set, 1); + $chunk[] = self::substr($set, 1); } } @@ -1809,19 +1826,55 @@ class CI_Email { { $this->_unwrap_specials(); - $method = '_send_with_'.$this->_get_protocol(); + $protocol = $this->_get_protocol(); + $method = '_send_with_'.$protocol; if ( ! $this->$method()) { - $this->_set_error_message('lang:email_send_failure_'.($this->_get_protocol() === 'mail' ? 'phpmail' : $this->_get_protocol())); + $this->_set_error_message('lang:email_send_failure_'.($protocol === 'mail' ? 'phpmail' : $protocol)); return FALSE; } - $this->_set_error_message('lang:email_sent', $this->_get_protocol()); + $this->_set_error_message('lang:email_sent', $protocol); return TRUE; } // -------------------------------------------------------------------- + /** + * Validate email for shell + * + * Applies stricter, shell-safe validation to email addresses. + * Introduced to prevent RCE via sendmail's -f option. + * + * @see https://github.com/bcit-ci/CodeIgniter/issues/4963 + * @see https://gist.github.com/Zenexer/40d02da5e07f151adeaeeaa11af9ab36 + * @license https://creativecommons.org/publicdomain/zero/1.0/ CC0 1.0, Public Domain + * + * Credits for the base concept go to Paul Buonopane + * + * @param string $email + * @return bool + */ + protected function _validate_email_for_shell(&$email) + { + if (function_exists('idn_to_ascii') && strpos($email, '@')) + { + list($account, $domain) = explode('@', $email, 2); + $domain = defined('INTL_IDNA_VARIANT_UTS46') + ? idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) + : idn_to_ascii($domain); + + if ($domain !== FALSE) + { + $email = $account.'@'.$domain; + } + } + + return (filter_var($email, FILTER_VALIDATE_EMAIL) === $email && preg_match('#\A[a-z0-9._+-]+@[a-z0-9.-]{1,253}\z#i', $email)); + } + + // -------------------------------------------------------------------- + /** * Send using mail() * @@ -1834,7 +1887,11 @@ class CI_Email { $this->_recipients = implode(', ', $this->_recipients); } - if ($this->_safe_mode === TRUE) + // _validate_email_for_shell() below accepts by reference, + // so this needs to be assigned to a variable + $from = $this->clean_email($this->_headers['Return-Path']); + + if ($this->_safe_mode === TRUE || ! $this->_validate_email_for_shell($from)) { return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str); } @@ -1842,7 +1899,7 @@ class CI_Email { { // most documentation of sendmail using the "-f" flag lacks a space after it, however // we've encountered servers that seem to require it to be in place. - return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['Return-Path'])); + return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$from); } } @@ -1855,13 +1912,22 @@ class CI_Email { */ protected function _send_with_sendmail() { - // is popen() enabled? - if ( ! function_usable('popen') - OR FALSE === ($fp = @popen( - $this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t' - , 'w')) - ) // server probably has popen disabled, so nothing we can do to get a verbose error. + // _validate_email_for_shell() below accepts by reference, + // so this needs to be assigned to a variable + $from = $this->clean_email($this->_headers['From']); + if ($this->_validate_email_for_shell($from)) { + $from = '-f '.$from; + } + else + { + $from = ''; + } + + // is popen() enabled? + if ( ! function_usable('popen') OR FALSE === ($fp = @popen($this->mailpath.' -oi '.$from.' -t', 'w'))) + { + // server probably has popen disabled, so nothing we can do to get a verbose error. return FALSE; } @@ -1902,6 +1968,7 @@ class CI_Email { if ( ! $this->_send_command('from', $this->clean_email($this->_headers['From']))) { + $this->_smtp_end(); return FALSE; } @@ -1909,6 +1976,7 @@ class CI_Email { { if ( ! $this->_send_command('to', $val)) { + $this->_smtp_end(); return FALSE; } } @@ -1919,6 +1987,7 @@ class CI_Email { { if ($val !== '' && ! $this->_send_command('to', $val)) { + $this->_smtp_end(); return FALSE; } } @@ -1930,6 +1999,7 @@ class CI_Email { { if ($val !== '' && ! $this->_send_command('to', $val)) { + $this->_smtp_end(); return FALSE; } } @@ -1937,6 +2007,7 @@ class CI_Email { if ( ! $this->_send_command('data')) { + $this->_smtp_end(); return FALSE; } @@ -1946,29 +2017,37 @@ class CI_Email { $this->_send_data('.'); $reply = $this->_get_smtp_data(); - $this->_set_error_message($reply); + $this->_smtp_end(); + if (strpos($reply, '250') !== 0) { $this->_set_error_message('lang:email_smtp_error', $reply); return FALSE; } - if ($this->smtp_keepalive) - { - $this->_send_command('reset'); - } - else - { - $this->_send_command('quit'); - } - return TRUE; } // -------------------------------------------------------------------- + /** + * SMTP End + * + * Shortcut to send RSET or QUIT depending on keep-alive + * + * @return void + */ + protected function _smtp_end() + { + ($this->smtp_keepalive) + ? $this->_send_command('reset') + : $this->_send_command('quit'); + } + + // -------------------------------------------------------------------- + /** * SMTP Connect * @@ -2003,7 +2082,19 @@ class CI_Email { $this->_send_command('hello'); $this->_send_command('starttls'); - $crypto = stream_socket_enable_crypto($this->_smtp_connect, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT); + /** + * STREAM_CRYPTO_METHOD_TLS_CLIENT is quite the mess ... + * + * - On PHP <5.6 it doesn't even mean TLS, but SSL 2.0, and there's no option to use actual TLS + * - On PHP 5.6.0-5.6.6, >=7.2 it means negotiation with any of TLS 1.0, 1.1, 1.2 + * - On PHP 5.6.7-7.1.* it means only TLS 1.0 + * + * We want the negotiation, so we'll force it below ... + */ + $method = is_php('5.6') + ? STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT + : STREAM_CRYPTO_METHOD_TLS_CLIENT; + $crypto = stream_socket_enable_crypto($this->_smtp_connect, TRUE, $method); if ($crypto !== TRUE) { @@ -2022,7 +2113,7 @@ class CI_Email { * * @param string * @param string - * @return string + * @return bool */ protected function _send_command($cmd, $data = '') { @@ -2085,7 +2176,7 @@ class CI_Email { $this->_debug_msg[] = '
'.$cmd.': '.$reply.'
'; - if ((int) substr($reply, 0, 3) !== $resp) + if ((int) self::substr($reply, 0, 3) !== $resp) { $this->_set_error_message('lang:email_smtp_error', $reply); return FALSE; @@ -2153,6 +2244,11 @@ class CI_Email { return FALSE; } + if ($this->smtp_keepalive) + { + $this->_smtp_auth = FALSE; + } + return TRUE; } @@ -2167,9 +2263,9 @@ class CI_Email { protected function _send_data($data) { $data .= $this->newline; - for ($written = $timestamp = 0, $length = strlen($data); $written < $length; $written += $result) + for ($written = $timestamp = 0, $length = self::strlen($data); $written < $length; $written += $result) { - if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE) + if (($result = fwrite($this->_smtp_connect, self::substr($data, $written))) === FALSE) { break; } @@ -2189,10 +2285,8 @@ class CI_Email { usleep(250000); continue; } - else - { - $timestamp = 0; - } + + $timestamp = 0; } if ($result === FALSE) @@ -2342,4 +2436,55 @@ class CI_Email { return 'application/x-unknown-content-type'; } + // -------------------------------------------------------------------- + + /** + * Destructor + * + * @return void + */ + public function __destruct() + { + is_resource($this->_smtp_connect) && $this->_send_command('quit'); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_overload) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php index 1372a31..17a3fe2 100644 --- a/system/libraries/Encrypt.php +++ b/system/libraries/Encrypt.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -122,7 +122,7 @@ class CI_Encrypt { $key = config_item('encryption_key'); - if ( ! strlen($key)) + if ( ! self::strlen($key)) { show_error('In order to use the encryption class requires that you set an encryption key in your config file.'); } @@ -252,7 +252,7 @@ class CI_Encrypt { $string = $this->_xor_merge($string, $key); $dec = ''; - for ($i = 0, $l = strlen($string); $i < $l; $i++) + for ($i = 0, $l = self::strlen($string); $i < $l; $i++) { $dec .= ($string[$i++] ^ $string[$i]); } @@ -275,7 +275,8 @@ class CI_Encrypt { { $hash = $this->hash($key); $str = ''; - for ($i = 0, $ls = strlen($string), $lh = strlen($hash); $i < $ls; $i++) + + for ($i = 0, $ls = self::strlen($string), $lh = self::strlen($hash); $i < $ls; $i++) { $str .= $string[$i] ^ $hash[($i % $lh)]; } @@ -295,7 +296,7 @@ class CI_Encrypt { public function mcrypt_encode($data, $key) { $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode()); - $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND); + $init_vect = mcrypt_create_iv($init_size, MCRYPT_DEV_URANDOM); return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key); } @@ -313,13 +314,14 @@ class CI_Encrypt { $data = $this->_remove_cipher_noise($data, $key); $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode()); - if ($init_size > strlen($data)) + if ($init_size > self::strlen($data)) { return FALSE; } - $init_vect = substr($data, 0, $init_size); - $data = substr($data, $init_size); + $init_vect = self::substr($data, 0, $init_size); + $data = self::substr($data, $init_size); + return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0"); } @@ -339,7 +341,7 @@ class CI_Encrypt { $key = $this->hash($key); $str = ''; - for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j) + for ($i = 0, $j = 0, $ld = self::strlen($data), $lk = self::strlen($key); $i < $ld; ++$i, ++$j) { if ($j >= $lk) { @@ -369,7 +371,7 @@ class CI_Encrypt { $key = $this->hash($key); $str = ''; - for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j) + for ($i = 0, $j = 0, $ld = self::strlen($data), $lk = self::strlen($key); $i < $ld; ++$i, ++$j) { if ($j >= $lk) { @@ -477,4 +479,43 @@ class CI_Encrypt { return hash($this->_hash_type, $str); } + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return defined('MB_OVERLOAD_STRING') + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (defined('MB_OVERLOAD_STRING')) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php index 92c38a0..62f8556 100644 --- a/system/libraries/Encryption.php +++ b/system/libraries/Encryption.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -135,11 +135,11 @@ class CI_Encryption { ); /** - * mbstring.func_override flag + * mbstring.func_overload flag * * @var bool */ - protected static $func_override; + protected static $func_overload; // -------------------------------------------------------------------- @@ -152,10 +152,8 @@ class CI_Encryption { public function __construct(array $params = array()) { $this->_drivers = array( - 'mcrypt' => defined('MCRYPT_DEV_URANDOM'), - // While OpenSSL is available for PHP 5.3.0, an IV parameter - // for the encrypt/decrypt functions is only available since 5.3.3 - 'openssl' => (is_php('5.3.3') && extension_loaded('openssl')) + 'mcrypt' => defined('MCRYPT_DEV_URANDOM'), + 'openssl' => extension_loaded('openssl') ); if ( ! $this->_drivers['mcrypt'] && ! $this->_drivers['openssl']) @@ -163,7 +161,7 @@ class CI_Encryption { show_error('Encryption: Unable to find an available encryption driver.'); } - isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); $this->initialize($params); if ( ! isset($this->_key) && self::strlen($key = config_item('encryption_key')) > 0) @@ -339,12 +337,26 @@ class CI_Encryption { { if (function_exists('random_bytes')) { - return random_bytes((int) $length); + try + { + return random_bytes((int) $length); + } + catch (Exception $e) + { + log_message('error', $e->getMessage()); + return FALSE; + } + } + elseif (defined('MCRYPT_DEV_URANDOM')) + { + return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); } - return ($this->_driver === 'mcrypt') - ? mcrypt_create_iv($length, MCRYPT_DEV_URANDOM) - : openssl_random_pseudo_bytes($length); + $is_secure = NULL; + $key = openssl_random_pseudo_bytes($length, $is_secure); + return ($is_secure === TRUE) + ? $key + : FALSE; } // -------------------------------------------------------------------- @@ -400,7 +412,7 @@ class CI_Encryption { // The greater-than-1 comparison is mostly a work-around for a bug, // where 1 is returned for ARCFour instead of 0. $iv = (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1) - ? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM) + ? $this->create_key($iv_size) : NULL; if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0) @@ -463,7 +475,7 @@ class CI_Encryption { } $iv = ($iv_size = openssl_cipher_iv_length($params['handle'])) - ? openssl_random_pseudo_bytes($iv_size) + ? $this->create_key($iv_size) : NULL; $data = openssl_encrypt( @@ -670,10 +682,8 @@ class CI_Encryption { { return FALSE; } - else - { - $params['mode'] = $this->_modes[$this->_driver][$params['mode']]; - } + + $params['mode'] = $this->_modes[$this->_driver][$params['mode']]; } if (isset($params['hmac']) && $params['hmac'] === FALSE) @@ -895,11 +905,11 @@ class CI_Encryption { * Byte-safe strlen() * * @param string $str - * @return integer + * @return int */ protected static function strlen($str) { - return (self::$func_override) + return (self::$func_overload) ? mb_strlen($str, '8bit') : strlen($str); } @@ -916,7 +926,7 @@ class CI_Encryption { */ protected static function substr($str, $start, $length = NULL) { - if (self::$func_override) + if (self::$func_overload) { // mb_substr($str, $start, null, '8bit') returns an empty // string on PHP 5.3 diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index e4a5189..27187df 100644 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -493,6 +493,63 @@ class CI_Form_validation { // -------------------------------------------------------------------- + /** + * Prepare rules + * + * Re-orders the provided rules in order of importance, so that + * they can easily be executed later without weird checks ... + * + * "Callbacks" are given the highest priority (always called), + * followed by 'required' (called if callbacks didn't fail), + * and then every next rule depends on the previous one passing. + * + * @param array $rules + * @return array + */ + protected function _prepare_rules($rules) + { + $new_rules = array(); + $callbacks = array(); + + foreach ($rules as &$rule) + { + // Let 'required' always be the first (non-callback) rule + if ($rule === 'required') + { + array_unshift($new_rules, 'required'); + } + // 'isset' is a kind of a weird alias for 'required' ... + elseif ($rule === 'isset' && (empty($new_rules) OR $new_rules[0] !== 'required')) + { + array_unshift($new_rules, 'isset'); + } + // The old/classic 'callback_'-prefixed rules + elseif (is_string($rule) && strncmp('callback_', $rule, 9) === 0) + { + $callbacks[] = $rule; + } + // Proper callables + elseif (is_callable($rule)) + { + $callbacks[] = $rule; + } + // "Named" callables; i.e. array('name' => $callable) + elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1])) + { + $callbacks[] = $rule; + } + // Everything else goes at the end of the queue + else + { + $new_rules[] = $rule; + } + } + + return array_merge($callbacks, $new_rules); + } + + // -------------------------------------------------------------------- + /** * Traverse a multidimensional $_POST array index until the data is found * @@ -580,70 +637,7 @@ class CI_Form_validation { return; } - // If the field is blank, but NOT required, no further tests are necessary - $callback = FALSE; - if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === '')) - { - // Before we bail out, does the rule contain a callback? - foreach ($rules as &$rule) - { - if (is_string($rule)) - { - if (strncmp($rule, 'callback_', 9) === 0) - { - $callback = TRUE; - $rules = array(1 => $rule); - break; - } - } - elseif (is_callable($rule)) - { - $callback = TRUE; - $rules = array(1 => $rule); - break; - } - elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1])) - { - $callback = TRUE; - $rules = array(array($rule[0], $rule[1])); - break; - } - } - - if ( ! $callback) - { - return; - } - } - - // Isset Test. Typically this rule will only apply to checkboxes. - if (($postdata === NULL OR $postdata === '') && ! $callback) - { - if (in_array('isset', $rules, TRUE) OR in_array('required', $rules)) - { - // Set the message type - $type = in_array('required', $rules) ? 'required' : 'isset'; - - $line = $this->_get_error_message($type, $row['field']); - - // Build the error message - $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label'])); - - // Save the error message - $this->_field_data[$row['field']]['error'] = $message; - - if ( ! isset($this->_error_array[$row['field']])) - { - $this->_error_array[$row['field']] = $message; - } - } - - return; - } - - // -------------------------------------------------------------------- - - // Cycle through each rule and run it + $rules = $this->_prepare_rules($rules); foreach ($rules as $rule) { $_in_array = FALSE; @@ -702,6 +696,17 @@ class CI_Form_validation { $param = $match[2]; } + // Ignore empty, non-required inputs with a few exceptions ... + if ( + ($postdata === NULL OR $postdata === '') + && $callback === FALSE + && $callable === FALSE + && ! in_array($rule, array('required', 'isset', 'matches'), TRUE) + ) + { + continue; + } + // Call the function that corresponds to the rule if ($callback OR $callable !== FALSE) { @@ -740,12 +745,6 @@ class CI_Form_validation { { $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result; } - - // If the field isn't required and we just processed a callback we'll move on... - if ( ! in_array('required', $rules, TRUE) && $result !== FALSE) - { - continue; - } } elseif ( ! method_exists($this, $rule)) { @@ -1055,7 +1054,9 @@ class CI_Form_validation { */ public function required($str) { - return is_array($str) ? (bool) count($str) : (trim($str) !== ''); + return is_array($str) + ? (empty($str) === FALSE) + : (trim($str) !== ''); } // -------------------------------------------------------------------- @@ -1199,7 +1200,7 @@ class CI_Form_validation { { return FALSE; } - elseif ( ! in_array($matches[1], array('http', 'https'), TRUE)) + elseif ( ! in_array(strtolower($matches[1]), array('http', 'https'), TRUE)) { return FALSE; } @@ -1215,18 +1216,7 @@ class CI_Form_validation { $str = 'ipv6.host'.substr($str, strlen($matches[1]) + 2); } - $str = 'http://'.$str; - - // There's a bug affecting PHP 5.2.13, 5.3.2 that considers the - // underscore to be a valid hostname character instead of a dash. - // Reference: https://bugs.php.net/bug.php?id=51192 - if (version_compare(PHP_VERSION, '5.2.13', '==') OR version_compare(PHP_VERSION, '5.3.2', '==')) - { - sscanf($str, 'http://%[^/]', $host); - $str = substr_replace($str, strtr($host, array('_' => '-', '-' => '_')), 7, strlen($host)); - } - - return (filter_var($str, FILTER_VALIDATE_URL) !== FALSE); + return (filter_var('http://'.$str, FILTER_VALIDATE_URL) !== FALSE); } // -------------------------------------------------------------------- @@ -1239,9 +1229,16 @@ class CI_Form_validation { */ public function valid_email($str) { - if (function_exists('idn_to_ascii') && $atpos = strpos($str, '@')) + if (function_exists('idn_to_ascii') && preg_match('#\A([^@]+)@(.+)\z#', $str, $matches)) { - $str = substr($str, 0, ++$atpos).idn_to_ascii(substr($str, $atpos)); + $domain = defined('INTL_IDNA_VARIANT_UTS46') + ? idn_to_ascii($matches[2], 0, INTL_IDNA_VARIANT_UTS46) + : idn_to_ascii($matches[2]); + + if ($domain !== FALSE) + { + $str = $matches[1].'@'.$domain; + } } return (bool) filter_var($str, FILTER_VALIDATE_EMAIL); diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php index 88f2658..2885b55 100644 --- a/system/libraries/Ftp.php +++ b/system/libraries/Ftp.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -486,7 +486,7 @@ class CI_FTP { { for ($i = 0, $c = count($list); $i < $c; $i++) { - // If we can't delete the item it's probaly a directory, + // If we can't delete the item it's probably a directory, // so we'll recursively call delete_dir() if ( ! preg_match('#/\.\.?$#', $list[$i]) && ! @ftp_delete($this->conn_id, $list[$i])) { diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php index f594b71..a5cb6fb 100644 --- a/system/libraries/Image_lib.php +++ b/system/libraries/Image_lib.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -392,6 +392,16 @@ class CI_Image_lib { $this->initialize($props); } + /** + * A work-around for some improperly formatted, but + * usable JPEGs; known to be produced by Samsung + * smartphones' front-facing cameras. + * + * @see https://github.com/bcit-ci/CodeIgniter/issues/4967 + * @see https://bugs.php.net/bug.php?id=72404 + */ + ini_set('gd.jpeg_ignore_warning', 1); + log_message('info', 'Image Lib Class Initialized'); } @@ -456,7 +466,7 @@ class CI_Image_lib { { if (property_exists($this, $key)) { - if (in_array($key, array('wm_font_color', 'wm_shadow_color'))) + if (in_array($key, array('wm_font_color', 'wm_shadow_color'), TRUE)) { if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches)) { @@ -478,6 +488,10 @@ class CI_Image_lib { continue; } } + elseif (in_array($key, array('width', 'height'), TRUE) && ! ctype_digit((string) $val)) + { + continue; + } $this->$key = $val; } @@ -540,37 +554,30 @@ class CI_Image_lib { */ if ($this->new_image === '') { - $this->dest_image = $this->source_image; + $this->dest_image = $this->source_image; $this->dest_folder = $this->source_folder; } - elseif (strpos($this->new_image, '/') === FALSE) + elseif (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE) { + $this->dest_image = $this->new_image; $this->dest_folder = $this->source_folder; - $this->dest_image = $this->new_image; } else { - if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE) + // Is there a file name? + if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $this->new_image)) { - $full_dest_path = str_replace('\\', '/', realpath($this->new_image)); + $this->dest_image = $this->source_image; + $this->dest_folder = $this->new_image; } else { - $full_dest_path = $this->new_image; + $x = explode('/', str_replace('\\', '/', $this->new_image)); + $this->dest_image = end($x); + $this->dest_folder = str_replace($this->dest_image, '', $this->new_image); } - // Is there a file name? - if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $full_dest_path)) - { - $this->dest_folder = $full_dest_path.'/'; - $this->dest_image = $this->source_image; - } - else - { - $x = explode('/', $full_dest_path); - $this->dest_image = end($x); - $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path); - } + $this->dest_folder = realpath($this->dest_folder).'/'; } /* Compile the finalized filenames/paths @@ -828,7 +835,10 @@ class CI_Image_lib { imagedestroy($dst_img); imagedestroy($src_img); - chmod($this->full_dst_path, $this->file_permissions); + if ($this->dynamic_output !== TRUE) + { + chmod($this->full_dst_path, $this->file_permissions); + } return TRUE; } @@ -862,27 +872,28 @@ class CI_Image_lib { if ($action === 'crop') { - $cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis.' "'.$this->full_src_path.'" "'.$this->full_dst_path .'" 2>&1'; + $cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis; } elseif ($action === 'rotate') { - $angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt') - ? '-flop' : '-rotate '.$this->rotation_angle; - - $cmd .= ' '.$angle.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1'; + $cmd .= ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt') + ? ' -flop' + : ' -rotate '.$this->rotation_angle; } else // Resize { if($this->maintain_ratio === TRUE) { - $cmd .= ' -resize '.$this->width.'x'.$this->height.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1'; + $cmd .= ' -resize '.$this->width.'x'.$this->height; } else { - $cmd .= ' -resize '.$this->width.'x'.$this->height.'\! "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1'; + $cmd .= ' -resize '.$this->width.'x'.$this->height.'\!'; } } + $cmd .= ' '.escapeshellarg($this->full_src_path).' '.escapeshellarg($this->full_dst_path).' 2>&1'; + $retval = 1; // exec() might be disabled if (function_usable('exec')) @@ -964,7 +975,7 @@ class CI_Image_lib { $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height; } - $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp'; + $cmd = $this->library_path.$cmd_in.' '.escapeshellarg($this->full_src_path).' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp'; $retval = 1; // exec() might be disabled @@ -1641,25 +1652,31 @@ class CI_Image_lib { } $vals = getimagesize($path); + if ($vals === FALSE) + { + $this->set_error('imglib_invalid_image'); + return FALSE; + } + $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); - $mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg'; + $mime = isset($types[$vals[2]]) ? 'image/'.$types[$vals[2]] : 'image/jpg'; if ($return === TRUE) { return array( - 'width' => $vals[0], - 'height' => $vals[1], - 'image_type' => $vals[2], - 'size_str' => $vals[3], - 'mime_type' => $mime - ); + 'width' => $vals[0], + 'height' => $vals[1], + 'image_type' => $vals[2], + 'size_str' => $vals[3], + 'mime_type' => $mime + ); } - $this->orig_width = $vals[0]; - $this->orig_height = $vals[1]; - $this->image_type = $vals[2]; - $this->size_str = $vals[3]; - $this->mime_type = $mime; + $this->orig_width = $vals[0]; + $this->orig_height = $vals[1]; + $this->image_type = $vals[2]; + $this->size_str = $vals[3]; + $this->mime_type = $mime; return TRUE; } diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php index dcf9337..ec5fe59 100644 --- a/system/libraries/Javascript.php +++ b/system/libraries/Javascript.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php index 9df1be1..70f9aac 100644 --- a/system/libraries/Javascript/Jquery.php +++ b/system/libraries/Javascript/Jquery.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php index 0771cb5..2c4f34a 100644 --- a/system/libraries/Migration.php +++ b/system/libraries/Migration.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -211,7 +211,7 @@ class CI_Migration { if ($target_version > 0 && ! isset($migrations[$target_version])) { - $this->_error_string = sprintf(lang('migration_not_found'), $target_version); + $this->_error_string = sprintf($this->lang->line('migration_not_found'), $target_version); return FALSE; } @@ -272,7 +272,7 @@ class CI_Migration { { if (isset($previous) && abs($number - $previous) > 1) { - $this->_error_string = sprintf(lang('migration_sequence_gap'), $number); + $this->_error_string = sprintf($this->lang->line('migration_sequence_gap'), $number); return FALSE; } @@ -285,15 +285,12 @@ class CI_Migration { // Validate the migration file structure if ( ! class_exists($class, FALSE)) { - $this->_error_string = sprintf(lang('migration_class_doesnt_exist'), $class); + $this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class); return FALSE; } - // method_exists() returns true for non-public methods, - // while is_callable() can't be used without instantiating. - // Only get_class_methods() satisfies both conditions. - elseif ( ! in_array($method, array_map('strtolower', get_class_methods($class)))) + elseif ( ! is_callable(array($class, $method))) { - $this->_error_string = sprintf(lang('migration_missing_'.$method.'_method'), $class); + $this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class); return FALSE; } @@ -336,7 +333,7 @@ class CI_Migration { if (empty($migrations)) { - $this->_error_string = lang('migration_none_found'); + $this->_error_string = $this->lang->line('migration_none_found'); return FALSE; } @@ -395,7 +392,7 @@ class CI_Migration { // There cannot be duplicate migration numbers if (isset($migrations[$number])) { - $this->_error_string = sprintf(lang('migration_multiple_version'), $number); + $this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $number); show_error($this->_error_string); } diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index 44f848f..3fe3d3a 100644 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -339,6 +339,10 @@ class CI_Pagination { } } + // _parse_attributes(), called by initialize(), needs to run at least once + // in order to enable "rel" attributes, and this triggers it. + isset($params['attributes']) OR $params['attributes'] = array(); + $this->initialize($params); log_message('info', 'Pagination Class Initialized'); } @@ -353,8 +357,7 @@ class CI_Pagination { */ public function initialize(array $params = array()) { - isset($params['attributes']) OR $params['attributes'] = array(); - if (is_array($params['attributes'])) + if (isset($params['attributes']) && is_array($params['attributes'])) { $this->_parse_attributes($params['attributes']); unset($params['attributes']); @@ -428,7 +431,7 @@ class CI_Pagination { { $get = $this->CI->input->get(); - // Unset the controll, method, old-school routing options + // Unset the control, method, old-school routing options unset($get['c'], $get['m'], $get[$this->query_string_segment]); } else diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php index 22cffb2..1534e4d 100644 --- a/system/libraries/Parser.php +++ b/system/libraries/Parser.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index cf455d3..3294cdf 100644 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -316,7 +316,7 @@ class CI_Profiler { { is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'"; $val = (is_array($val) OR is_object($val)) - ? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
+					? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset')).'
' : htmlspecialchars($val, ENT_QUOTES, config_item('charset')); $output .= '$_GET[' @@ -356,7 +356,7 @@ class CI_Profiler { { is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'"; $val = (is_array($val) OR is_object($val)) - ? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
+					? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset')).'
' : htmlspecialchars($val, ENT_QUOTES, config_item('charset')); $output .= '$_POST[' @@ -368,7 +368,7 @@ class CI_Profiler { { is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'"; $val = (is_array($val) OR is_object($val)) - ? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
+					? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset')).'
' : htmlspecialchars($val, ENT_QUOTES, config_item('charset')); $output .= '$_FILES[' @@ -484,13 +484,19 @@ class CI_Profiler { foreach ($this->CI->config->config as $config => $val) { + $pre = ''; + $pre_close = ''; + if (is_array($val) OR is_object($val)) { $val = print_r($val, TRUE); + + $pre = '
' ;
+ 				$pre_close = '
'; } $output .= '' - .$config.'  '.htmlspecialchars($val)."\n"; + .$config.'  '.$pre.htmlspecialchars($val, ENT_QUOTES, config_item('charset')).$pre_close."\n"; } return $output."\n"; @@ -516,13 +522,19 @@ class CI_Profiler { foreach ($this->CI->session->userdata() as $key => $val) { + $pre = ''; + $pre_close = ''; + if (is_array($val) OR is_object($val)) { $val = print_r($val, TRUE); + + $pre = '
' ;
+ 				$pre_close = '
'; } $output .= '' - .$key.'  '.htmlspecialchars($val)."\n"; + .$key.'  '.$pre.htmlspecialchars($val, ENT_QUOTES, config_item('charset')).$pre_close."\n"; } return $output."\n"; diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index c9d2e8a..aa1fafb 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 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 @@ -57,6 +57,7 @@ class CI_Session { protected $_driver = 'files'; protected $_config; + protected $_sid_regexp; // ------------------------------------------------------------------------ @@ -91,6 +92,7 @@ class CI_Session { // Note: BC workaround elseif (config_item('sess_use_database')) { + log_message('debug', 'Session: "sess_driver" is empty; using BC fallback to "sess_use_database".'); $this->_driver = 'database'; } @@ -98,6 +100,7 @@ class CI_Session { // Configuration ... $this->_configure($params); + $this->_config['_sid_regexp'] = $this->_sid_regexp; $class = new $class($this->_config); if ($class instanceof SessionHandlerInterface) @@ -130,7 +133,7 @@ class CI_Session { if (isset($_COOKIE[$this->_config['cookie_name']]) && ( ! is_string($_COOKIE[$this->_config['cookie_name']]) - OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']]) + OR ! preg_match('#\A'.$this->_sid_regexp.'\z#', $_COOKIE[$this->_config['cookie_name']]) ) ) { @@ -238,10 +241,8 @@ class CI_Session { { return $prefix.$class; } - else - { - log_message('debug', 'Session: '.$prefix.$class.".php found but it doesn't declare class ".$prefix.$class.'.'); - } + + log_message('debug', 'Session: '.$prefix.$class.".php found but it doesn't declare class ".$prefix.$class.'.'); } return 'CI_'.$class; @@ -314,8 +315,82 @@ class CI_Session { ini_set('session.use_strict_mode', 1); ini_set('session.use_cookies', 1); ini_set('session.use_only_cookies', 1); - ini_set('session.hash_function', 1); - ini_set('session.hash_bits_per_character', 4); + + $this->_configure_sid_length(); + } + + // ------------------------------------------------------------------------ + + /** + * Configure session ID length + * + * To make life easier, we used to force SHA-1 and 4 bits per + * character on everyone. And of course, someone was unhappy. + * + * Then PHP 7.1 broke backwards-compatibility because ext/session + * is such a mess that nobody wants to touch it with a pole stick, + * and the one guy who does, nobody has the energy to argue with. + * + * So we were forced to make changes, and OF COURSE something was + * going to break and now we have this pile of shit. -- Narf + * + * @return void + */ + protected function _configure_sid_length() + { + if (PHP_VERSION_ID < 70100) + { + $hash_function = ini_get('session.hash_function'); + if (ctype_digit($hash_function)) + { + if ($hash_function !== '1') + { + ini_set('session.hash_function', 1); + } + + $bits = 160; + } + elseif ( ! in_array($hash_function, hash_algos(), TRUE)) + { + ini_set('session.hash_function', 1); + $bits = 160; + } + elseif (($bits = strlen(hash($hash_function, 'dummy', false)) * 4) < 160) + { + ini_set('session.hash_function', 1); + $bits = 160; + } + + $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + $sid_length = (int) ceil($bits / $bits_per_character); + } + else + { + $bits_per_character = (int) ini_get('session.sid_bits_per_character'); + $sid_length = (int) ini_get('session.sid_length'); + if (($bits = $sid_length * $bits_per_character) < 160) + { + // Add as many more characters as necessary to reach at least 160 bits + $sid_length += (int) ceil((160 % $bits) / $bits_per_character); + ini_set('session.sid_length', $sid_length); + } + } + + // Yes, 4,5,6 are the only known possible values as of 2016-10-27 + switch ($bits_per_character) + { + case 4: + $this->_sid_regexp = '[0-9a-f]'; + break; + case 5: + $this->_sid_regexp = '[0-9a-v]'; + break; + case 6: + $this->_sid_regexp = '[0-9a-zA-Z,-]'; + break; + } + + $this->_sid_regexp .= '{'.$sid_length.'}'; } // ------------------------------------------------------------------------ @@ -529,7 +604,7 @@ class CI_Session { // ------------------------------------------------------------------------ /** - * Unmark flash + * Unmark temp * * @param mixed $key Session data key(s) * @return void @@ -729,7 +804,7 @@ class CI_Session { * * Legacy CI_Session compatibility method * - * @param mixed $data Session data key(s) + * @param mixed $key Session data key(s) * @return void */ public function unset_userdata($key) diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index b3533dd..db0bc7d 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 55ddb25..2fe30b8 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 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -112,6 +112,23 @@ abstract class CI_Session_driver implements SessionHandlerInterface { // ------------------------------------------------------------------------ + /** + * PHP 5.x validate ID + * + * Enforces session.use_strict_mode on PHP 5.x (7+ does it by itself) + * + * @return void + */ + public function php5_validate_id() + { + if (PHP_VERSION_ID < 70000 && isset($_COOKIE[$this->_config['cookie_name']]) && ! $this->validateId($_COOKIE[$this->_config['cookie_name']])) + { + unset($_COOKIE[$this->_config['cookie_name']]); + } + } + + // ------------------------------------------------------------------------ + /** * Cookie destroy * diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 317bd7d..074accf 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 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -109,7 +109,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } // Note: BC work-around for the old 'sess_table_name' setting, should be removed in the future. - isset($this->_config['save_path']) OR $this->_config['save_path'] = config_item('sess_table_name'); + if ( ! isset($this->_config['save_path']) && ($this->_config['save_path'] = config_item('sess_table_name'))) + { + log_message('debug', 'Session: "sess_save_path" is empty; using BC fallback to "sess_table_name".'); + } } // ------------------------------------------------------------------------ @@ -130,6 +133,8 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return $this->_fail(); } + $this->php5_validate_id(); + return $this->_success; } @@ -206,7 +211,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_db->reset_query(); // Was the ID regenerated? - if ($session_id !== $this->_session_id) + if (isset($this->_session_id) && $session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { @@ -337,6 +342,30 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan : $this->_fail(); } + // -------------------------------------------------------------------- + + /** + * Validate ID + * + * Checks whether a session ID record exists server-side, + * to enforce session.use_strict_mode. + * + * @param string $id + * @return bool + */ + public function validateId($id) + { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + + $this->_db->select('1')->from($this->_config['save_path'])->where('id', $id); + empty($this->_config['match_ip']) OR $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); + $result = $this->_db->get(); + empty($result) OR $result = $result->row(); + + return ! empty($result); + } + // ------------------------------------------------------------------------ /** @@ -351,7 +380,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ($this->_platform === 'mysql') { - $arg = $session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + $arg = md5($session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : '')); if ($this->_db->query("SELECT GET_LOCK('".$arg."', 300) AS ci_session_lock")->row()->ci_session_lock) { $this->_lock = $arg; @@ -414,4 +443,4 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return parent::_release_lock(); } -} \ No newline at end of file +} diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 119bf65..654f300 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 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -76,6 +76,20 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ protected $_file_new; + /** + * Validate SID regular expression + * + * @var string + */ + protected $_sid_regexp; + + /** + * mbstring.func_overload flag + * + * @var bool + */ + protected static $func_overload; + // ------------------------------------------------------------------------ /** @@ -95,8 +109,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } else { + log_message('debug', 'Session: "sess_save_path" is empty; using "session.save_path" value from php.ini.'); $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } + + $this->_sid_regexp = $this->_config['_sid_regexp']; + + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); } // ------------------------------------------------------------------------ @@ -129,6 +148,8 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle .$name // we'll use the session cookie name as a prefix to avoid collisions .($this->_config['match_ip'] ? md5($_SERVER['REMOTE_ADDR']) : ''); + $this->php5_validate_id(); + return $this->_success; } @@ -148,18 +169,9 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // which re-reads session data if ($this->_file_handle === NULL) { - // Just using fopen() with 'c+b' mode would be perfect, but it is only - // available since PHP 5.2.6 and we have to set permissions for new files, - // so we'd have to hack around this ... - if (($this->_file_new = ! file_exists($this->_file_path.$session_id)) === TRUE) - { - if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) - { - log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); - return $this->_failure; - } - } - elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) + $this->_file_new = ! file_exists($this->_file_path.$session_id); + + if (($this->_file_handle = fopen($this->_file_path.$session_id, 'c+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); return $this->_failure; @@ -195,7 +207,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } $session_data = ''; - for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += strlen($buffer)) + for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += self::strlen($buffer)) { if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE) { @@ -351,10 +363,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $ts = time() - $maxlifetime; + $pattern = ($this->_config['match_ip'] === TRUE) + ? '[0-9a-f]{32}' + : ''; + $pattern = sprintf( - '/^%s[0-9a-f]{%d}$/', - preg_quote($this->_config['cookie_name'], '/'), - ($this->_config['match_ip'] === TRUE ? 72 : 40) + '#\A%s'.$pattern.$this->_sid_regexp.'\z#', + preg_quote($this->_config['cookie_name']) ); while (($file = readdir($directory)) !== FALSE) @@ -376,4 +391,34 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle return $this->_success; } -} \ No newline at end of file + // -------------------------------------------------------------------- + + /** + * Validate ID + * + * Checks whether a session ID record exists server-side, + * to enforce session.use_strict_mode. + * + * @param string $id + * @return bool + */ + public function validateId($id) + { + return is_file($this->_file_path.$id); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } +} diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 88eb4b3..7d8e390 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 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -145,6 +145,8 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_fail(); } + $this->php5_validate_id(); + return $this->_success; } @@ -186,7 +188,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa */ public function write($session_id, $session_data) { - if ( ! isset($this->_memcached)) + if ( ! isset($this->_memcached, $this->_lock_key)) { return $this->_fail(); } @@ -202,32 +204,25 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_session_id = $session_id; } - if (isset($this->_lock_key)) + $key = $this->_key_prefix.$session_id; + + $this->_memcached->replace($this->_lock_key, time(), 300); + if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { - $key = $this->_key_prefix.$session_id; - - $this->_memcached->replace($this->_lock_key, time(), 300); - if ($this->_fingerprint !== ($fingerprint = md5($session_data))) - { - if ( - $this->_memcached->replace($key, $session_data, $this->_config['expiration']) - OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) - ) - { - $this->_fingerprint = $fingerprint; - return $this->_success; - } - - return $this->_fail(); - } - - if ( - $this->_memcached->touch($key, $this->_config['expiration']) - OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) - ) + if ($this->_memcached->set($key, $session_data, $this->_config['expiration'])) { + $this->_fingerprint = $fingerprint; return $this->_success; } + + return $this->_fail(); + } + elseif ( + $this->_memcached->touch($key, $this->_config['expiration']) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + ) + { + return $this->_success; } return $this->_fail(); @@ -297,6 +292,23 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_success; } + // -------------------------------------------------------------------- + + /** + * Validate ID + * + * Checks whether a session ID record exists server-side, + * to enforce session.use_strict_mode. + * + * @param string $id + * @return bool + */ + public function validateId($id) + { + $this->_memcached-get($this->_key_prefix.$id); + return ($this->_memcached->getResultCode() === Memcached::RES_SUCCESS); + } + // ------------------------------------------------------------------------ /** @@ -317,9 +329,11 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if ( ! $this->_memcached->replace($this->_lock_key, time(), 300)) { return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) - ? $this->_memcached->set($this->_lock_key, time(), 300) + ? $this->_memcached->add($this->_lock_key, time(), 300) : FALSE; } + + return TRUE; } // 30 attempts to obtain a lock, in case another request already has it @@ -333,7 +347,8 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa continue; } - if ( ! $this->_memcached->set($lock_key, time(), 300)) + $method = ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) ? 'add' : 'set'; + if ( ! $this->_memcached->$method($lock_key, time(), 300)) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); return FALSE; @@ -379,4 +394,4 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return TRUE; } -} \ No newline at end of file +} diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index e4e09fe..d7a5755 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 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -51,7 +51,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle /** * phpRedis instance * - * @var resource + * @var Redis */ protected $_redis; @@ -153,6 +153,8 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $this->_success; } + $this->php5_validate_id(); + return $this->_fail(); } @@ -199,7 +201,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle */ public function write($session_id, $session_data) { - if ( ! isset($this->_redis)) + if ( ! isset($this->_redis, $this->_lock_key)) { return $this->_fail(); } @@ -215,27 +217,22 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle $this->_session_id = $session_id; } - if (isset($this->_lock_key)) + $this->_redis->setTimeout($this->_lock_key, 300); + if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) { - $this->_redis->setTimeout($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'])) { - if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) - { - $this->_fingerprint = $fingerprint; - $this->_key_exists = TRUE; - return $this->_success; - } - - return $this->_fail(); + $this->_fingerprint = $fingerprint; + $this->_key_exists = TRUE; + return $this->_success; } - return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) - ? $this->_success - : $this->_fail(); + return $this->_fail(); } - return $this->_fail(); + return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) + ? $this->_success + : $this->_fail(); } // ------------------------------------------------------------------------ @@ -255,7 +252,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if ($this->_redis->ping() === '+PONG') { $this->_release_lock(); - if ($this->_redis->close() === $this->_failure) + if ($this->_redis->close() === FALSE) { return $this->_fail(); } @@ -315,6 +312,22 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $this->_success; } + // -------------------------------------------------------------------- + + /** + * Validate ID + * + * Checks whether a session ID record exists server-side, + * to enforce session.use_strict_mode. + * + * @param string $id + * @return bool + */ + public function validateId($id) + { + return (bool) $this->_redis->exists($this->_key_prefix.$id); + } + // ------------------------------------------------------------------------ /** @@ -346,7 +359,11 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle continue; } - if ( ! $this->_redis->setex($lock_key, 300, time())) + $result = ($ttl === -2) + ? $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300)) + : $this->_redis->setex($lock_key, 300, time()); + + if ( ! $result) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); return FALSE; diff --git a/system/libraries/Table.php b/system/libraries/Table.php index 3bce294..36da513 100644 --- a/system/libraries/Table.php +++ b/system/libraries/Table.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.1 @@ -277,6 +277,7 @@ class CI_Table { public function set_caption($caption) { $this->caption = $caption; + return $this; } // -------------------------------------------------------------------- @@ -434,7 +435,7 @@ class CI_Table { /** * Set table data from a database result object * - * @param CI_DB_result $db_result Database result object + * @param CI_DB_result $object Database result object * @return void */ protected function _set_from_db_result($object) diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php index a9b2564..228794d 100644 --- a/system/libraries/Trackback.php +++ b/system/libraries/Trackback.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -370,7 +370,7 @@ class CI_Trackback { { $url = trim($url); - if (strpos($url, 'http') !== 0) + if (stripos($url, 'http') !== 0) { $url = 'http://'.$url; } diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php index c45398b..bfc9934 100644 --- a/system/libraries/Typography.php +++ b/system/libraries/Typography.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -241,7 +241,7 @@ class CI_Typography { // Clean up stray paragraph tags that appear before block level elements '#

<('.$this->block_elements.')#' => '<$1', - // Clean up stray non-breaking spaces preceeding block elements + // Clean up stray non-breaking spaces preceding block elements '#( \s*)+<('.$this->block_elements.')#' => ' <$2', // Replace the temporary markers we added earlier diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php index 3ac6af7..fa87e03 100644 --- a/system/libraries/Unit_test.php +++ b/system/libraries/Unit_test.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.1 @@ -154,7 +154,6 @@ class CI_Unit_test { if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null', 'is_resource'), TRUE)) { - $expected = str_replace('is_double', 'is_float', $expected); $result = $expected($test); $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected)); } @@ -291,7 +290,7 @@ class CI_Unit_test { { continue; } - elseif (in_array($key, array('test_name', 'test_datatype', 'test_res_datatype', 'result'), TRUE)) + elseif (in_array($key, array('test_name', 'test_datatype', 'res_datatype', 'result'), TRUE)) { if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val), FALSE))) { diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index f241837..8e6bdfa 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -286,7 +286,7 @@ class CI_Upload { /** * Constructor * - * @param array $props + * @param array $config * @return void */ public function __construct($config = array()) @@ -601,7 +601,7 @@ class CI_Upload { 'file_type' => $this->file_type, 'file_path' => $this->upload_path, 'full_path' => $this->upload_path.$this->file_name, - 'raw_name' => str_replace($this->file_ext, '', $this->file_name), + 'raw_name' => substr($this->file_name, 0, -strlen($this->file_ext)), 'orig_name' => $this->orig_name, 'client_name' => $this->client_name, 'file_ext' => $this->file_ext, @@ -678,10 +678,8 @@ class CI_Upload { $this->set_error('upload_bad_filename', 'debug'); return FALSE; } - else - { - return $new_filename; - } + + return $new_filename; } // -------------------------------------------------------------------- @@ -1083,16 +1081,27 @@ class CI_Upload { return FALSE; } - if (memory_get_usage() && ($memory_limit = ini_get('memory_limit'))) + if (memory_get_usage() && ($memory_limit = ini_get('memory_limit')) > 0) { - $memory_limit *= 1024 * 1024; - - // There was a bug/behavioural change in PHP 5.2, where numbers over one million get output - // into scientific notation. number_format() ensures this number is an integer - // http://bugs.php.net/bug.php?id=43053 - - $memory_limit = number_format(ceil(filesize($file) + $memory_limit), 0, '.', ''); + $memory_limit = str_split($memory_limit, strspn($memory_limit, '1234567890')); + if ( ! empty($memory_limit[1])) + { + switch ($memory_limit[1][0]) + { + case 'g': + case 'G': + $memory_limit[0] *= 1024 * 1024 * 1024; + break; + case 'm': + case 'M': + $memory_limit[0] *= 1024 * 1024; + break; + default: + break; + } + } + $memory_limit = (int) ceil(filesize($file) + $memory_limit[0]); ini_set('memory_limit', $memory_limit); // When an integer is used, the value is measured in bytes. - PHP.net } @@ -1207,10 +1216,13 @@ class CI_Upload { // We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii) $regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/'; - /* Fileinfo extension - most reliable method + /** + * Fileinfo extension - most reliable method * - * Unfortunately, prior to PHP 5.3 - it's only available as a PECL extension and the - * more convenient FILEINFO_MIME_TYPE flag doesn't exist. + * Apparently XAMPP, CentOS, cPanel and who knows what + * other PHP distribution channels EXPLICITLY DISABLE + * ext/fileinfo, which is otherwise enabled by default + * since PHP 5.3 ... */ if (function_exists('finfo_file')) { @@ -1298,7 +1310,7 @@ class CI_Upload { } } - // Fall back to the deprecated mime_content_type(), if available (still better than $_FILES[$field]['type']) + // Fall back to mime_content_type(), if available (still better than $_FILES[$field]['type']) if (function_exists('mime_content_type')) { $this->file_type = @mime_content_type($file['tmp_name']); diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index c4e1159..b1a011f 100644 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -173,13 +173,11 @@ class CI_User_agent { */ public function __construct() { + $this->_load_agent_file(); + if (isset($_SERVER['HTTP_USER_AGENT'])) { $this->agent = trim($_SERVER['HTTP_USER_AGENT']); - } - - if ($this->agent !== NULL && $this->_load_agent_file()) - { $this->_compile_data(); } diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index f965858..c23504d 100644 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -238,7 +238,7 @@ class CI_Xmlrpc { public $result; /** - * XML-RPC Reponse + * XML-RPC Response * * @var array */ @@ -352,7 +352,7 @@ class CI_Xmlrpc { */ public function server($url, $port = 80, $proxy = FALSE, $proxy_port = 8080) { - if (strpos($url, 'http') !== 0) + if (stripos($url, 'http') !== 0) { $url = 'http://'.$url; } @@ -460,7 +460,7 @@ class CI_Xmlrpc { { if (is_array($value[0]) && ($value[1] === 'struct' OR $value[1] === 'array')) { - while (list($k) = each($value[0])) + foreach (array_keys($value[0]) as $k) { $value[0][$k] = $this->values_parsing($value[0][$k]); } @@ -735,6 +735,8 @@ class XML_RPC_Client extends CI_Xmlrpc .'Content-Length: '.strlen($msg->payload).$r.$r .$msg->payload; + stream_set_timeout($fp, $this->timeout); // set timeout for subsequent operations + for ($written = $timestamp = 0, $length = strlen($op); $written < $length; $written += $result) { if (($result = fwrite($fp, substr($op, $written))) === FALSE) @@ -753,9 +755,6 @@ class XML_RPC_Client extends CI_Xmlrpc $result = FALSE; break; } - - usleep(250000); - continue; } else { @@ -932,15 +931,15 @@ class XML_RPC_Response if (is_array($array)) { - while (list($key) = each($array)) + foreach ($array as $key => &$value) { - if (is_array($array[$key])) + if (is_array($value)) { - $array[$key] = $this->decode($array[$key]); + $array[$key] = $this->decode($value); } elseif ($this->xss_clean) { - $array[$key] = $CI->security->xss_clean($array[$key]); + $array[$key] = $CI->security->xss_clean($value); } } @@ -994,10 +993,11 @@ class XML_RPC_Response reset($xmlrpc_val->me['struct']); $arr = array(); - while (list($key,$value) = each($xmlrpc_val->me['struct'])) + foreach ($xmlrpc_val->me['struct'] as $key => &$value) { $arr[$key] = $this->xmlrpc_decoder($value); } + return $arr; } } @@ -1181,7 +1181,7 @@ class XML_RPC_Message extends CI_Xmlrpc $data = implode("\r\n", $lines); // Parse XML data - if ( ! xml_parse($parser, $data, count($data))) + if ( ! xml_parse($parser, $data, TRUE)) { $errstr = sprintf('XML error: %s at line %d', xml_error_string(xml_get_error_code($parser)), @@ -1563,17 +1563,17 @@ class XML_RPC_Message extends CI_Xmlrpc if ( ! empty($array)) { - while (list($key) = each($array)) + foreach ($array as $key => &$value) { - if (is_array($array[$key])) + if (is_array($value)) { - $array[$key] = $this->output_parameters($array[$key]); + $array[$key] = $this->output_parameters($value); } elseif ($key !== 'bits' && $this->xss_clean) { // 'bits' is for the MetaWeblog API image bits // @todo - this needs to be made more general purpose - $array[$key] = $CI->security->xss_clean($array[$key]); + $array[$key] = $CI->security->xss_clean($value); } } @@ -1633,7 +1633,7 @@ class XML_RPC_Message extends CI_Xmlrpc reset($param->me['struct']); $arr = array(); - while (list($key,$value) = each($param->me['struct'])) + foreach ($param->me['struct'] as $key => &$value) { $arr[$key] = $this->decode_message($value); } @@ -1824,7 +1824,7 @@ class XML_RPC_Values extends CI_Xmlrpc // struct $rs .= "\n"; reset($val); - while (list($key2, $val2) = each($val)) + foreach ($val as $key2 => &$val2) { $rs .= "\n{$key2}\n".$this->serializeval($val2)."\n"; } @@ -1885,11 +1885,9 @@ class XML_RPC_Values extends CI_Xmlrpc */ public function serializeval($o) { - $ar = $o->me; - reset($ar); - - list($typ, $val) = each($ar); - return "\n".$this->serializedata($typ, $val)."\n"; + $array = $o->me; + list($value, $type) = array(reset($array), key($array)); + return "\n".$this->serializedata($type, $value)."\n"; } // -------------------------------------------------------------------- @@ -1901,8 +1899,7 @@ class XML_RPC_Values extends CI_Xmlrpc */ public function scalarval() { - reset($this->me); - return current($this->me); + return reset($this->me); } // -------------------------------------------------------------------- diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php index afcdbe6..4680bbf 100644 --- a/system/libraries/Xmlrpcs.php +++ b/system/libraries/Xmlrpcs.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -339,11 +339,11 @@ class CI_Xmlrpcs extends CI_Xmlrpc { //------------------------------------- $method_parts = explode('.', $this->methods[$methName]['function']); - $objectCall = (isset($method_parts[1]) && $method_parts[1] !== ''); + $objectCall = ! empty($method_parts[1]); if ($system_call === TRUE) { - if ( ! is_callable(array($this,$method_parts[1]))) + if ( ! is_callable(array($this, $method_parts[1]))) { return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); } @@ -400,17 +400,13 @@ class CI_Xmlrpcs extends CI_Xmlrpc { } elseif ($this->object === FALSE) { - return get_instance()->$method_parts[1]($m); - } - else - { - return $this->object->$method_parts[1]($m); + return get_instance()->{$method_parts[1]}($m); } + + return $this->object->{$method_parts[1]}($m); } - else - { - return call_user_func($this->methods[$methName]['function'], $m); - } + + return call_user_func($this->methods[$methName]['function'], $m); } // -------------------------------------------------------------------- @@ -499,10 +495,8 @@ class CI_Xmlrpcs extends CI_Xmlrpc { return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string')); } - else - { - return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']); - } + + return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']); } // -------------------------------------------------------------------- @@ -584,7 +578,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc { return $this->multicall_error('nomethod'); } - list($scalar_type, $scalar_value) = each($methName->me); + list($scalar_value, $scalar_type) = array(reset($methName->me), key($methName->me)); $scalar_type = $scalar_type === $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type; if ($methName->kindOf() !== 'scalar' OR $scalar_type !== 'string') @@ -604,7 +598,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc { return $this->multicall_error('notarray'); } - list($a, $b) = each($params->me); + list($b, $a) = array(reset($params->me), key($params->me)); $msg = new XML_RPC_Message($scalar_value); for ($i = 0, $numParams = count($b); $i < $numParams; $i++) diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php index 140ad72..f8f95fe 100644 --- a/system/libraries/Zip.php +++ b/system/libraries/Zip.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2018, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -105,6 +105,13 @@ class CI_Zip { */ public $compression_level = 2; + /** + * mbstring.func_overload flag + * + * @var bool + */ + protected static $func_overload; + /** * Initialize zip compression class * @@ -112,6 +119,8 @@ class CI_Zip { */ public function __construct() { + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + $this->now = time(); log_message('info', 'Zip Compression Class Initialized'); } @@ -182,7 +191,7 @@ class CI_Zip { .pack('V', 0) // crc32 .pack('V', 0) // compressed filesize .pack('V', 0) // uncompressed filesize - .pack('v', strlen($dir)) // length of pathname + .pack('v', self::strlen($dir)) // length of pathname .pack('v', 0) // extra field length .$dir // below is "data descriptor" segment @@ -197,7 +206,7 @@ class CI_Zip { .pack('V',0) // crc32 .pack('V',0) // compressed filesize .pack('V',0) // uncompressed filesize - .pack('v', strlen($dir)) // length of pathname + .pack('v', self::strlen($dir)) // length of pathname .pack('v', 0) // extra field length .pack('v', 0) // file comment length .pack('v', 0) // disk number start @@ -206,7 +215,7 @@ class CI_Zip { .pack('V', $this->offset) // relative offset of local header .$dir; - $this->offset = strlen($this->zipdata); + $this->offset = self::strlen($this->zipdata); $this->entries++; } @@ -255,10 +264,10 @@ class CI_Zip { { $filepath = str_replace('\\', '/', $filepath); - $uncompressed_size = strlen($data); + $uncompressed_size = self::strlen($data); $crc32 = crc32($data); - $gzdata = substr(gzcompress($data, $this->compression_level), 2, -4); - $compressed_size = strlen($gzdata); + $gzdata = self::substr(gzcompress($data, $this->compression_level), 2, -4); + $compressed_size = self::strlen($gzdata); $this->zipdata .= "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00" @@ -267,7 +276,7 @@ class CI_Zip { .pack('V', $crc32) .pack('V', $compressed_size) .pack('V', $uncompressed_size) - .pack('v', strlen($filepath)) // length of filename + .pack('v', self::strlen($filepath)) // length of filename .pack('v', 0) // extra field length .$filepath .$gzdata; // "file data" segment @@ -279,7 +288,7 @@ class CI_Zip { .pack('V', $crc32) .pack('V', $compressed_size) .pack('V', $uncompressed_size) - .pack('v', strlen($filepath)) // length of filename + .pack('v', self::strlen($filepath)) // length of filename .pack('v', 0) // extra field length .pack('v', 0) // file comment length .pack('v', 0) // disk number start @@ -288,7 +297,7 @@ class CI_Zip { .pack('V', $this->offset) // relative offset of local header .$filepath; - $this->offset = strlen($this->zipdata); + $this->offset = self::strlen($this->zipdata); $this->entries++; $this->file_num++; } @@ -401,8 +410,8 @@ class CI_Zip { .$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', strlen($this->directory)) // size of central dir - .pack('V', strlen($this->zipdata)) // offset to start of central dir + .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 } @@ -425,9 +434,9 @@ class CI_Zip { flock($fp, LOCK_EX); - for ($result = $written = 0, $data = $this->get_zip(), $length = strlen($data); $written < $length; $written += $result) + for ($result = $written = 0, $data = $this->get_zip(), $length = self::strlen($data); $written < $length; $written += $result) { - if (($result = fwrite($fp, substr($data, $written))) === FALSE) + if (($result = fwrite($fp, self::substr($data, $written))) === FALSE) { break; } @@ -481,4 +490,43 @@ class CI_Zip { return $this; } + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_overload) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } }