diff options
-rw-r--r-- | application/config/config.php | 2 | ||||
-rw-r--r-- | application/config/constants.php | 5 | ||||
-rw-r--r-- | application/config/foreign_chars.php | 60 | ||||
-rw-r--r-- | application/config/mimes.php | 1 | ||||
-rw-r--r-- | system/core/CodeIgniter.php | 7 | ||||
-rw-r--r-- | system/core/Common.php | 35 | ||||
-rw-r--r-- | system/core/Exceptions.php | 2 | ||||
-rw-r--r-- | system/core/Input.php | 31 | ||||
-rw-r--r-- | system/core/Loader.php | 2 | ||||
-rw-r--r-- | system/core/Log.php | 3 | ||||
-rw-r--r-- | system/core/Output.php | 37 | ||||
-rw-r--r-- | system/database/DB_query_builder.php | 4 | ||||
-rw-r--r-- | system/database/drivers/mysqli/mysqli_driver.php | 27 | ||||
-rw-r--r-- | system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php | 4 | ||||
-rw-r--r-- | system/database/drivers/postgre/postgre_driver.php | 12 | ||||
-rw-r--r-- | system/helpers/form_helper.php | 118 | ||||
-rw-r--r-- | system/libraries/Email.php | 3 | ||||
-rw-r--r-- | system/libraries/Upload.php | 2 | ||||
-rw-r--r-- | tests/mocks/core/common.php | 2 | ||||
-rw-r--r-- | user_guide_src/source/changelog.rst | 17 | ||||
-rw-r--r-- | user_guide_src/source/general/common_functions.rst | 3 | ||||
-rw-r--r-- | user_guide_src/source/libraries/form_validation.rst | 3 |
22 files changed, 212 insertions, 168 deletions
diff --git a/application/config/config.php b/application/config/config.php index 0608348c6..8d08a7401 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -282,7 +282,7 @@ $config['encryption_key'] = ''; | 'sess_driver' = the driver to load: cookie (Classic), native (PHP sessions), | or your custom driver name | 'sess_valid_drivers' = additional valid drivers which may be loaded -| 'sess_cookie_name' = the name you want for the cookie +| 'sess_cookie_name' = the name you want for the cookie, must contain only [0-9a-z_-] characters | 'sess_expiration' = the number of SECONDS you want the session to last. | by default sessions last 7200 seconds (two hours). Set to zero for no expiration. | 'sess_expire_on_close' = Whether to cause the session to expire automatically diff --git a/application/config/constants.php b/application/config/constants.php index dc84712cd..e71097b6c 100644 --- a/application/config/constants.php +++ b/application/config/constants.php @@ -81,11 +81,11 @@ define('SHOW_DEBUG_BACKTRACE', TRUE); | Used to indicate the conditions under which the script is exit()ing. | While there is no universal standard for error codes, there are some | broad conventions. Three such conventions are mentioned below, for -| those who wish to make use of them. The CodeIgniter defaults were +| those who wish to make use of them. The CodeIgniter defaults were | chosen for the least overlap with these conventions, while still | leaving room for others to be defined in future versions and user | applications. -| +| | The three main conventions used for determining exit status codes | are as follows: | @@ -108,7 +108,6 @@ define('EXIT_USER_INPUT', 7); // invalid user input define('EXIT_DATABASE', 8); // database error define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code - /* End of file constants.php */ /* Location: ./application/config/constants.php */
\ No newline at end of file diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php index b0c32cf96..ab98224f7 100644 --- a/application/config/foreign_chars.php +++ b/application/config/foreign_chars.php @@ -50,16 +50,16 @@ $foreign_characters = array( '/д/' => 'd', '/Ð|Ď|Đ|Δ/' => 'Dj', '/ð|ď|đ|δ/' => 'dj', - '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Ё|Э/' => 'E', - '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|ё|э/' => 'e', + '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E', + '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e', '/Ф/' => 'F', '/ф/' => 'f', - '/Ĝ|Ğ|Ġ|Ģ|Γ|Г/' => 'G', - '/ĝ|ğ|ġ|ģ|γ|г/' => 'g', + '/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G', + '/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g', '/Ĥ|Ħ/' => 'H', '/ĥ|ħ/' => 'h', - '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Й/' => 'I', - '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|й/' => 'i', + '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I', + '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i', '/Ĵ/' => 'J', '/ĵ/' => 'j', '/Ķ|Κ|К/' => 'K', @@ -80,10 +80,10 @@ $foreign_characters = array( '/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's', '/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T', '/ț|ţ|ť|ŧ|т/' => 't', - '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У|Ъ/' => 'U', - '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у|ъ/' => 'u', - '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ/' => 'Y', - '/ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ/' => 'y', + '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U', + '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u', + '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y', + '/ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y', '/В/' => 'V', '/в/' => 'v', '/Ŵ/' => 'W', @@ -91,7 +91,7 @@ $foreign_characters = array( '/Ź|Ż|Ž|Ζ|З/' => 'Z', '/ź|ż|ž|ζ|з/' => 'z', '/Æ|Ǽ/' => 'AE', - '/ß/'=> 'ss', + '/ß/' => 'ss', '/IJ/' => 'IJ', '/ij/' => 'ij', '/Œ/' => 'OE', @@ -101,22 +101,28 @@ $foreign_characters = array( '/β/' => 'v', '/μ/' => 'm', '/ψ/' => 'ps', - '/Ж/'=>'Zh', - '/ж/'=>'zh', - '/Х/'=>'Kh', - '/х/'=>'kh', - '/Ц/'=>'Tc', - '/ц/'=>'tc', - '/Ч/'=>'Ch', - '/ч/'=>'ch', - '/Ш/'=>'Sh', - '/ш/'=>'sh', - '/Щ/'=>'Shch', - '/щ/'=>'shch', - '/Ю/'=>'Iu', - '/ю/'=>'iu', - '/Я/'=>'Ia', - '/я/'=>'ia' + '/Ё/' => 'Yo', + '/ё/' => 'yo', + '/Є/' => 'Ye', + '/є/' => 'ye', + '/Ї/' => 'Yi', + '/Ж/' => 'Zh', + '/ж/' => 'zh', + '/Х/' => 'Kh', + '/х/' => 'kh', + '/Ц/' => 'Ts', + '/ц/' => 'ts', + '/Ч/' => 'Ch', + '/ч/' => 'ch', + '/Ш/' => 'Sh', + '/ш/' => 'sh', + '/Щ/' => 'Shch', + '/щ/' => 'shch', + '/Ъ|ъ|Ь|ь/' => '', + '/Ю/' => 'Yu', + '/ю/' => 'yu', + '/Я/' => 'Ya', + '/я/' => 'ya' ); /* End of file foreign_chars.php */ diff --git a/application/config/mimes.php b/application/config/mimes.php index 32d10f6c1..ad3602126 100644 --- a/application/config/mimes.php +++ b/application/config/mimes.php @@ -78,6 +78,7 @@ return array( 'sit' => 'application/x-stuffit', 'tar' => 'application/x-tar', 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), + 'z' => 'application/x-compress', 'xhtml' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml', 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'), diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index c962fda20..c12116236 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -73,11 +73,10 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ------------------------------------------------------ */ set_error_handler('_exception_handler'); + register_shutdown_function('_shutdown_handler'); - if ( ! is_php('5.4')) - { - @ini_set('magic_quotes_runtime', 0); // Kill magic quotes - } + // Kill magic quotes + is_php('5.4') OR @ini_set('magic_quotes_runtime', 0); /* * ------------------------------------------------------ diff --git a/system/core/Common.php b/system/core/Common.php index 7f296b133..c25707e50 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -82,7 +82,7 @@ if ( ! function_exists('is_really_writable')) function is_really_writable($file) { // If we're on a Unix server with safe_mode off we call is_writable - if (DIRECTORY_SEPARATOR === '/' && (bool) @ini_get('safe_mode') === FALSE) + if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR (bool) @ini_get('safe_mode') === FALSE)) { return is_writable($file); } @@ -429,10 +429,9 @@ if ( ! function_exists('log_message')) * * @param string the error level: 'error', 'debug' or 'info' * @param string the error message - * @param bool whether the error is a native PHP error * @return void */ - function log_message($level, $message, $php_error = FALSE) + function log_message($level, $message) { static $_log; @@ -442,7 +441,7 @@ if ( ! function_exists('log_message')) $_log[0] =& load_class('Log', 'core'); } - $_log[0]->write_log($level, $message, $php_error); + $_log[0]->write_log($level, $message); } } @@ -577,6 +576,34 @@ if ( ! function_exists('_exception_handler')) } } +// ------------------------------------------------------------------------ + +if ( ! function_exists('_shutdown_handler')) +{ + /** + * Shutdown Handler + * + * This is the shutdown handler that is declared at the top + * of CodeIgniter.php. The main reason we use this is to simulate + * a complete custom exception handler. + * + * E_STRICT is purposivly neglected because such events may have + * been caught. Duplication or none? None is preferred for now. + * + * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a + * @return void + */ + function _shutdown_handler() + { + $last_error = function_exists('error_get_last') ? error_get_last() : NULL; + if (isset($last_error) && + ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) + { + _exception_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); + } + } +} + // -------------------------------------------------------------------- if ( ! function_exists('remove_invisible_characters')) diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index 9c68d06a5..d7e5ed4d9 100644 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -91,7 +91,7 @@ class CI_Exceptions { public function log_exception($severity, $message, $filepath, $line) { $severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity; - log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE); + log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line); } // -------------------------------------------------------------------- diff --git a/system/core/Input.php b/system/core/Input.php index 24e21ea08..8c32e459e 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -693,7 +693,14 @@ class CI_Input { foreach ($_COOKIE as $key => $val) { - $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE) + { + $_COOKIE[$cookie_key] = $this->_clean_input_data($val); + } + else + { + unset($_COOKIE[$key]); + } } } @@ -706,7 +713,7 @@ class CI_Input { $this->security->csrf_verify(); } - log_message('debug', 'Global POST and COOKIE data sanitized'); + log_message('debug', 'Global POST, GET and COOKIE data sanitized'); } // -------------------------------------------------------------------- @@ -776,15 +783,25 @@ class CI_Input { * only named with alpha-numeric text and a few other items. * * @param string $str Input string - * @return string + * @param string $fatal Whether to terminate script exection + * or to return FALSE if an invalid + * key is encountered + * @return string|bool */ - protected function _clean_input_keys($str) + protected function _clean_input_keys($str, $fatal = TRUE) { if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str)) { - set_status_header(503); - echo 'Disallowed Key Characters.'; - exit(EXIT_USER_INPUT); + if ($fatal === TRUE) + { + return FALSE; + } + else + { + set_status_header(503); + echo 'Disallowed Key Characters.'; + exit(EXIT_USER_INPUT); + } } // Clean UTF-8 if supported diff --git a/system/core/Loader.php b/system/core/Loader.php index 1709c2db1..2eef9979c 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -222,7 +222,7 @@ class CI_Loader { { foreach ($model as $key => $value) { - $this->model(is_int($key) ? $value : $key, $value); + is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); } return; } diff --git a/system/core/Log.php b/system/core/Log.php index e4d72b544..b2327b8f0 100644 --- a/system/core/Log.php +++ b/system/core/Log.php @@ -140,10 +140,9 @@ class CI_Log { * * @param string the error level: 'error', 'debug' or 'info' * @param string the error message - * @param bool whether the error is a native PHP error * @return bool */ - public function write_log($level, $msg, $php_error = FALSE) + public function write_log($level, $msg) { if ($this->_enabled === FALSE) { diff --git a/system/core/Output.php b/system/core/Output.php index 06d7a866b..7c2a64d24 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -841,14 +841,43 @@ class CI_Output { $output = substr_replace($output, '', 0, $pos); // Remove closing tag and save it for later - $pos = strpos($output, '</'); - $closing_tag = substr($output, $pos, strlen($output)); + $pos = strrpos($output, '</'); + $closing_tag = substr($output, $pos); $output = substr_replace($output, '', $pos); } // Remove CSS comments $output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!i', '', $output); + // Remove Javascript inline comments + if ($has_tags === TRUE && strpos(strtolower($open_tag), 'script') !== FALSE) + { + $lines = preg_split('/\r?\n|\n?\r/', $output); + foreach ($lines as &$line) + { + $in_string = $in_dstring = FALSE; + for ($i = 0, $len = strlen($line); $i < $len; $i++) + { + if ( ! $in_string && ! $in_dstring && substr($line, $i, 2) === '//') + { + $line = substr($line, 0, $i); + break; + } + + if ($line[$i] === "'" && ! $in_dstring) + { + $in_string = ! $in_string; + } + elseif ($line[$i] === '"' && ! $in_string) + { + $in_dstring = ! $in_dstring; + } + } + } + + $output = implode("\n", $lines); + } + // Remove spaces around curly brackets, colons, // semi-colons, parenthesis, commas $chunks = preg_split('/([\'|"]).+(?![^\\\]\\1)\\1/iU', $output, -1, PREG_SPLIT_OFFSET_CAPTURE); @@ -899,11 +928,11 @@ class CI_Output { } } - if ($value === "'") + if ($value === "'" && ! $in_dstring) { $in_string = ! $in_string; } - elseif ($value === '"') + elseif ($value === '"' && ! $in_string) { $in_dstring = ! $in_dstring; } diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index e6a108209..a36501eb6 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -1138,7 +1138,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * ORDER BY * * @param string $orderby - * @param string $direction ASC or DESC + * @param string $direction ASC, DESC or RANDOM * @param bool $escape * @return CI_DB_query_builder */ @@ -1152,7 +1152,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // Do we have a seed value? $orderby = ctype_digit((string) $orderby) - ? $orderby = sprintf($this->_random_keyword[1], $orderby) + ? sprintf($this->_random_keyword[1], $orderby) : $this->_random_keyword[0]; } elseif (empty($orderby)) diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index ef2cb8a8d..0f3c6fc62 100644 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -241,9 +241,10 @@ class CI_DB_mysqli_driver extends CI_DB { // even if the queries produce a successful result. $this->_trans_failure = ($test_mode === TRUE); - $this->simple_query('SET AUTOCOMMIT=0'); - $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK - return TRUE; + $this->conn_id->autocommit(FALSE); + return is_php('5.5') + ? $this->conn_id->begin_transaction() + : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK } // -------------------------------------------------------------------- @@ -261,9 +262,13 @@ class CI_DB_mysqli_driver extends CI_DB { return TRUE; } - $this->simple_query('COMMIT'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + if ($this->conn_id->commit()) + { + $this->conn_id->autocommit(TRUE); + return TRUE; + } + + return FALSE; } // -------------------------------------------------------------------- @@ -281,9 +286,13 @@ class CI_DB_mysqli_driver extends CI_DB { return TRUE; } - $this->simple_query('ROLLBACK'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + if ($this->conn_id->rollback()) + { + $this->conn_id->autocommit(TRUE); + return TRUE; + } + + return FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php index d0cdde2e2..fda3f238b 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php @@ -137,7 +137,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|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(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); } // -------------------------------------------------------------------- @@ -166,7 +166,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { * ORDER BY * * @param string $orderby - * @param string $direction ASC or DESC + * @param string $direction ASC, DESC or RANDOM * @param bool $escape * @return object */ diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index ac7345ad6..b72fb873a 100644 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -318,7 +318,7 @@ class CI_DB_postgre_driver extends CI_DB { */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|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(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); } // -------------------------------------------------------------------- @@ -331,7 +331,7 @@ class CI_DB_postgre_driver extends CI_DB { */ protected function _escape_str($str) { - return pg_escape_string($str); + return pg_escape_string($this->conn_id, $str); } // -------------------------------------------------------------------- @@ -346,7 +346,11 @@ class CI_DB_postgre_driver extends CI_DB { */ public function escape($str) { - if (is_bool($str)) + if (is_php('5.4.4') && (is_string($str) OR (is_object($str) && method_exists($str, '__toString')))) + { + return pg_escape_literal($this->conn_id, $str); + } + elseif (is_bool($str)) { return ($str) ? 'TRUE' : 'FALSE'; } @@ -512,7 +516,7 @@ class CI_DB_postgre_driver extends CI_DB { * ORDER BY * * @param string $orderby - * @param string $direction ASC or DESC + * @param string $direction ASC, DESC or RANDOM * @param bool $escape * @return object */ diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 146c0f588..0cc5bd157 100644 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -675,37 +675,22 @@ if ( ! function_exists('set_select')) */ function set_select($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) + { + return $CI->form_validation->set_select($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' selected="selected"' : ''; + } + elseif (is_array($input) && in_array($value, $input, TRUE)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' selected="selected"'; - } - return ''; - } - - $field = $_POST[$field]; - - if (is_array($field)) - { - if ( ! in_array($value, $field)) - { - return ''; - } - } - elseif (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - return ' selected="selected"'; } - return $OBJ->set_select($field, $value, $default); + return ($input === $value) ? ' selected="selected"' : ''; } } @@ -726,37 +711,22 @@ if ( ! function_exists('set_checkbox')) */ function set_checkbox($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) + { + return $CI->form_validation->set_checkbox($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' checked="checked"' : ''; + } + elseif (is_array($input) && in_array($value, $input, TRUE)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' checked="checked"'; - } - return ''; - } - - $field = $_POST[$field]; - - if (is_array($field)) - { - if ( ! in_array($value, $field)) - { - return ''; - } - } - elseif (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - return ' checked="checked"'; } - return $OBJ->set_checkbox($field, $value, $default); + return ($input === $value) ? ' checked="checked"' : ''; } } @@ -770,47 +740,25 @@ if ( ! function_exists('set_radio')) * Let's you set the selected value of a radio field via info in the POST array. * If Form Validation is active it retrieves the info from the validation class * - * @param string - * @param string - * @param bool + * @param string $field + * @param string $value + * @param bool $default * @return string */ function set_radio($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' checked="checked"'; - } - return ''; - } - - $field = $_POST[$field]; - - if (is_array($field)) - { - if ( ! in_array($value, $field)) - { - return ''; - } - } - else - { - if (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - } - - return ' checked="checked"'; + return $CI->form_validation->set_radio($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' checked="checked"' : ''; } - return $OBJ->set_radio($field, $value, $default); + return ($input === $value) ? ' checked="checked"' : ''; } } diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 082629a4c..efdbfd7c1 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -399,9 +399,9 @@ class CI_Email { else { $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - $this->_safe_mode = (bool) @ini_get('safe_mode'); } + $this->_safe_mode = ( ! is_php('5.4') && (bool) @ini_get('safe_mode')); $this->charset = strtoupper($this->charset); log_message('debug', 'Email Class Initialized'); @@ -451,7 +451,6 @@ class CI_Email { $this->clear(); $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - $this->_safe_mode = (bool) @ini_get('safe_mode'); return $this; } diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 15eb74bd5..060973847 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -1245,7 +1245,7 @@ class CI_Upload { } } - if ( (bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec')) + if ((bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec')) { $mime = @shell_exec($cmd); if (strlen($mime) > 0) diff --git a/tests/mocks/core/common.php b/tests/mocks/core/common.php index 0ccfe1ea4..e5dc29c86 100644 --- a/tests/mocks/core/common.php +++ b/tests/mocks/core/common.php @@ -178,7 +178,7 @@ if ( ! function_exists('is_loaded')) if ( ! function_exists('log_message')) { - function log_message($level, $message, $php_error = FALSE) + function log_message($level, $message) { return TRUE; } diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 84989189d..a66fb265f 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -181,6 +181,7 @@ Release Date: Not Released - Server version checking is now done via ``mysqli::$server_info`` instead of running an SQL query. - Added persistent connections support for PHP >= 5.3. - Added support for ``backup()`` in :doc:`Database Utilities <database/utilities>`. + - Changed methods ``trans_begin()``, ``trans_commit()`` and ``trans_rollback()`` to use the PHP API instead of sending queries. - Improved support of the PDO driver, including: @@ -198,6 +199,7 @@ Release Date: Not Released - Removed ``limit()`` and ``order_by()`` support for *UPDATE* and *DELETE* queries as PostgreSQL does not support those features. - Added a work-around for dead persistent connections to be re-created after a database restart. - Changed ``db_connect()`` to include the (new) **schema** value into Postgre's **search_path** session variable. + - ``pg_escape_literal()`` is now used for escaping strings, if available. - Improved support of the CUBRID driver, including: @@ -390,6 +392,7 @@ Release Date: Not Released - Changed methods ``get()``, ``post()``, ``get_post()``, ``cookie()``, ``server()``, ``user_agent()`` to return NULL instead of FALSE when no value is found. - Added method ``post_get()`` and changed ``get_post()`` to search in GET data first. Both methods' names now properly match their GET/POST data search priorities. - Changed method ``_fetch_from_array()`` to parse array notation in field name. + - Added an option for ``_clean_input_keys()`` to return FALSE instead of terminating the whole script. - :doc:`Common functions <general/common_functions>` changes include: @@ -399,6 +402,7 @@ Release Date: Not Released - Changed ``_exception_handler()`` to respect php.ini *display_errors* setting. - Added function :php:func:`is_https()` to check if a secure connection is used. - Added function :php:func:`function_usable()` to check if a function exists and is not disabled by `Suhosin <http://www.hardened-php.net/suhosin/>`. + - Removed the third (`$php_error`) from function :php:func:`log_message()`. - :doc:`Output Library <libraries/output>` changes include: @@ -436,6 +440,7 @@ Release Date: Not Released - Added support for HTTP-Only cookies with new config option *cookie_httponly* (default FALSE). - Renamed method ``_call_hook()`` to ``call_hook()`` in the :doc:`Hooks Library <general/hooks>`. - ``$config['time_reference']`` now supports all timezone strings supported by PHP. + - Fatal PHP errors are now also passed to ``_exception_handler()``, so they can be logged. Bug fixes for 3.0 @@ -464,7 +469,7 @@ Bug fixes for 3.0 - Fixed a possible bug in ``CI_Input::is_ajax_request()`` where some clients might not send the X-Requested-With HTTP header value exactly as 'XmlHttpRequest'. - Fixed a bug (#1039) - MySQL's _backup() method failed due to a table name not being escaped. - Fixed a bug (#1070) - CI_DB_driver::initialize() didn't set a character set if a database is not selected. -- Fixed a bug (#177) - CI_Form_validation::set_value() didn't set the default value if POST data is NULL. +- Fixed a bug (#177) - ``CI_Form_validation::set_value()`` didn't set the default value if POST data is NULL. - Fixed a bug (#68, #414) - Oracle's escape_str() didn't properly escape LIKE wild characters. - Fixed a bug (#81) - ODBC's list_fields() and field_data() methods skipped the first column due to odbc_field_*() functions' index starting at 1 instead of 0. - Fixed a bug (#129) - ODBC's num_rows() returned -1 in some cases, due to not all subdrivers supporting the odbc_num_rows() function. @@ -592,7 +597,7 @@ Bug fixes for 3.0 - Fixed a bug (#2239) - :doc:`Email Library <libraries/email>` improperly handled the Subject when used with ``bcc_batch_mode`` resulting in E_WARNING messages and an empty Subject. - Fixed a bug (#2234) - :doc:`Query Builder <database/query_builder>` didn't reset JOIN cache for write-type queries. - Fixed a bug (#2298) - :doc:`Database Results <database/results>` method ``next_row()`` kept returning the last row, allowing for infinite loops. -- Fixed a bug (#2236) - :doc:`Form Helper <helpers/form_helper>` function ``set_value()`` didn't parse array notation for keys if the rule was not present in the :doc:`Form Validation Library <libraries/form_validation>`. +- Fixed a bug (#2236, #2639) - :doc:`Form Helper <helpers/form_helper>` functions :func:`set_value()`, :func:`set_select()`, :func:`set_radio()`, :func:`set_checkbox()` didn't parse array notation for keys if the rule was not present in the :doc:`Form Validation Library <libraries/form_validation>`. - Fixed a bug (#2353) - :doc:`Query Builder <database/query_builder>` erroneously prefixed literal strings with **dbprefix**. - Fixed a bug (#78) - :doc:`Cart Library <libraries/cart>` didn't allow non-English letters in product names. - Fixed a bug (#77) - :doc:`Database Class <database/index>` didn't properly handle the transaction "test mode" flag. @@ -600,7 +605,7 @@ Bug fixes for 3.0 - Fixed a bug (#2388) - :doc:`Email Library <libraries/email>` used to ignore attachment errors, resulting in broken emails being sent. - Fixed a bug (#2498) - :doc:`Form Validation Library <libraries/form_validation>` rule **valid_base64** only checked characters instead of actual validity. - Fixed a bug (#2425) - OCI8 :doc:`database <database>` driver's method ``stored_procedure()`` didn't log an error unless **db_debug** was set to TRUE. -- Fixed a bug (#2490) - :doc:`Database Class <database/queries>` method ``query()`` returning boolean instead of a result object for PostgreSQL-specific *INSERT INTO ... RETURNING* statements. +- Fixed a bug (#2490) - :doc:`Database Class <database/queries>` method ``query()`` returning boolean instead of a result object when the PostgreSQL-specific *RETURNING* clause is used. - Fixed a bug (#249) - :doc:`Cache Library <libraries/caching>` didn't properly handle Memcache(d) configurations with missing options. - Fixed a bug (#180) - :php:func:`config_item()` didn't take into account run-time configuration changes. - Fixed a bug (#2551) - :doc:`Loader Library <libraries/loader>` method ``library()`` didn't properly check if a class that is being loaded already exists. @@ -608,6 +613,9 @@ Bug fixes for 3.0 - Fixed a bug (#2585) - :doc:`Query Builder <database/query_builder>` methods ``min()``, ``max()``, ``avg()``, ``sum()`` didn't escape field names. - Fixed an edge case (#2583) in the :doc:`Email Library <libraries/email>` where `Suhosin <http://www.hardened-php.net/suhosin/>` blocked messages sent via ``mail()`` due to trailing newspaces in headers. - Fixed a bug (#2590) - :php:func:`log_message()` didn't actually cache the ``CI_Log`` class instance. +- Fixed a bug (#2609) - :php:func:`get_config()` optional argument was only effective on first function call. Also, it can now add items, in addition to updating existing items. +- Fixed a bug in the 'postgre' :doc:`database <database/index>` driver where the connection ID wasn't passed to ``pg_escape_string()``. +- Fixed a bug (#33) - Script execution was terminated when an invalid cookie key was encountered. Version 2.1.4 ============= @@ -764,7 +772,6 @@ Bug fixes for 2.1.0 but the requested method did not. - Fixed a bug (Reactor #89) where MySQL export would fail if the table had hyphens or other non alphanumeric/underscore characters. -- Fixed a bug (#200) where MySQL queries would be malformed after calling $this->db->count_all() then $this->db->get() - Fixed a bug (#105) that stopped query errors from being logged unless database debugging was enabled - Fixed a bug (#160) - Removed unneeded array copy in the file cache driver. @@ -785,7 +792,7 @@ Bug fixes for 2.1.0 - Fixed a bug (#537) - Support for all wav type in browser. - Fixed a bug (#576) - Using ini_get() function to detect if apc is enabled or not. - Fixed invalid date time format in :doc:`Date helper <helpers/date_helper>` and :doc:`XMLRPC library <libraries/xmlrpc>`. -- Fixed a bug (#200) - MySQL queries would be malformed after calling count_all() then db->get(). +- Fixed a bug (#200) - MySQL queries would be malformed after calling db->count_all() then db->get(). Version 2.0.3 ============= diff --git a/user_guide_src/source/general/common_functions.rst b/user_guide_src/source/general/common_functions.rst index 32e8a8be0..e085ef808 100644 --- a/user_guide_src/source/general/common_functions.rst +++ b/user_guide_src/source/general/common_functions.rst @@ -96,11 +96,10 @@ please see the :doc:`Error Handling <errors>` documentation. log_message() ============= -.. php:function:: log_message($level, $message, $php_error = FALSE) +.. php:function:: log_message($level, $message) :param string $level: Log level: 'error', 'debug' or 'info' :param string $message: Message to log - :param bool $php_error: Whether we're logging a native PHP error message :returns: void This function is an alias for ``CI_Log::write_log()``. For more info, diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst index 8b35fdc75..8534175bb 100644 --- a/user_guide_src/source/libraries/form_validation.rst +++ b/user_guide_src/source/libraries/form_validation.rst @@ -431,7 +431,7 @@ Here's how your controller should now look:: } } - protected function username_check($str) + public function username_check($str) { if ($str == 'test') { @@ -866,6 +866,7 @@ Rule Parameter Description **is_unique** Yes Returns FALSE if the form element is not unique to the table and field name in the is_unique[table.field] parameter. Note: This rule requires :doc:`Query Builder <../database/query_builder>` to be enabled in order to work. +**min_length** Yes Returns FALSE if the form element is shorter then the parameter value. min_length[3] **max_length** Yes Returns FALSE if the form element is longer then the parameter value. max_length[12] **exact_length** Yes Returns FALSE if the form element is not exactly the parameter value. exact_length[8] **greater_than** Yes Returns FALSE if the form element is less than or equal to the parameter value or not greater_than[8] |