codeigniter v2.1.1

This commit is contained in:
Claude 2012-09-02 14:35:49 +02:00
parent 7c5b559397
commit 4c3e571e3b
24 changed files with 409 additions and 169 deletions

View File

@ -93,8 +93,8 @@ $mimes = array( 'hqx' => 'application/mac-binhex40',
'avi' => 'video/x-msvideo', 'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie', 'movie' => 'video/x-sgi-movie',
'doc' => 'application/msword', 'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'),
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip'),
'word' => array('application/msword', 'application/octet-stream'), 'word' => array('application/msword', 'application/octet-stream'),
'xl' => 'application/excel', 'xl' => 'application/excel',
'eml' => 'message/rfc822', 'eml' => 'message/rfc822',

View File

@ -33,7 +33,7 @@
* @var string * @var string
* *
*/ */
define('CI_VERSION', '2.1.0'); define('CI_VERSION', '2.1.2');
/** /**
* CodeIgniter Branch (Core = TRUE, Reactor = FALSE) * CodeIgniter Branch (Core = TRUE, Reactor = FALSE)

View File

@ -365,18 +365,70 @@ class CI_Input {
/** /**
* Validate IP Address * Validate IP Address
* *
* Updated version suggested by Geert De Deckere
*
* @access public * @access public
* @param string * @param string
* @return string * @param string ipv4 or ipv6
* @return bool
*/ */
function valid_ip($ip) public function valid_ip($ip, $which = '')
{
$which = strtolower($which);
// First check if filter_var is available
if (is_callable('filter_var'))
{
switch ($which) {
case 'ipv4':
$flag = FILTER_FLAG_IPV4;
break;
case 'ipv6':
$flag = FILTER_FLAG_IPV6;
break;
default:
$flag = '';
break;
}
return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag);
}
if ($which !== 'ipv6' && $which !== 'ipv4')
{
if (strpos($ip, ':') !== FALSE)
{
$which = 'ipv6';
}
elseif (strpos($ip, '.') !== FALSE)
{
$which = 'ipv4';
}
else
{
return FALSE;
}
}
$func = '_valid_'.$which;
return $this->$func($ip);
}
// --------------------------------------------------------------------
/**
* Validate IPv4 Address
*
* Updated version suggested by Geert De Deckere
*
* @access protected
* @param string
* @return bool
*/
protected function _valid_ipv4($ip)
{ {
$ip_segments = explode('.', $ip); $ip_segments = explode('.', $ip);
// Always 4 segments needed // Always 4 segments needed
if (count($ip_segments) != 4) if (count($ip_segments) !== 4)
{ {
return FALSE; return FALSE;
} }
@ -385,6 +437,7 @@ class CI_Input {
{ {
return FALSE; return FALSE;
} }
// Check each segment // Check each segment
foreach ($ip_segments as $segment) foreach ($ip_segments as $segment)
{ {
@ -401,6 +454,80 @@ class CI_Input {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/**
* Validate IPv6 Address
*
* @access protected
* @param string
* @return bool
*/
protected function _valid_ipv6($str)
{
// 8 groups, separated by :
// 0-ffff per group
// one set of consecutive 0 groups can be collapsed to ::
$groups = 8;
$collapsed = FALSE;
$chunks = array_filter(
preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE)
);
// Rule out easy nonsense
if (current($chunks) == ':' OR end($chunks) == ':')
{
return FALSE;
}
// PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well
if (strpos(end($chunks), '.') !== FALSE)
{
$ipv4 = array_pop($chunks);
if ( ! $this->_valid_ipv4($ipv4))
{
return FALSE;
}
$groups--;
}
while ($seg = array_pop($chunks))
{
if ($seg[0] == ':')
{
if (--$groups == 0)
{
return FALSE; // too many groups
}
if (strlen($seg) > 2)
{
return FALSE; // long separator
}
if ($seg == '::')
{
if ($collapsed)
{
return FALSE; // multiple collapsed
}
$collapsed = TRUE;
}
}
elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4)
{
return FALSE; // invalid segment
}
}
return $collapsed OR $groups == 1;
}
// --------------------------------------------------------------------
/** /**
* User Agent * User Agent
* *

View File

@ -89,10 +89,11 @@ class CI_Security {
* @access protected * @access protected
*/ */
protected $_never_allowed_regex = array( protected $_never_allowed_regex = array(
"javascript\s*:" => '[removed]', 'javascript\s*:',
"expression\s*(\(|&\#40;)" => '[removed]', // CSS and IE 'expression\s*(\(|&\#40;)', // CSS and IE
"vbscript\s*:" => '[removed]', // IE, surprise! 'vbscript\s*:', // IE, surprise!
"Redirect\s+302" => '[removed]' 'Redirect\s+302',
"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
); );
/** /**
@ -364,7 +365,7 @@ class CI_Security {
* These words are compacted back to their correct state. * These words are compacted back to their correct state.
*/ */
$words = array( $words = array(
'javascript', 'expression', 'vbscript', 'script', 'javascript', 'expression', 'vbscript', 'script', 'base64',
'applet', 'alert', 'document', 'write', 'cookie', 'window' 'applet', 'alert', 'document', 'write', 'cookie', 'window'
); );
@ -619,10 +620,11 @@ class CI_Security {
$attribs = array(); $attribs = array();
// find occurrences of illegal attribute strings without quotes // find occurrences of illegal attribute strings without quotes
preg_match_all("/(".implode('|', $evil_attributes).")\s*=\s*([^\s]*)/is", $str, $matches, PREG_SET_ORDER); preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
foreach ($matches as $attr) foreach ($matches as $attr)
{ {
$attribs[] = preg_quote($attr[0], '/'); $attribs[] = preg_quote($attr[0], '/');
} }
@ -637,7 +639,7 @@ class CI_Security {
// replace illegal attribute strings that are inside an html tag // replace illegal attribute strings that are inside an html tag
if (count($attribs) > 0) if (count($attribs) > 0)
{ {
$str = preg_replace("/<(\/?[^><]+?)([^A-Za-z\-])(".implode('|', $attribs).")([\s><])([><]*)/i", '<$1$2$4$5', $str, -1, $count); $str = preg_replace("/<(\/?[^><]+?)([^A-Za-z<>\-])(.*?)(".implode('|', $attribs).")(.*?)([\s><])([><]*)/i", '<$1 $3$5$6$7', $str, -1, $count);
} }
} while ($count); } while ($count);
@ -682,9 +684,15 @@ class CI_Security {
*/ */
protected function _js_link_removal($match) protected function _js_link_removal($match)
{ {
$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); return str_replace(
$match[1],
return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]); preg_replace(
'#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
'',
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
),
$match[0]
);
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -702,9 +710,15 @@ class CI_Security {
*/ */
protected function _js_img_removal($match) protected function _js_img_removal($match)
{ {
$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); return str_replace(
$match[1],
return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]); preg_replace(
'#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
'',
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
),
$match[0]
);
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -819,14 +833,11 @@ class CI_Security {
*/ */
protected function _do_never_allowed($str) protected function _do_never_allowed($str)
{ {
foreach ($this->_never_allowed_str as $key => $val) $str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str);
{
$str = str_replace($key, $val, $str);
}
foreach ($this->_never_allowed_regex as $key => $val) foreach ($this->_never_allowed_regex as $regex)
{ {
$str = preg_replace("#".$key."#i", $val, $str); $str = preg_replace('#'.$regex.'#is', '[removed]', $str);
} }
return $str; return $str;
@ -848,7 +859,7 @@ class CI_Security {
// each page load since a page could contain embedded // each page load since a page could contain embedded
// sub-pages causing this feature to fail // sub-pages causing this feature to fail
if (isset($_COOKIE[$this->_csrf_cookie_name]) && if (isset($_COOKIE[$this->_csrf_cookie_name]) &&
$_COOKIE[$this->_csrf_cookie_name] != '') preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->_csrf_cookie_name]) === 1)
{ {
return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name]; return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
} }

View File

@ -661,7 +661,11 @@ class CI_DB_active_record extends CI_DB_driver {
$v = $this->escape_like_str($v); $v = $this->escape_like_str($v);
if ($side == 'before') if ($side == 'none')
{
$like_statement = $prefix." $k $not LIKE '{$v}'";
}
elseif ($side == 'before')
{ {
$like_statement = $prefix." $k $not LIKE '%{$v}'"; $like_statement = $prefix." $k $not LIKE '%{$v}'";
} }
@ -1643,7 +1647,7 @@ class CI_DB_active_record extends CI_DB_driver {
if (strpos($table, " ") !== FALSE) if (strpos($table, " ") !== FALSE)
{ {
// if the alias is written with the AS keyword, remove it // if the alias is written with the AS keyword, remove it
$table = preg_replace('/ AS /i', ' ', $table); $table = preg_replace('/\s+AS\s+/i', ' ', $table);
// Grab the alias // Grab the alias
$table = trim(strrchr($table, " ")); $table = trim(strrchr($table, " "));

View File

@ -265,6 +265,12 @@ class CI_DB_driver {
$sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql); $sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);
} }
// Compile binds if needed
if ($binds !== FALSE)
{
$sql = $this->compile_binds($sql, $binds);
}
// Is query caching enabled? If the query is a "read type" // Is query caching enabled? If the query is a "read type"
// we will load the caching class and return the previously // we will load the caching class and return the previously
// cached query if it exists // cached query if it exists
@ -280,12 +286,6 @@ class CI_DB_driver {
} }
} }
// Compile binds if needed
if ($binds !== FALSE)
{
$sql = $this->compile_binds($sql, $binds);
}
// Save the query for debugging // Save the query for debugging
if ($this->save_queries == TRUE) if ($this->save_queries == TRUE)
{ {
@ -1015,10 +1015,16 @@ class CI_DB_driver {
else else
{ {
$args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null; $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
if (is_null($args))
{
return call_user_func($function);
}
else
{
return call_user_func_array($function, $args); return call_user_func_array($function, $args);
} }
} }
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -1261,12 +1267,15 @@ class CI_DB_driver {
// If the item has an alias declaration we remove it and set it aside. // If the item has an alias declaration we remove it and set it aside.
// Basically we remove everything to the right of the first space // Basically we remove everything to the right of the first space
$alias = '';
if (strpos($item, ' ') !== FALSE) if (strpos($item, ' ') !== FALSE)
{ {
$alias = strstr($item, " "); $alias = strstr($item, ' ');
$item = substr($item, 0, - strlen($alias)); $item = substr($item, 0, - strlen($alias));
} }
else
{
$alias = '';
}
// This is basically a bug fix for queries that use MAX, MIN, etc. // This is basically a bug fix for queries that use MAX, MIN, etc.
// If a parenthesis is found we know that we do not need to // If a parenthesis is found we know that we do not need to
@ -1382,9 +1391,20 @@ class CI_DB_driver {
return $item.$alias; return $item.$alias;
} }
// --------------------------------------------------------------------
/**
* Dummy method that allows Active Record class to be disabled
*
* This function is used extensively by every db driver.
*
* @return void
*/
protected function _reset_select()
{
}
} }
/* End of file DB_driver.php */ /* End of file DB_driver.php */
/* Location: ./system/database/DB_driver.php */ /* Location: ./system/database/DB_driver.php */

View File

@ -9,7 +9,7 @@
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @author EllisLab Dev Team * @author EllisLab Dev Team
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.1.0 * @since Version 2.1.2
* @filesource * @filesource
*/ */
@ -78,7 +78,7 @@ class CI_DB_pdo_driver extends CI_DB {
$this->_like_escape_chr = '!'; $this->_like_escape_chr = '!';
} }
$this->hostname .= ";dbname=".$this->database; empty($this->database) OR $this->hostname .= ';dbname='.$this->database;
$this->trans_enabled = FALSE; $this->trans_enabled = FALSE;
@ -189,12 +189,21 @@ class CI_DB_pdo_driver extends CI_DB {
function _execute($sql) function _execute($sql)
{ {
$sql = $this->_prep_query($sql); $sql = $this->_prep_query($sql);
$result_id = $this->conn_id->query($sql); $result_id = $this->conn_id->prepare($sql);
$result_id->execute();
if (is_object($result_id)) if (is_object($result_id))
{
if (is_numeric(stripos($sql, 'SELECT')))
{
$this->affect_rows = count($result_id->fetchAll());
$result_id->execute();
}
else
{ {
$this->affect_rows = $result_id->rowCount(); $this->affect_rows = $result_id->rowCount();
} }
}
else else
{ {
$this->affect_rows = 0; $this->affect_rows = 0;

View File

@ -9,7 +9,7 @@
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @author EllisLab Dev Team * @author EllisLab Dev Team
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.1.0 * @since Version 2.1.2
* @filesource * @filesource
*/ */

View File

@ -9,7 +9,7 @@
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @author EllisLab Dev Team * @author EllisLab Dev Team
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.1.0 * @since Version 2.1.2
* @filesource * @filesource
*/ */
@ -33,9 +33,20 @@ class CI_DB_pdo_result extends CI_DB_result {
* @return integer * @return integer
*/ */
function num_rows() function num_rows()
{
if (is_numeric(stripos($this->result_id->queryString, 'SELECT')))
{
$dbh = $this->conn_id;
$query = $dbh->query($this->result_id->queryString);
$result = $query->fetchAll();
unset($dbh, $query);
return count($result);
}
else
{ {
return $this->result_id->rowCount(); return $this->result_id->rowCount();
} }
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------

View File

@ -9,7 +9,7 @@
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @author EllisLab Dev Team * @author EllisLab Dev Team
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.1.0 * @since Version 2.1.2
* @filesource * @filesource
*/ */

View File

@ -65,7 +65,7 @@ if ( ! function_exists('form_open'))
$form .= '>'; $form .= '>';
// Add CSRF field if enabled, but leave it out for GET requests and requests to external websites // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites
if ($CI->config->item('csrf_protection') === TRUE AND ! (strpos($action, $CI->config->site_url()) === FALSE OR strpos($form, 'method="get"'))) if ($CI->config->item('csrf_protection') === TRUE AND ! (strpos($action, $CI->config->base_url()) === FALSE OR strpos($form, 'method="get"')))
{ {
$hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash(); $hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash();
} }

View File

@ -466,38 +466,34 @@ if ( ! function_exists('prep_url'))
* Create URL Title * Create URL Title
* *
* Takes a "title" string as input and creates a * Takes a "title" string as input and creates a
* human-friendly URL string with either a dash * human-friendly URL string with a "separator" string
* or an underscore as the word separator. * as the word separator.
* *
* @access public * @access public
* @param string the string * @param string the string
* @param string the separator: dash, or underscore * @param string the separator
* @return string * @return string
*/ */
if ( ! function_exists('url_title')) if ( ! function_exists('url_title'))
{ {
function url_title($str, $separator = 'dash', $lowercase = FALSE) function url_title($str, $separator = '-', $lowercase = FALSE)
{ {
if ($separator == 'dash') if ($separator == 'dash')
{ {
$search = '_'; $separator = '-';
$replace = '-';
} }
else else if ($separator == 'underscore')
{ {
$search = '-'; $separator = '_';
$replace = '_';
} }
$q_separator = preg_quote($separator);
$trans = array( $trans = array(
'&\#\d+?;' => '', '&.+?;' => '',
'&\S+?;' => '', '[^a-z0-9 _-]' => '',
'\s+' => $replace, '\s+' => $separator,
'[^a-z0-9\-\._]' => '', '('.$q_separator.')+' => $separator
$replace.'+' => $replace,
$replace.'$' => $replace,
'^'.$replace => $replace,
'\.+$' => ''
); );
$str = strip_tags($str); $str = strip_tags($str);
@ -512,7 +508,7 @@ if ( ! function_exists('url_title'))
$str = strtolower($str); $str = strtolower($str);
} }
return trim(stripslashes($str)); return trim($str, $separator);
} }
} }

View File

@ -5,7 +5,7 @@ $lang['migration_not_found'] = "This migration could not be found.";
$lang['migration_multiple_version'] = "This are multiple migrations with the same version number: %d."; $lang['migration_multiple_version'] = "This are multiple migrations with the same version number: %d.";
$lang['migration_class_doesnt_exist'] = "The migration class \"%s\" could not be found."; $lang['migration_class_doesnt_exist'] = "The migration class \"%s\" could not be found.";
$lang['migration_missing_up_method'] = "The migration class \"%s\" is missing an 'up' method."; $lang['migration_missing_up_method'] = "The migration class \"%s\" is missing an 'up' method.";
$lang['migration_missing_down_method'] = "The migration class \"%s\" is missing an 'up' method."; $lang['migration_missing_down_method'] = "The migration class \"%s\" is missing an 'down' method.";
$lang['migration_invalid_filename'] = "Migration \"%s\" has an invalid filename."; $lang['migration_invalid_filename'] = "Migration \"%s\" has an invalid filename.";

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author ExpressionEngine Dev Team * @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006 - 2011 EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.0 * @since Version 2.0

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author ExpressionEngine Dev Team * @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006 - 2011 EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.0 * @since Version 2.0

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author ExpressionEngine Dev Team * @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006 - 2011 EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.0 * @since Version 2.0

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author ExpressionEngine Dev Team * @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006 - 2011 EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.0 * @since Version 2.0

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author ExpressionEngine Dev Team * @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006 - 2011 EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 2.0 * @since Version 2.0

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author ExpressionEngine Dev Team * @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006 - 2011, EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 1.0 * @since Version 1.0

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author EllisLab Dev Team * @author EllisLab Dev Team
* @copyright Copyright (c) 2006 - 2011, EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 1.0 * @since Version 1.0
@ -30,7 +30,7 @@
class CI_Driver_Library { class CI_Driver_Library {
protected $valid_drivers = array(); protected $valid_drivers = array();
protected static $lib_name; protected $lib_name;
// The first time a child is used it won't exist, so we instantiate it // The first time a child is used it won't exist, so we instantiate it
// subsequents calls will go straight to the proper child. // subsequents calls will go straight to the proper child.

View File

@ -1079,11 +1079,12 @@ class CI_Form_validation {
* *
* @access public * @access public
* @param string * @param string
* @param string "ipv4" or "ipv6" to validate a specific ip format
* @return string * @return string
*/ */
public function valid_ip($ip) public function valid_ip($ip, $which = '')
{ {
return $this->CI->input->valid_ip($ip); return $this->CI->input->valid_ip($ip, $which);
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------

View File

@ -104,7 +104,7 @@ class CI_Image_lib {
*/ */
function clear() function clear()
{ {
$props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity'); $props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'width', 'height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity');
foreach ($props as $val) foreach ($props as $val)
{ {
@ -208,7 +208,7 @@ class CI_Image_lib {
} }
else else
{ {
if (strpos($this->new_image, '/') === FALSE) if (strpos($this->new_image, '/') === FALSE AND strpos($this->new_image, '\\') === FALSE)
{ {
$this->dest_folder = $this->source_folder; $this->dest_folder = $this->source_folder;
$this->dest_image = $this->new_image; $this->dest_image = $this->new_image;

View File

@ -6,7 +6,7 @@
* *
* @package CodeIgniter * @package CodeIgniter
* @author EllisLab Dev Team * @author EllisLab Dev Team
* @copyright Copyright (c) 2006 - 2011, EllisLab, Inc. * @copyright Copyright (c) 2006 - 2012, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html * @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com * @link http://codeigniter.com
* @since Version 1.0 * @since Version 1.0

View File

@ -868,6 +868,10 @@ class CI_Upload {
{ {
return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good
} }
else
{
return FALSE;
}
} }
if (($data = @file_get_contents($file)) === FALSE) if (($data = @file_get_contents($file)) === FALSE)
@ -1018,47 +1022,104 @@ class CI_Upload {
*/ */
protected function _file_mime_type($file) protected function _file_mime_type($file)
{ {
// Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag) // We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii)
if ( (float) substr(phpversion(), 0, 3) >= 5.3 && function_exists('finfo_file')) $regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/';
/* Fileinfo extension - most reliable method
*
* Unfortunately, prior to PHP 5.3 - it's only available as a PECL extension and the
* more convenient FILEINFO_MIME_TYPE flag doesn't exist.
*/
if (function_exists('finfo_file'))
{ {
$finfo = new finfo(FILEINFO_MIME_TYPE); $finfo = finfo_open(FILEINFO_MIME);
if ($finfo !== FALSE) // This is possible, if there is no magic MIME database file found on the system if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
{ {
$file_type = $finfo->file($file['tmp_name']); $mime = @finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
/* According to the comments section of the PHP manual page, /* According to the comments section of the PHP manual page,
* it is possible that this function returns an empty string * it is possible that this function returns an empty string
* for some files (e.g. if they don't exist in the magic MIME database) * for some files (e.g. if they don't exist in the magic MIME database)
*/ */
if (strlen($file_type) > 1) if (is_string($mime) && preg_match($regexp, $mime, $matches))
{ {
$this->file_type = $file_type; $this->file_type = $matches[1];
return; return;
} }
} }
} }
// Fall back to the deprecated mime_content_type(), if available /* This is an ugly hack, but UNIX-type systems provide a "native" way to detect the file type,
* which is still more secure than depending on the value of $_FILES[$field]['type'], and as it
* was reported in issue #750 (https://github.com/EllisLab/CodeIgniter/issues/750) - it's better
* than mime_content_type() as well, hence the attempts to try calling the command line with
* three different functions.
*
* Notes:
* - the DIRECTORY_SEPARATOR comparison ensures that we're not on a Windows system
* - many system admins would disable the exec(), shell_exec(), popen() and similar functions
* due to security concerns, hence the function_exists() checks
*/
if (DIRECTORY_SEPARATOR !== '\\')
{
$cmd = 'file --brief --mime ' . escapeshellarg($file['tmp_name']) . ' 2>&1';
if (function_exists('exec'))
{
/* This might look confusing, as $mime is being populated with all of the output when set in the second parameter.
* However, we only neeed the last line, which is the actual return value of exec(), and as such - it overwrites
* anything that could already be set for $mime previously. This effectively makes the second parameter a dummy
* value, which is only put to allow us to get the return status code.
*/
$mime = @exec($cmd, $mime, $return_status);
if ($return_status === 0 && is_string($mime) && preg_match($regexp, $mime, $matches))
{
$this->file_type = $matches[1];
return;
}
}
if ( (bool) @ini_get('safe_mode') === FALSE && function_exists('shell_exec'))
{
$mime = @shell_exec($cmd);
if (strlen($mime) > 0)
{
$mime = explode("\n", trim($mime));
if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
{
$this->file_type = $matches[1];
return;
}
}
}
if (function_exists('popen'))
{
$proc = @popen($cmd, 'r');
if (is_resource($proc))
{
$mime = @fread($proc, 512);
@pclose($proc);
if ($mime !== FALSE)
{
$mime = explode("\n", trim($mime));
if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
{
$this->file_type = $matches[1];
return;
}
}
}
}
}
// Fall back to the deprecated mime_content_type(), if available (still better than $_FILES[$field]['type'])
if (function_exists('mime_content_type')) if (function_exists('mime_content_type'))
{ {
$this->file_type = @mime_content_type($file['tmp_name']); $this->file_type = @mime_content_type($file['tmp_name']);
return; if (strlen($this->file_type) > 0) // It's possible that mime_content_type() returns FALSE or an empty string
}
/* This is an ugly hack, but UNIX-type systems provide a native way to detect the file type,
* which is still more secure than depending on the value of $_FILES[$field]['type'].
*
* Notes:
* - a 'W' in the substr() expression bellow, would mean that we're using Windows
* - many system admins would disable the exec() function due to security concerns, hence the function_exists() check
*/
if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec'))
{ {
$output = array();
@exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code);
if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution
{
$this->file_type = rtrim($output[0]);
return; return;
} }
} }