summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/core/CodeIgniter.php19
-rw-r--r--system/core/Common.php20
-rw-r--r--system/core/Config.php3
-rw-r--r--system/core/Exceptions.php16
-rw-r--r--system/core/Hooks.php2
-rw-r--r--system/core/Input.php4
-rw-r--r--system/core/Log.php30
-rw-r--r--system/core/Output.php2
-rwxr-xr-xsystem/core/Security.php84
-rw-r--r--system/core/compat/password.php17
-rw-r--r--system/core/compat/standard.php (renamed from system/core/compat/array.php)143
-rw-r--r--system/database/DB_cache.php11
-rw-r--r--system/database/DB_driver.php5
-rw-r--r--system/database/DB_forge.php2
-rw-r--r--system/database/DB_query_builder.php6
-rw-r--r--system/database/drivers/cubrid/cubrid_driver.php9
-rw-r--r--system/database/drivers/ibase/ibase_driver.php6
-rw-r--r--system/database/drivers/mssql/mssql_driver.php4
-rw-r--r--system/database/drivers/mysql/mysql_driver.php4
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php4
-rw-r--r--system/database/drivers/pdo/pdo_result.php2
-rw-r--r--system/database/drivers/sqlite3/sqlite3_driver.php2
-rw-r--r--system/helpers/captcha_helper.php18
-rw-r--r--system/helpers/file_helper.php4
-rw-r--r--system/helpers/url_helper.php6
-rw-r--r--system/libraries/Cache/drivers/Cache_file.php14
-rw-r--r--system/libraries/Cache/drivers/Cache_memcached.php4
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php61
-rw-r--r--system/libraries/Email.php5
-rw-r--r--system/libraries/Encrypt.php4
-rw-r--r--system/libraries/Encryption.php177
-rw-r--r--system/libraries/Form_validation.php61
-rw-r--r--system/libraries/Image_lib.php23
-rw-r--r--system/libraries/Pagination.php84
-rw-r--r--system/libraries/Parser.php66
-rw-r--r--system/libraries/Upload.php47
-rw-r--r--system/libraries/Zip.php2
37 files changed, 661 insertions, 310 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 1c6e76b4f..5ff788ae3 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -249,7 +249,7 @@ if ( ! is_php('5.4'))
require_once(BASEPATH.'core/compat/mbstring.php');
require_once(BASEPATH.'core/compat/hash.php');
require_once(BASEPATH.'core/compat/password.php');
- require_once(BASEPATH.'core/compat/array.php');
+ require_once(BASEPATH.'core/compat/standard.php');
/*
* ------------------------------------------------------
@@ -449,6 +449,23 @@ if ( ! is_php('5.4'))
/*
* ------------------------------------------------------
+ * Should we use a Composer autoloader?
+ * ------------------------------------------------------
+ */
+ if (($composer_autoload = config_item('composer_autoload')) !== FALSE)
+ {
+ if ($composer_autoload === TRUE && file_exists(APPPATH.'vendor/autoload.php'))
+ {
+ require_once(APPPATH.'vendor/autoload.php');
+ }
+ elseif (file_exists($composer_autoload))
+ {
+ require_once($composer_autoload);
+ }
+ }
+
+/*
+ * ------------------------------------------------------
* Is there a "pre_controller" hook?
* ------------------------------------------------------
*/
diff --git a/system/core/Common.php b/system/core/Common.php
index 752a2e7f1..504e22571 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -289,7 +289,7 @@ if ( ! function_exists('config_item'))
$_config[0] =& get_config();
}
- return isset($_config[0][$item]) ? $_config[0][$item] : FALSE;
+ return isset($_config[0][$item]) ? $_config[0][$item] : NULL;
}
}
@@ -690,16 +690,20 @@ if ( ! function_exists('remove_invisible_characters'))
if ( ! function_exists('html_escape'))
{
/**
- * Returns HTML escaped variable
+ * Returns HTML escaped variable.
*
- * @param mixed
- * @return mixed
+ * @param mixed $var The input string or array of strings to be escaped.
+ * @param bool $double_encode $double_encode set to FALSE prevents escaping twice.
+ * @return mixed The escaped string or array of strings as a result.
*/
- function html_escape($var)
+ function html_escape($var, $double_encode = TRUE)
{
- return is_array($var)
- ? array_map('html_escape', $var)
- : htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
+ if (is_array($var))
+ {
+ return array_map('html_escape', $var, array_fill(0, count($var), $double_encode));
+ }
+
+ return htmlspecialchars($var, ENT_QUOTES, config_item('charset'), $double_encode);
}
}
diff --git a/system/core/Config.php b/system/core/Config.php
index ad0e5f981..db406dfde 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -104,10 +104,11 @@ class CI_Config {
public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
$file = ($file === '') ? 'config' : str_replace('.php', '', $file);
- $found = $loaded = FALSE;
+ $loaded = FALSE;
foreach ($this->_config_paths as $path)
{
+ $found = FALSE;
foreach (array(ENVIRONMENT.'/'.$file, $file) as $location)
{
$file_path = $path.'config/'.$location.'.php';
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index cb4bc3cd6..49c2217c9 100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -145,9 +145,11 @@ class CI_Exceptions {
*/
public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
- $templates_path = config_item('error_views_path')
- ? config_item('error_views_path')
- : VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ $templates_path = config_item('error_views_path');
+ if (empty($templates_path))
+ {
+ $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ }
if (is_cli())
{
@@ -185,9 +187,11 @@ class CI_Exceptions {
*/
public function show_php_error($severity, $message, $filepath, $line)
{
- $templates_path = config_item('error_views_path')
- ? config_item('error_views_path')
- : VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ $templates_path = config_item('error_views_path');
+ if (empty($templates_path))
+ {
+ $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ }
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index fd1a2ba11..26ced0894 100644
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
@@ -127,7 +127,7 @@ class CI_Hooks {
return FALSE;
}
- if (is_array($this->hooks[$which]))
+ if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function']))
{
foreach ($this->hooks[$which] as $val)
{
diff --git a/system/core/Input.php b/system/core/Input.php
index 544b7c08b..9ae2f6d6f 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -353,7 +353,7 @@ class CI_Input {
$path = config_item('cookie_path');
}
- if ($secure === FALSE && config_item('cookie_secure') !== FALSE)
+ if ($secure === FALSE && config_item('cookie_secure') === TRUE)
{
$secure = config_item('cookie_secure');
}
@@ -766,7 +766,7 @@ class CI_Input {
*
* @param string $index Header name
* @param bool $xss_clean Whether to apply XSS filtering
- * @return string|bool The requested header on success or FALSE on failure
+ * @return string|null The requested header on success or NULL on failure
*/
public function get_request_header($index, $xss_clean = FALSE)
{
diff --git a/system/core/Log.php b/system/core/Log.php
index a949c3f39..1dca1bf3b 100644
--- a/system/core/Log.php
+++ b/system/core/Log.php
@@ -45,32 +45,39 @@ class CI_Log {
protected $_log_path;
/**
+ * File permissions
+ *
+ * @var int
+ */
+ protected $_file_permissions = 0644;
+
+ /**
* Level of logging
*
* @var int
*/
- protected $_threshold = 1;
+ protected $_threshold = 1;
/**
* Highest level of logging
*
* @var int
*/
- protected $_threshold_max = 0;
+ protected $_threshold_max = 0;
/**
* Array of threshold levels to log
*
* @var array
*/
- protected $_threshold_array = array();
+ protected $_threshold_array = array();
/**
* Format of timestamp for log files
*
* @var string
*/
- protected $_date_fmt = 'Y-m-d H:i:s';
+ protected $_date_fmt = 'Y-m-d H:i:s';
/**
* Filename extension
@@ -84,14 +91,14 @@ class CI_Log {
*
* @var bool
*/
- protected $_enabled = TRUE;
+ protected $_enabled = TRUE;
/**
* Predefined logging levels
*
* @var array
*/
- protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4);
+ protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4);
// --------------------------------------------------------------------
@@ -108,7 +115,7 @@ class CI_Log {
$this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '')
? ltrim($config['log_file_extension'], '.') : 'php';
- file_exists($this->_log_path) OR mkdir($this->_log_path, 0777, TRUE);
+ file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE);
if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path))
{
@@ -125,10 +132,15 @@ class CI_Log {
$this->_threshold_array = array_flip($config['log_threshold']);
}
- if ($config['log_date_format'] !== '')
+ if ( ! empty($config['log_date_format']))
{
$this->_date_fmt = $config['log_date_format'];
}
+
+ if ( ! empty($config['log_file_permissions']) && is_int($config['log_file_permissions']))
+ {
+ $this->_file_permissions = $config['log_file_permissions'];
+ }
}
// --------------------------------------------------------------------
@@ -192,7 +204,7 @@ class CI_Log {
if (isset($newfile) && $newfile === TRUE)
{
- @chmod($filepath, 0666);
+ chmod($filepath, $this->_file_permissions);
}
return is_int($result);
diff --git a/system/core/Output.php b/system/core/Output.php
index 238d223e2..de07125ad 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -606,7 +606,7 @@ class CI_Output {
if (is_int($result))
{
- @chmod($cache_path, 0666);
+ chmod($cache_path, 0640);
log_message('debug', 'Cache file written: '.$cache_path);
// Send HTTP cache-control headers to browser to match file cache settings.
diff --git a/system/core/Security.php b/system/core/Security.php
index 2cf214b18..cffdb9ad9 100755
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -77,7 +77,7 @@ class CI_Security {
*
* @var string
*/
- protected $_xss_hash = '';
+ protected $_xss_hash;
/**
* CSRF Hash
@@ -86,7 +86,7 @@ class CI_Security {
*
* @var string
*/
- protected $_csrf_hash = '';
+ protected $_csrf_hash;
/**
* CSRF Expire time
@@ -158,7 +158,7 @@ class CI_Security {
public function __construct()
{
// Is CSRF protection enabled?
- if (config_item('csrf_protection') === TRUE)
+ if (config_item('csrf_protection'))
{
// CSRF config
foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key)
@@ -170,9 +170,9 @@ class CI_Security {
}
// Append application specific cookie prefix
- if (config_item('cookie_prefix'))
+ if ($cookie_prefix = config_item('cookie_prefix'))
{
- $this->_csrf_cookie_name = config_item('cookie_prefix').$this->_csrf_cookie_name;
+ $this->_csrf_cookie_name = $cookie_prefix.$this->_csrf_cookie_name;
}
// Set the CSRF hash
@@ -203,9 +203,12 @@ class CI_Security {
if ($exclude_uris = config_item('csrf_exclude_uris'))
{
$uri = load_class('URI', 'core');
- if (in_array($uri->uri_string(), $exclude_uris))
+ foreach ($exclude_uris as $excluded)
{
- return $this;
+ if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), $uri->uri_string()))
+ {
+ return $this;
+ }
}
}
@@ -224,7 +227,7 @@ class CI_Security {
{
// Nothing should last forever
unset($_COOKIE[$this->_csrf_cookie_name]);
- $this->_csrf_hash = '';
+ $this->_csrf_hash = NULL;
}
$this->_csrf_set_hash();
@@ -275,7 +278,7 @@ class CI_Security {
*/
public function csrf_show_error()
{
- show_error('The action you have requested is not allowed.');
+ show_error('The action you have requested is not allowed.', 403);
}
// --------------------------------------------------------------------
@@ -370,7 +373,7 @@ class CI_Security {
* We only convert entities that are within tags since
* these are the ones that will pose security problems.
*/
- $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
+ $str = preg_replace_callback("/[^a-z0-9>]+[a-z0-9]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
$str = preg_replace_callback('/<\w+.*/si', array($this, '_decode_entity'), $str);
// Remove Invisible Characters Again!
@@ -436,7 +439,7 @@ class CI_Security {
/*
* Remove disallowed Javascript in links or img tags
- * We used to do some version comparisons and use of stripos for PHP5,
+ * We used to do some version comparisons and use of stripos(),
* but it is dog slow compared to these simplified non-capturing
* preg_match(), especially if the pattern exists in the string
*
@@ -535,9 +538,12 @@ class CI_Security {
*/
public function xss_hash()
{
- if ($this->_xss_hash === '')
+ if ($this->_xss_hash === NULL)
{
- $this->_xss_hash = md5(uniqid(mt_rand()));
+ $rand = $this->get_random_bytes(16);
+ $this->_xss_hash = ($rand === FALSE)
+ ? md5(uniqid(mt_rand(), TRUE))
+ : bin2hex($rand);
}
return $this->_xss_hash;
@@ -546,6 +552,48 @@ class CI_Security {
// --------------------------------------------------------------------
/**
+ * Get random bytes
+ *
+ * @param int $length Output length
+ * @return string
+ */
+ public function get_random_bytes($length)
+ {
+ if (empty($length) OR ! ctype_digit((string) $length))
+ {
+ return FALSE;
+ }
+
+ // Unfortunately, none of the following PRNGs is guaranteed to exist ...
+ if (defined('MCRYPT_DEV_URANDOM') && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== FALSE)
+ {
+ return $output;
+ }
+
+
+ if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== FALSE)
+ {
+ // Try not to waste entropy ...
+ is_php('5.4') && stream_set_chunk_size($fp, $length);
+ $output = fread($fp, $length);
+ fclose($fp);
+ if ($output !== FALSE)
+ {
+ return $output;
+ }
+ }
+
+ if (function_exists('openssl_random_pseudo_bytes'))
+ {
+ return openssl_random_pseudo_bytes($length);
+ }
+
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* HTML Entities Decode
*
* A replacement for html_entity_decode()
@@ -605,7 +653,7 @@ class CI_Security {
{
if (($char = array_search($matches[$i].';', $_entities, TRUE)) !== FALSE)
{
- $replace[$matches[$i]] = $character;
+ $replace[$matches[$i]] = $char;
}
}
@@ -912,7 +960,7 @@ class CI_Security {
*/
protected function _csrf_set_hash()
{
- if ($this->_csrf_hash === '')
+ if ($this->_csrf_hash === NULL)
{
// If the cookie exists we will use its value.
// We don't necessarily want to regenerate it with
@@ -924,8 +972,10 @@ class CI_Security {
return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
}
- $this->_csrf_hash = md5(uniqid(mt_rand(), TRUE));
- $this->csrf_set_cookie();
+ $rand = $this->get_random_bytes(16);
+ $this->_csrf_hash = ($rand === FALSE)
+ ? md5(uniqid(mt_rand(), TRUE))
+ : bin2hex($rand);
}
return $this->_csrf_hash;
diff --git a/system/core/compat/password.php b/system/core/compat/password.php
index a9355d5d0..1f67a5269 100644
--- a/system/core/compat/password.php
+++ b/system/core/compat/password.php
@@ -83,6 +83,9 @@ 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'));
+
if ($algo !== 1)
{
trigger_error('password_hash(): Unknown hashing algorithm: '.(int) $algo, E_USER_WARNING);
@@ -95,9 +98,9 @@ if ( ! function_exists('password_hash'))
return NULL;
}
- if (isset($options['salt']) && strlen($options['salt']) < 22)
+ if (isset($options['salt']) && ($saltlen = ($func_override ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))) < 22)
{
- trigger_error('password_hash(): Provided salt is too short: '.strlen($options['salt']).' expecting 22', E_USER_WARNING);
+ trigger_error('password_hash(): Provided salt is too short: '.$saltlen.' expecting 22', E_USER_WARNING);
return NULL;
}
elseif ( ! isset($options['salt']))
@@ -118,8 +121,11 @@ if ( ! function_exists('password_hash'))
return FALSE;
}
+ // Try not to waste entropy ...
+ is_php('5.4') && stream_set_chunk_size($fp, 16);
+
$options['salt'] = '';
- for ($read = 0; $read < 16; $read = strlen($options['salt']))
+ for ($read = 0; $read < 16; $read = ($func_override) ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))
{
if (($read = fread($fp, 16 - $read)) === FALSE)
{
@@ -145,7 +151,10 @@ if ( ! function_exists('password_hash'))
}
isset($options['cost']) OR $options['cost'] = 10;
- return crypt($password, sprintf('$2y$%02d$%s', $options['cost'], $options['salt']));
+
+ return (strlen($password = crypt($password, sprintf('$2y$%02d$%s', $options['cost'], $options['salt']))) === 60)
+ ? $password
+ : FALSE;
}
}
diff --git a/system/core/compat/array.php b/system/core/compat/standard.php
index 07dae21c2..afe9e9852 100644
--- a/system/core/compat/array.php
+++ b/system/core/compat/standard.php
@@ -27,14 +27,13 @@
defined('BASEPATH') OR exit('No direct script access allowed');
/**
- * PHP ext/standard/array compatibility package
+ * PHP ext/standard compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link http://codeigniter.com/user_guide/
- * @link http://php.net/book.array
*/
// ------------------------------------------------------------------------
@@ -125,6 +124,54 @@ if ( ! function_exists('array_column'))
// ------------------------------------------------------------------------
+if (is_php('5.4'))
+{
+ return;
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('hex2bin'))
+{
+ /**
+ * hex2bin()
+ *
+ * @link http://php.net/hex2bin
+ * @param string $data
+ * @return string
+ */
+ function hex2bin($data)
+ {
+ if (in_array($type = gettype($data), array('array', 'double', 'object'), TRUE))
+ {
+ if ($type === 'object' && method_exists($data, '__toString'))
+ {
+ $data = (string) $data;
+ }
+ else
+ {
+ trigger_error('hex2bin() expects parameter 1 to be string, '.$type.' given', E_USER_WARNING);
+ return NULL;
+ }
+ }
+
+ if (strlen($data) % 2 !== 0)
+ {
+ trigger_error('Hexadecimal input string must have an even length', E_USER_WARNING);
+ return FALSE;
+ }
+ elseif ( ! preg_match('/^[0-9a-f]*$/i', $data))
+ {
+ trigger_error('Input string must be hexadecimal string', E_USER_WARNING);
+ return FALSE;
+ }
+
+ return pack('H*', $data);
+ }
+}
+
+// ------------------------------------------------------------------------
+
if (is_php('5.3'))
{
return;
@@ -242,5 +289,93 @@ if ( ! function_exists('array_replace_recursive'))
}
}
-/* End of file array.php */
-/* Location: ./system/core/compat/array.php */ \ No newline at end of file
+// ------------------------------------------------------------------------
+
+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;
+ }
+}
+
+/* End of file standard.php */
+/* Location: ./system/core/compat/standard.php */ \ No newline at end of file
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
index b855ff24e..2efb42c5c 100644
--- a/system/database/DB_cache.php
+++ b/system/database/DB_cache.php
@@ -156,14 +156,9 @@ class CI_DB_Cache {
$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
$filename = md5($sql);
- if ( ! is_dir($dir_path))
+ if ( ! is_dir($dir_path) && ! @mkdir($dir_path, 0750))
{
- if ( ! @mkdir($dir_path, 0777))
- {
- return FALSE;
- }
-
- @chmod($dir_path, 0777);
+ return FALSE;
}
if (write_file($dir_path.$filename, serialize($object)) === FALSE)
@@ -171,7 +166,7 @@ class CI_DB_Cache {
return FALSE;
}
- @chmod($dir_path.$filename, 0666);
+ chmod($dir_path.$filename, 0640);
return TRUE;
}
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 12ab5bb2a..62cea758e 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -1440,7 +1440,7 @@ abstract class CI_DB_driver {
*/
protected function _has_operator($str)
{
- return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str));
+ return (bool) preg_match('/(<|>|!|=|\sIS\s|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str));
}
// --------------------------------------------------------------------
@@ -1464,8 +1464,7 @@ abstract class CI_DB_driver {
'\s*(?:<|>|!)?=\s*', // =, <=, >=, !=
'\s*<>?\s*', // <, <>
'\s*>\s*', // >
- '\s+IS NULL', // IS NULL
- '\s+IS NOT NULL', // IS NOT NULL
+ '\s+IS(?:\sNOT)?(?:\sNULL)?', // IS[ NOT] NULL
'\s+EXISTS\s*\([^\)]+\)', // EXISTS(sql)
'\s+NOT EXISTS\s*\([^\)]+\)', // NOT EXISTS(sql)
'\s+BETWEEN\s+\S+\s+AND\s+\S+', // BETWEEN value AND value
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 111546ecc..2dd243cae 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -929,7 +929,7 @@ abstract class CI_DB_forge {
$field['default'] = empty($this->_null) ? '' : $this->_default.$this->_null;
// Override the NULL attribute if that's our default
- $attributes['NULL'] = NULL;
+ $attributes['NULL'] = TRUE;
$field['null'] = empty($this->_null) ? '' : ' '.$this->_null;
}
else
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 085c615e5..2096ffd60 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -635,7 +635,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$key = array($key => $value);
}
- // If the escape value was not set will will base it on the global setting
+ // If the escape value was not set will base it on the global setting
is_bool($escape) OR $escape = $this->_protect_identifiers;
foreach ($key as $k => $v)
@@ -661,6 +661,10 @@ 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*(!?=|<>)\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);
if ($this->qb_caching === TRUE)
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index 138b0ed45..c5cb79683 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_driver.php
@@ -264,14 +264,7 @@ class CI_DB_cubrid_driver extends CI_DB {
*/
protected function _escape_str($str)
{
- if (function_exists('cubrid_real_escape_string') &&
- (is_resource($this->conn_id)
- OR (get_resource_type($this->conn_id) === 'Unknown' && preg_match('/Resource id #/', strval($this->conn_id)))))
- {
- return cubrid_real_escape_string($str, $this->conn_id);
- }
-
- return addslashes($str);
+ return cubrid_real_escape_string($str, $this->conn_id);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php
index b19985c37..f4e5aef7c 100644
--- a/system/database/drivers/ibase/ibase_driver.php
+++ b/system/database/drivers/ibase/ibase_driver.php
@@ -219,11 +219,11 @@ class CI_DB_ibase_driver extends CI_DB {
*/
protected function _list_tables($prefix_limit = FALSE)
{
- $sql = 'SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\'';
+ $sql = 'SELECT TRIM("RDB$RELATION_NAME") AS TABLE_NAME FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\'';
if ($prefix_limit !== FALSE && $this->dbprefix !== '')
{
- return $sql.' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
+ return $sql.' AND TRIM("RDB$RELATION_NAME") AS TABLE_NAME LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
.sprintf($this->_like_escape_str, $this->_like_escape_chr);
}
@@ -242,7 +242,7 @@ class CI_DB_ibase_driver extends CI_DB {
*/
protected function _list_columns($table = '')
{
- return 'SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table);
+ return 'SELECT TRIM("RDB$FIELD_NAME") AS COLUMN_NAME FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index f4a166180..8d830fb51 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -143,8 +143,8 @@ class CI_DB_mssql_driver extends CI_DB {
}
// Note: Escaping is required in the event that the DB name
- // contains reserved characters
- if (mssql_select_db($this->escape_identifiers($database), $this->conn_id))
+ // contains reserved characters.
+ if (mssql_select_db('['.$database.']', $this->conn_id))
{
$this->database = $database;
return TRUE;
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 7cbcf1028..a827a6ed4 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -336,9 +336,7 @@ class CI_DB_mysql_driver extends CI_DB {
*/
protected function _escape_str($str)
{
- return is_resource($this->conn_id)
- ? mysql_real_escape_string($str, $this->conn_id)
- : addslashes($str);
+ return mysql_real_escape_string($str, $this->conn_id);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 09277fc39..aa4c6b559 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -307,9 +307,7 @@ class CI_DB_mysqli_driver extends CI_DB {
*/
protected function _escape_str($str)
{
- return is_object($this->conn_id)
- ? $this->conn_id->real_escape_string($str)
- : addslashes($str);
+ return $this->conn_id->real_escape_string($str);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
index 1b8fbc9d4..3f3af2e19 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_result.php
@@ -93,7 +93,7 @@ class CI_DB_pdo_result extends CI_DB_result {
{
// Might trigger an E_WARNING due to not all subdrivers
// supporting getColumnMeta()
- $field_names[$i] = @$this->result_id->getColumnMeta();
+ $field_names[$i] = @$this->result_id->getColumnMeta($i);
$field_names[$i] = $field_names[$i]['name'];
}
diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php
index a7d0d087d..2b447a1b3 100644
--- a/system/database/drivers/sqlite3/sqlite3_driver.php
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -189,7 +189,7 @@ class CI_DB_sqlite3_driver extends CI_DB {
*/
protected function _escape_str($str)
{
- return $this->conn_id->escapeString(remove_invisible_characters($str));
+ return $this->conn_id->escapeString($str);
}
// --------------------------------------------------------------------
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index 74ab24ffb..f4ed6168f 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -216,8 +216,22 @@ if ( ! function_exists('create_captcha'))
// Generate the image
// -----------------------------------
$img_url = rtrim($img_url, '/').'/';
- $img_filename = $now.'.jpg';
- ImageJPEG($im, $img_path.$img_filename);
+
+ if (function_exists('imagejpeg'))
+ {
+ $img_filename = $now.'.jpg';
+ imagejpeg($im, $img_path.$img_filename);
+ }
+ elseif (function_exists('imagepng'))
+ {
+ $img_filename = $now.'.png';
+ imagepng($im, $img_path.$img_filename);
+ }
+ else
+ {
+ return FALSE;
+ }
+
$img = '<img src="'.$img_url.$img_filename.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />';
ImageDestroy($im);
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 8cfe0f1c1..7d2253ef0 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -80,7 +80,7 @@ if ( ! function_exists('write_file'))
flock($fp, LOCK_EX);
- for ($written = 0, $length = strlen($data); $written < $length; $written += $result)
+ for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result)
{
if (($result = fwrite($fp, substr($data, $written))) === FALSE)
{
@@ -225,7 +225,7 @@ if ( ! function_exists('get_dir_file_info'))
$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
}
- // foreach (scandir($source_dir, 1) as $file) // In addition to being PHP5+, scandir() is simply not as fast
+ // Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast
while (FALSE !== ($file = readdir($fp)))
{
if (is_dir($source_dir.$file) && $file[0] !== '.' && $top_level_only === FALSE)
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index dff1a86d2..0846472e7 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -208,8 +208,12 @@ if ( ! function_exists('anchor_popup'))
$window_name = $attributes['window_name'];
unset($attributes['window_name']);
}
+ else
+ {
+ $window_name = '_blank';
+ }
- foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0') as $key => $val)
+ foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'menubar' => 'no', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0') as $key => $val)
{
$atts[$key] = isset($attributes[$key]) ? $attributes[$key] : $val;
unset($attributes[$key]);
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index c6aa848fe..29898040a 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -92,7 +92,7 @@ class CI_Cache_file extends CI_Driver {
if (write_file($this->_cache_path.$id, serialize($contents)))
{
- @chmod($this->_cache_path.$id, 0660);
+ chmod($this->_cache_path.$id, 0640);
return TRUE;
}
@@ -125,7 +125,11 @@ class CI_Cache_file extends CI_Driver {
{
$data = $this->_get($id);
- if ($data === FALSE OR ! is_int($data['data']))
+ if ($data === FALSE)
+ {
+ $data = array('data' => 0, 'ttl' => 60);
+ }
+ elseif ( ! is_int($data['data']))
{
return FALSE;
}
@@ -149,7 +153,11 @@ class CI_Cache_file extends CI_Driver {
{
$data = $this->_get($id);
- if ($data === FALSE OR ! is_int($data['data']))
+ if ($data === FALSE)
+ {
+ $data = array('data' => 0, 'ttl' => 60);
+ }
+ elseif ( ! is_int($data['data']))
{
return FALSE;
}
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index bed606afb..55b769424 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -49,7 +49,7 @@ class CI_Cache_memcached extends CI_Driver {
*
* @var array
*/
- protected $_memcache_conf = array(
+ protected $_memcache_conf = array(
'default' => array(
'host' => '127.0.0.1',
'port' => 11211,
@@ -202,12 +202,12 @@ class CI_Cache_memcached extends CI_Driver {
{
// Try to load memcached server info from the config file.
$CI =& get_instance();
+ $defaults = $this->_memcache_conf['default'];
if ($CI->config->load('memcached', TRUE, TRUE))
{
if (is_array($CI->config->config['memcached']))
{
- $defaults = $this->_memcache_conf['default'];
$this->_memcache_conf = array();
foreach ($CI->config->config['memcached'] as $name => $conf)
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
index 1c76426c5..7c9da3d2e 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -58,6 +58,13 @@ class CI_Cache_redis extends CI_Driver
*/
protected $_redis;
+ /**
+ * An internal cache for storing keys of serialized values.
+ *
+ * @var array
+ */
+ protected $_serialized = array();
+
// ------------------------------------------------------------------------
/**
@@ -68,7 +75,14 @@ class CI_Cache_redis extends CI_Driver
*/
public function get($key)
{
- return $this->_redis->get($key);
+ $value = $this->_redis->get($key);
+
+ if ($value !== FALSE && isset($this->_serialized[$key]))
+ {
+ return unserialize($value);
+ }
+
+ return $value;
}
// ------------------------------------------------------------------------
@@ -84,6 +98,22 @@ class CI_Cache_redis extends CI_Driver
*/
public function save($id, $data, $ttl = 60, $raw = FALSE)
{
+ if (is_array($data) OR is_object($data))
+ {
+ if ( ! $this->_redis->sAdd('_ci_redis_serialized', $id))
+ {
+ return FALSE;
+ }
+
+ isset($this->_serialized[$id]) OR $this->_serialized[$id] = TRUE;
+ $data = serialize($data);
+ }
+ elseif (isset($this->_serialized[$id]))
+ {
+ $this->_serialized[$id] = NULL;
+ $this->_redis->sRemove('_ci_redis_serialized', $id);
+ }
+
return ($ttl)
? $this->_redis->setex($id, $ttl, $data)
: $this->_redis->set($id, $data);
@@ -99,7 +129,18 @@ class CI_Cache_redis extends CI_Driver
*/
public function delete($key)
{
- return ($this->_redis->delete($key) === 1);
+ if ($this->_redis->delete($key) !== 1)
+ {
+ return FALSE;
+ }
+
+ if (isset($this->_serialized[$key]))
+ {
+ $this->_serialized[$key] = NULL;
+ $this->_redis->sRemove('_ci_redis_serialized', $key);
+ }
+
+ return TRUE;
}
// ------------------------------------------------------------------------
@@ -113,9 +154,7 @@ class CI_Cache_redis extends CI_Driver
*/
public function increment($id, $offset = 1)
{
- return $this->_redis->exists($id)
- ? $this->_redis->incr($id, $offset)
- : FALSE;
+ return $this->_redis->incr($id, $offset);
}
// ------------------------------------------------------------------------
@@ -129,9 +168,7 @@ class CI_Cache_redis extends CI_Driver
*/
public function decrement($id, $offset = 1)
{
- return $this->_redis->exists($id)
- ? $this->_redis->decr($id, $offset)
- : FALSE;
+ return $this->_redis->decr($id, $offset);
}
// ------------------------------------------------------------------------
@@ -259,13 +296,19 @@ class CI_Cache_redis extends CI_Driver
$this->_redis->auth($config['password']);
}
+ // Initialize the index of serialized values.
+ $serialized = $this->_redis->sMembers('_ci_redis_serialized');
+ if ( ! empty($serialized))
+ {
+ $this->_serialized = array_flip($serialized);
+ }
+
return TRUE;
}
// ------------------------------------------------------------------------
/**
-
* Class destructor
*
* Closes the connection to Redis if present.
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index c39a26a15..88398d316 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1079,6 +1079,11 @@ class CI_Email {
*/
public function valid_email($email)
{
+ if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@'))
+ {
+ $email = substr($email, 0, ++$atpos).idn_to_ascii(substr($email, $atpos));
+ }
+
return (bool) filter_var($email, FILTER_VALIDATE_EMAIL);
}
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 2541a4467..1af42ed1f 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -29,7 +29,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter Encryption Class
*
- * Provides two-way keyed encoding using XOR Hashing and Mcrypt
+ * Provides two-way keyed encoding using Mcrypt
*
* @package CodeIgniter
* @subpackage Libraries
@@ -111,7 +111,7 @@ class CI_Encrypt {
$key = config_item('encryption_key');
- if ($key === FALSE)
+ if ( ! strlen($key))
{
show_error('In order to use the encryption class requires that you set an encryption key in your config file.');
}
diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php
index 810b7bf4a..1a61967a7 100644
--- a/system/libraries/Encryption.php
+++ b/system/libraries/Encryption.php
@@ -105,7 +105,6 @@ class CI_Encryption {
'cfb8' => 'cfb8',
'ctr' => 'ctr',
'stream' => '',
- 'gcm' => 'gcm',
'xts' => 'xts'
)
);
@@ -124,6 +123,13 @@ class CI_Encryption {
'sha512' => 64
);
+ /**
+ * mbstring.func_override flag
+ *
+ * @var bool
+ */
+ protected static $func_override;
+
// --------------------------------------------------------------------
/**
@@ -146,8 +152,10 @@ class CI_Encryption {
return 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'));
$this->initialize($params);
- if ( ! isset($this->_key) && strlen($key = config_item('encryption_key')) > 0)
+
+ if ( ! isset($this->_key) && self::strlen($key = config_item('encryption_key')) > 0)
{
$this->_key = $key;
}
@@ -310,6 +318,21 @@ class CI_Encryption {
// --------------------------------------------------------------------
/**
+ * Create a random key
+ *
+ * @param int $length Output length
+ * @return string
+ */
+ public function create_key($length)
+ {
+ return ($this->_driver === 'mcrypt')
+ ? mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)
+ : openssl_random_pseudo_bytes($length);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Encrypt
*
* @param string $data Input data
@@ -323,7 +346,7 @@ class CI_Encryption {
return FALSE;
}
- isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, strlen($this->_key), 'encryption');
+ isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, self::strlen($this->_key), 'encryption');
if (($data = $this->{'_'.$this->_driver.'_encrypt'}($data, $params)) === FALSE)
{
@@ -356,16 +379,14 @@ class CI_Encryption {
{
return FALSE;
}
- elseif ( ! isset($params['iv']))
- {
- // The greater-than-1 comparison is mostly a work-around for a bug,
- // where 1 is returned for ARCFour instead of 0.
- $params['iv'] = (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1)
- ? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM)
- : NULL;
- }
- if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0)
+ // 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)
+ : NULL;
+
+ if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0)
{
if ($params['handle'] !== $this->_handle)
{
@@ -380,7 +401,7 @@ class CI_Encryption {
if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE))
{
$block_size = mcrypt_enc_get_block_size($params['handle']);
- $pad = $block_size - (strlen($data) % $block_size);
+ $pad = $block_size - (self::strlen($data) % $block_size);
$data .= str_repeat(chr($pad), $pad);
}
@@ -396,7 +417,7 @@ class CI_Encryption {
// but OpenSSL isn't that dumb and we need to make the process
// portable, so ...
$data = (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB')
- ? $params['iv'].mcrypt_generic($params['handle'], $data)
+ ? $iv.mcrypt_generic($params['handle'], $data)
: mcrypt_generic($params['handle'], $data);
mcrypt_generic_deinit($params['handle']);
@@ -423,19 +444,17 @@ class CI_Encryption {
{
return FALSE;
}
- elseif ( ! isset($params['iv']))
- {
- $params['iv'] = ($iv_size = openssl_cipher_iv_length($params['handle']))
- ? openssl_random_pseudo_bytes($iv_size)
- : NULL;
- }
+
+ $iv = ($iv_size = openssl_cipher_iv_length($params['handle']))
+ ? openssl_random_pseudo_bytes($iv_size)
+ : NULL;
$data = openssl_encrypt(
$data,
$params['handle'],
$params['key'],
1, // DO NOT TOUCH!
- $params['iv']
+ $iv
);
if ($data === FALSE)
@@ -443,7 +462,7 @@ class CI_Encryption {
return FALSE;
}
- return $params['iv'].$data;
+ return $iv.$data;
}
// --------------------------------------------------------------------
@@ -470,13 +489,13 @@ class CI_Encryption {
? $this->_digests[$params['hmac_digest']] * 2
: $this->_digests[$params['hmac_digest']];
- if (strlen($data) <= $digest_size)
+ if (self::strlen($data) <= $digest_size)
{
return FALSE;
}
- $hmac_input = substr($data, 0, $digest_size);
- $data = substr($data, $digest_size);
+ $hmac_input = self::substr($data, 0, $digest_size);
+ $data = self::substr($data, $digest_size);
isset($params['hmac_key']) OR $params['hmac_key'] = $this->hkdf($this->_key, 'sha512', NULL, NULL, 'authentication');
$hmac_check = hash_hmac($params['hmac_digest'], $data, $params['hmac_key'], ! $params['base64']);
@@ -499,12 +518,7 @@ class CI_Encryption {
$data = base64_decode($data);
}
- if (isset($params['iv']) && strncmp($params['iv'], $data, $iv_size = strlen($params['iv'])) === 0)
- {
- $data = substr($data, $iv_size);
- }
-
- isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, strlen($this->_key), 'encryption');
+ isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, self::strlen($this->_key), 'encryption');
return $this->{'_'.$this->_driver.'_decrypt'}($data, $params);
}
@@ -524,30 +538,28 @@ class CI_Encryption {
{
return FALSE;
}
- elseif ( ! isset($params['iv']))
+
+ // The greater-than-1 comparison is mostly a work-around for a bug,
+ // where 1 is returned for ARCFour instead of 0.
+ if (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1)
{
- // The greater-than-1 comparison is mostly a work-around for a bug,
- // where 1 is returned for ARCFour instead of 0.
- if (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1)
+ if (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB')
{
- if (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB')
- {
- $params['iv'] = substr($data, 0, $iv_size);
- $data = substr($data, $iv_size);
- }
- else
- {
- // MCrypt is dumb and this is ignored, only size matters
- $params['iv'] = str_repeat("\x0", $iv_size);
- }
+ $iv = self::substr($data, 0, $iv_size);
+ $data = self::substr($data, $iv_size);
}
else
{
- $params['iv'] = NULL;
+ // MCrypt is dumb and this is ignored, only size matters
+ $iv = str_repeat("\x0", $iv_size);
}
}
+ else
+ {
+ $iv = NULL;
+ }
- if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0)
+ if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0)
{
if ($params['handle'] !== $this->_handle)
{
@@ -561,7 +573,7 @@ class CI_Encryption {
// Remove PKCS#7 padding, if necessary
if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE))
{
- $data = substr($data, 0, -ord($data[strlen($data)-1]));
+ $data = self::substr($data, 0, -ord($data[self::strlen($data)-1]));
}
mcrypt_generic_deinit($params['handle']);
@@ -584,17 +596,14 @@ class CI_Encryption {
*/
protected function _openssl_decrypt($data, $params)
{
- if ( ! isset($params['iv']))
+ if ($iv_size = openssl_cipher_iv_length($params['handle']))
{
- if ($iv_size = openssl_cipher_iv_length($params['handle']))
- {
- $params['iv'] = substr($data, 0, $iv_size);
- $data = substr($data, $iv_size);
- }
- else
- {
- $params['iv'] = NULL;
- }
+ $iv = self::substr($data, 0, $iv_size);
+ $data = self::substr($data, $iv_size);
+ }
+ else
+ {
+ $iv = NULL;
}
return empty($params['handle'])
@@ -604,7 +613,7 @@ class CI_Encryption {
$params['handle'],
$params['key'],
1, // DO NOT TOUCH!
- $params['iv']
+ $iv
);
}
@@ -627,7 +636,7 @@ class CI_Encryption {
'mode' => $this->_mode,
'key' => NULL,
'base64' => TRUE,
- 'hmac_digest' => ($this->_mode !== 'gcm' ? 'sha512' : NULL),
+ 'hmac_digest' => 'sha512',
'hmac_key' => NULL
)
: FALSE;
@@ -650,7 +659,7 @@ class CI_Encryption {
}
}
- if ($params['mode'] === 'gcm' OR (isset($params['hmac']) && $params['hmac'] === FALSE))
+ if (isset($params['hmac']) && $params['hmac'] === FALSE)
{
$params['hmac_digest'] = $params['hmac_key'] = NULL;
}
@@ -679,7 +688,6 @@ class CI_Encryption {
'cipher' => $params['cipher'],
'mode' => $params['mode'],
'key' => $params['key'],
- 'iv' => isset($params['iv']) ? $params['iv'] : NULL,
'base64' => isset($params['raw_data']) ? ! $params['raw_data'] : FALSE,
'hmac_digest' => $params['hmac_digest'],
'hmac_key' => $params['hmac_key']
@@ -828,17 +836,17 @@ class CI_Encryption {
return FALSE;
}
- strlen($salt) OR $salt = str_repeat("\0", $this->_digests[$digest]);
+ self::strlen($salt) OR $salt = str_repeat("\0", $this->_digests[$digest]);
$prk = hash_hmac($digest, $key, $salt, TRUE);
$key = '';
- for ($key_block = '', $block_index = 1; strlen($key) < $length; $block_index++)
+ for ($key_block = '', $block_index = 1; self::strlen($key) < $length; $block_index++)
{
$key_block = hash_hmac($digest, $key_block.$info.chr($block_index), $prk, TRUE);
$key .= $key_block;
}
- return substr($key, 0, $length);
+ return self::substr($key, 0, $length);
}
// --------------------------------------------------------------------
@@ -864,6 +872,45 @@ class CI_Encryption {
return NULL;
}
+ // --------------------------------------------------------------------
+
+ /**
+ * Byte-safe strlen()
+ *
+ * @param string $str
+ * @return integer
+ */
+ protected static function strlen($str)
+ {
+ return (self::$func_override)
+ ? 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_override)
+ {
+ // 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);
+ }
}
/* End of file Encryption.php */
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index dc5d17fb3..b640f1ec1 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -701,6 +701,12 @@ class CI_Form_validation {
{
$callable = TRUE;
}
+ elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1]))
+ {
+ // We have a "named" callable, so save the name
+ $callable = $rule[0];
+ $rule = $rule[1];
+ }
// Strip the parameter (if exists) from the rule
// Rules can contain a parameter: max_length[5]
@@ -712,7 +718,7 @@ class CI_Form_validation {
}
// Call the function that corresponds to the rule
- if ($callback OR $callable)
+ if ($callback OR $callable !== FALSE)
{
if ($callback)
{
@@ -730,8 +736,14 @@ class CI_Form_validation {
else
{
$result = is_array($rule)
- ? $rule[0]->{$rule[1]}($postdata, $param)
- : $rule($postdata, $param);
+ ? $rule[0]->{$rule[1]}($postdata)
+ : $rule($postdata);
+
+ // Is $callable set to a rule name?
+ if ($callable !== FALSE)
+ {
+ $rule = $callable;
+ }
}
// Re-assign the result to the master data array
@@ -791,28 +803,30 @@ class CI_Form_validation {
// Did the rule test negatively? If so, grab the error.
if ($result === FALSE)
{
- // Callable rules don't have named error messages
- if ( ! is_callable($rule))
+ // Callable rules might not have named error messages
+ if ( ! is_string($rule))
{
- // Check if a custom message is defined
- if (isset($this->_field_data[$row['field']]['errors'][$rule]))
- {
- $line = $this->_field_data[$row['field']]['errors'][$rule];
- }
- elseif ( ! isset($this->_error_messages[$rule]))
- {
- if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule))
- // DEPRECATED support for non-prefixed keys
- && FALSE === ($line = $this->CI->lang->line($rule, FALSE)))
- {
- $line = 'Unable to access an error message corresponding to your field name.';
- }
- }
- else
+ return;
+ }
+
+ // Check if a custom message is defined
+ if (isset($this->_field_data[$row['field']]['errors'][$rule]))
+ {
+ $line = $this->_field_data[$row['field']]['errors'][$rule];
+ }
+ elseif ( ! isset($this->_error_messages[$rule]))
+ {
+ if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule))
+ // DEPRECATED support for non-prefixed keys
+ && FALSE === ($line = $this->CI->lang->line($rule, FALSE)))
{
- $line = $this->_error_messages[$rule];
+ $line = 'Unable to access an error message corresponding to your field name.';
}
}
+ else
+ {
+ $line = $this->_error_messages[$rule];
+ }
// Is the parameter we are inserting into the error message the name
// of another field? If so we need to grab its "field label"
@@ -1225,6 +1239,11 @@ class CI_Form_validation {
*/
public function valid_email($str)
{
+ if (function_exists('idn_to_ascii') && $atpos = strpos($str, '@'))
+ {
+ $str = substr($str, 0, ++$atpos).idn_to_ascii(substr($str, $atpos));
+ }
+
return (bool) filter_var($str, FILTER_VALIDATE_EMAIL);
}
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index f1339b57a..39753705b 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -327,6 +327,13 @@ class CI_Image_lib {
public $full_dst_path = '';
/**
+ * File permissions
+ *
+ * @var int
+ */
+ public $file_permissions = 0644;
+
+ /**
* Name of function to create image
*
* @var string
@@ -734,7 +741,7 @@ class CI_Image_lib {
{
if ($this->source_image !== $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
{
- @chmod($this->full_dst_path, 0666);
+ chmod($this->full_dst_path, $this->file_permissions);
}
return TRUE;
@@ -810,8 +817,7 @@ class CI_Image_lib {
imagedestroy($dst_img);
imagedestroy($src_img);
- // Set the file to 666
- @chmod($this->full_dst_path, 0666);
+ chmod($this->full_dst_path, $this->file_permissions);
return TRUE;
}
@@ -880,8 +886,7 @@ class CI_Image_lib {
return FALSE;
}
- // Set the file to 666
- @chmod($this->full_dst_path, 0666);
+ chmod($this->full_dst_path, $this->file_permissions);
return TRUE;
}
@@ -969,7 +974,7 @@ class CI_Image_lib {
// we have to rename the temp file.
copy($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
unlink($this->dest_folder.'netpbm.tmp');
- @chmod($this->full_dst_path, 0666);
+ chmod($this->full_dst_path, $this->file_permissions);
return TRUE;
}
@@ -1013,8 +1018,7 @@ class CI_Image_lib {
imagedestroy($dst_img);
imagedestroy($src_img);
- // Set the file to 666
- @chmod($this->full_dst_path, 0666);
+ chmod($this->full_dst_path, $this->file_permissions);
return TRUE;
}
@@ -1086,8 +1090,7 @@ class CI_Image_lib {
// Kill the file handles
imagedestroy($src_img);
- // Set the file to 666
- @chmod($this->full_dst_path, 0666);
+ chmod($this->full_dst_path, $this->file_permissions);
return TRUE;
}
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 5b9bfcb5d..b7df06292 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -51,45 +51,45 @@ class CI_Pagination {
*
* @var string
*/
- protected $prefix = '';
+ protected $prefix = '';
/**
* Suffix
*
* @var string
*/
- protected $suffix = '';
+ protected $suffix = '';
/**
* Total number of items
*
* @var int
*/
- protected $total_rows = 0;
+ protected $total_rows = 0;
/**
- * Items per page
+ * Number of links to show
+ *
+ * Relates to "digit" type links shown before/after
+ * the currently viewed page.
*
* @var int
*/
- protected $per_page = 10;
+ protected $num_links = 2;
/**
- * Number of links to show
- *
- * Relates to "digit" type links shown before/after
- * the currently viewed page.
+ * Items per page
*
* @var int
*/
- protected $num_links = 2;
+ public $per_page = 10;
/**
* Current page
*
* @var int
*/
- protected $cur_page = 0;
+ public $cur_page = 0;
/**
* Use page numbers flag
@@ -98,84 +98,84 @@ class CI_Pagination {
*
* @var bool
*/
- protected $use_page_numbers = FALSE;
+ protected $use_page_numbers = FALSE;
/**
* First link
*
* @var string
*/
- protected $first_link = '&lsaquo; First';
+ protected $first_link = '&lsaquo; First';
/**
* Next link
*
* @var string
*/
- protected $next_link = '&gt;';
+ protected $next_link = '&gt;';
/**
* Previous link
*
* @var string
*/
- protected $prev_link = '&lt;';
+ protected $prev_link = '&lt;';
/**
* Last link
*
* @var string
*/
- protected $last_link = 'Last &rsaquo;';
+ protected $last_link = 'Last &rsaquo;';
/**
* URI Segment
*
* @var int
*/
- protected $uri_segment = 0;
+ protected $uri_segment = 0;
/**
* Full tag open
*
* @var string
*/
- protected $full_tag_open = '';
+ protected $full_tag_open = '';
/**
* Full tag close
*
* @var string
*/
- protected $full_tag_close = '';
+ protected $full_tag_close = '';
/**
* First tag open
*
* @var string
*/
- protected $first_tag_open = '';
+ protected $first_tag_open = '';
/**
* First tag close
*
* @var string
*/
- protected $first_tag_close = '';
+ protected $first_tag_close = '';
/**
* Last tag open
*
* @var string
*/
- protected $last_tag_open = '';
+ protected $last_tag_open = '';
/**
* Last tag close
*
* @var string
*/
- protected $last_tag_close = '';
+ protected $last_tag_close = '';
/**
* First URL
@@ -184,70 +184,70 @@ class CI_Pagination {
*
* @var string
*/
- protected $first_url = '';
+ protected $first_url = '';
/**
* Current tag open
*
* @var string
*/
- protected $cur_tag_open = '<strong>';
+ protected $cur_tag_open = '<strong>';
/**
* Current tag close
*
* @var string
*/
- protected $cur_tag_close = '</strong>';
+ protected $cur_tag_close = '</strong>';
/**
* Next tag open
*
* @var string
*/
- protected $next_tag_open = '';
+ protected $next_tag_open = '';
/**
* Next tag close
*
* @var string
*/
- protected $next_tag_close = '';
+ protected $next_tag_close = '';
/**
* Previous tag open
*
* @var string
*/
- protected $prev_tag_open = '';
+ protected $prev_tag_open = '';
/**
* Previous tag close
*
* @var string
*/
- protected $prev_tag_close = '';
+ protected $prev_tag_close = '';
/**
* Number tag open
*
* @var string
*/
- protected $num_tag_open = '';
+ protected $num_tag_open = '';
/**
* Number tag close
*
* @var string
*/
- protected $num_tag_close = '';
+ protected $num_tag_close = '';
/**
* Page query string flag
*
* @var bool
*/
- protected $page_query_string = FALSE;
+ protected $page_query_string = FALSE;
/**
* Query string segment
@@ -261,14 +261,14 @@ class CI_Pagination {
*
* @var bool
*/
- protected $display_pages = TRUE;
+ protected $display_pages = TRUE;
/**
* Attributes
*
* @var string
*/
- protected $_attributes = '';
+ protected $_attributes = '';
/**
* Link types
@@ -278,21 +278,21 @@ class CI_Pagination {
* @see CI_Pagination::_attr_rel()
* @var array
*/
- protected $_link_types = array();
+ protected $_link_types = array();
/**
* Reuse query string flag
*
* @var bool
*/
- protected $reuse_query_string = FALSE;
+ protected $reuse_query_string = FALSE;
/**
* Data page attribute
*
* @var string
*/
- protected $data_page_attr = 'data-ci-pagination-page';
+ protected $data_page_attr = 'data-ci-pagination-page';
/**
* CI Singleton
@@ -393,9 +393,9 @@ class CI_Pagination {
// Check the user defined number of links.
$this->num_links = (int) $this->num_links;
- if ($this->num_links < 1)
+ if ($this->num_links < 0)
{
- show_error('Your number of links must be a positive number.');
+ show_error('Your number of links must be a non-negative number.');
}
// Keep any existing query string items.
@@ -533,7 +533,7 @@ class CI_Pagination {
$output = '';
// Render the "First" link.
- if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1))
+ if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1 + ! $this->num_links))
{
// Take the general parameters, and squeeze this pagination-page attr in for JS frameworks.
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, 1);
@@ -609,7 +609,7 @@ class CI_Pagination {
}
// Render the "Last" link
- if ($this->last_link !== FALSE && ($this->cur_page + $this->num_links) < $num_pages)
+ if ($this->last_link !== FALSE && ($this->cur_page + $this->num_links + ! $this->num_links) < $num_pages)
{
$i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page;
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index d23a53423..2c2fc73b6 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -128,13 +128,20 @@ class CI_Parser {
return FALSE;
}
+ $replace = array();
foreach ($data as $key => $val)
{
- $template = is_array($val)
+ $replace = array_merge(
+ $replace,
+ is_array($val)
? $this->_parse_pair($key, $val, $template)
- : $template = $this->_parse_single($key, (string) $val, $template);
+ : $this->_parse_single($key, (string) $val, $template)
+ );
}
+ unset($data);
+ $template = strtr($template, $replace);
+
if ($return === FALSE)
{
$this->CI->output->append_output($template);
@@ -170,7 +177,7 @@ class CI_Parser {
*/
protected function _parse_single($key, $val, $string)
{
- return str_replace($this->l_delim.$key.$this->r_delim, (string) $val, $string);
+ return array($this->l_delim.$key.$this->r_delim => (string) $val);
}
// --------------------------------------------------------------------
@@ -187,50 +194,43 @@ class CI_Parser {
*/
protected function _parse_pair($variable, $data, $string)
{
- if (FALSE === ($matches = $this->_match_pair($string, $variable)))
- {
- return $string;
- }
+ $replace = array();
+ preg_match_all(
+ '#'.preg_quote($this->l_delim.$variable.$this->r_delim).'(.+?)'.preg_quote($this->l_delim.'/'.$variable.$this->r_delim).'#s',
+ $string,
+ $matches,
+ PREG_SET_ORDER
+ );
- $str = '';
- $search = $replace = array();
foreach ($matches as $match)
{
$str = '';
foreach ($data as $row)
{
- $temp = $match[1];
+ $temp = array();
foreach ($row as $key => $val)
{
- $temp = is_array($val)
- ? $this->_parse_pair($key, $val, $temp)
- : $this->_parse_single($key, $val, $temp);
+ if (is_array($val))
+ {
+ $pair = $this->_parse_pair($key, $val, $match[1]);
+ if ( ! empty($pair))
+ {
+ $temp = array_merge($temp, $pair);
+ }
+
+ continue;
+ }
+
+ $temp[$this->l_delim.$key.$this->r_delim] = $val;
}
- $str .= $temp;
+ $str .= strtr($match[1], $temp);
}
- $search[] = $match[0];
- $replace[] = $str;
+ $replace[$match[0]] = $str;
}
- return str_replace($search, $replace, $string);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Matches a variable pair
- *
- * @param string $string
- * @param string $variable
- * @return mixed
- */
- protected function _match_pair($string, $variable)
- {
- return preg_match_all('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s',
- $string, $match, PREG_SET_ORDER)
- ? $match : FALSE;
+ return $replace;
}
}
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 75fc0624f..49c69a32c 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -327,23 +327,26 @@ class CI_Upload {
$this->$key = $defaults[$key];
}
}
-
- return $this;
+
}
-
- foreach ($config as $key => &$value)
+ else
{
- if ($key[0] !== '_' && $reflection->hasProperty($key))
+
+ foreach ($config as $key => &$value)
{
- if ($reflection->hasMethod('set_'.$key))
- {
- $this->{'set_'.$key}($value);
- }
- else
+ if ($key[0] !== '_' && $reflection->hasProperty($key))
{
- $this->$key = $value;
+ if ($reflection->hasMethod('set_'.$key))
+ {
+ $this->{'set_'.$key}($value);
+ }
+ else
+ {
+ $this->$key = $value;
+ }
}
}
+
}
// if a file_name was provided in the config, use it instead of the user input
@@ -1155,28 +1158,14 @@ class CI_Upload {
*/
protected function _prep_filename($filename)
{
- if ($this->mod_mime_fix === FALSE OR $this->allowed_types === '*' OR strpos($filename, '.') === FALSE)
+ if ($this->mod_mime_fix === FALSE OR $this->allowed_types === '*' OR ($ext_pos = strrpos($filename, '.')) === FALSE)
{
return $filename;
}
- $parts = explode('.', $filename);
- $ext = array_pop($parts);
- $filename = array_shift($parts);
-
- foreach ($parts as $part)
- {
- if ( ! in_array(strtolower($part), $this->allowed_types) OR ! isset($this->_mimes[strtolower($part)]))
- {
- $filename .= '.'.$part.'_';
- }
- else
- {
- $filename .= '.'.$part;
- }
- }
-
- return $filename.'.'.$ext;
+ $ext = substr($filename, $ext_pos);
+ $filename = substr($filename, 0, $ext_pos);
+ return str_replace('.', '_', $filename).$ext;
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index ab30a9019..62a84ae75 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -405,7 +405,7 @@ class CI_Zip {
flock($fp, LOCK_EX);
- for ($written = 0, $data = $this->get_zip(), $length = strlen($data); $written < $length; $written += $result)
+ for ($result = $written = 0, $data = $this->get_zip(), $length = strlen($data); $written < $length; $written += $result)
{
if (($result = fwrite($fp, substr($data, $written))) === FALSE)
{