summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application/config/config.php2
-rw-r--r--application/config/constants.php5
-rw-r--r--application/config/foreign_chars.php60
-rw-r--r--application/config/mimes.php1
-rw-r--r--system/core/CodeIgniter.php7
-rw-r--r--system/core/Common.php35
-rw-r--r--system/core/Exceptions.php2
-rw-r--r--system/core/Input.php31
-rw-r--r--system/core/Loader.php2
-rw-r--r--system/core/Log.php3
-rw-r--r--system/core/Output.php37
-rw-r--r--system/database/DB_query_builder.php4
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php27
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php4
-rw-r--r--system/database/drivers/postgre/postgre_driver.php12
-rw-r--r--system/helpers/form_helper.php118
-rw-r--r--system/libraries/Email.php3
-rw-r--r--system/libraries/Upload.php2
-rw-r--r--tests/mocks/core/common.php2
-rw-r--r--user_guide_src/source/changelog.rst17
-rw-r--r--user_guide_src/source/general/common_functions.rst3
-rw-r--r--user_guide_src/source/libraries/form_validation.rst3
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]