summaryrefslogtreecommitdiffstats
path: root/system/core
diff options
context:
space:
mode:
authorAndrey Andreev <narf@bofh.bg>2012-10-12 10:56:34 +0200
committerAndrey Andreev <narf@bofh.bg>2012-10-12 10:56:34 +0200
commitbffe3fb935c8a28e1ccacf56f678a491edcff043 (patch)
tree5a39ba6907623d5ad46b7d13ef17e360df1dfe5e /system/core
parent55b82c95be57a6727d45d6ae9652ff612f96bc37 (diff)
parent9ae82faaad2f6b07a050d79129652b74483d1da0 (diff)
Merge changes from develop
Diffstat (limited to 'system/core')
-rw-r--r--system/core/CodeIgniter.php2
-rw-r--r--system/core/Common.php62
-rw-r--r--system/core/Config.php2
-rw-r--r--system/core/Input.php132
-rw-r--r--system/core/Loader.php51
-rw-r--r--system/core/Output.php6
-rw-r--r--system/core/Utf8.php39
7 files changed, 209 insertions, 85 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 8159b19f5..f3592eaf9 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -50,7 +50,7 @@
* Load the global functions
* ------------------------------------------------------
*/
- require(BASEPATH.'core/Common.php');
+ require_once(BASEPATH.'core/Common.php');
/*
* ------------------------------------------------------
diff --git a/system/core/Common.php b/system/core/Common.php
index 06b162264..341402c6b 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -150,7 +150,7 @@ if ( ! function_exists('load_class'))
if (class_exists($name) === FALSE)
{
- require($path.$directory.'/'.$class.'.php');
+ require_once($path.$directory.'/'.$class.'.php');
}
break;
@@ -164,7 +164,7 @@ if ( ! function_exists('load_class'))
if (class_exists($name) === FALSE)
{
- require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
+ require_once(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
}
}
@@ -488,13 +488,9 @@ if ( ! function_exists('set_status_header'))
{
header('Status: '.$code.' '.$text, TRUE);
}
- elseif ($server_protocol === 'HTTP/1.0')
- {
- header('HTTP/1.0 '.$code.' '.$text, TRUE, $code);
- }
else
{
- header('HTTP/1.1 '.$code.' '.$text, TRUE, $code);
+ header(($server_protocol ? $server_protocol : 'HTTP/1.1').' '.$code.' '.$text, TRUE, $code);
}
}
}
@@ -524,18 +520,17 @@ if ( ! function_exists('_exception_handler'))
{
$_error =& load_class('Exceptions', 'core');
- // Should we display the error? We'll get the current error_reporting
+ // Should we ignore the error? We'll get the current error_reporting
// level and add its bits with the severity bits to find out.
- // And respect display_errors
- if (($severity & error_reporting()) === $severity && (bool) ini_get('display_errors') === TRUE)
+ if (($severity & error_reporting()) !== $severity)
{
- $_error->show_php_error($severity, $message, $filepath, $line);
+ return;
}
- // Should we log the error? No? We're done...
- if (config_item('log_threshold') === 0)
+ // Should we display the error?
+ if ((bool) ini_get('display_errors') === TRUE)
{
- return;
+ $_error->show_php_error($severity, $message, $filepath, $line);
}
$_error->log_exception($severity, $message, $filepath, $line);
@@ -598,5 +593,44 @@ if ( ! function_exists('html_escape'))
}
}
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('_stringify_attributes'))
+{
+ /**
+ * Stringify attributes for use in HTML tags.
+ *
+ * Helper function used to convert a string, array, or object
+ * of attributes to a string.
+ *
+ * @param mixed string, array, object
+ * @param bool
+ * @return string
+ */
+ function _stringify_attributes($attributes, $js = FALSE)
+ {
+ $atts = NULL;
+
+ if (empty($attributes))
+ {
+ return $atts;
+ }
+
+ if (is_string($attributes))
+ {
+ return ' '.$attributes;
+ }
+
+ $attributes = (array) $attributes;
+
+ foreach ($attributes as $key => $val)
+ {
+ $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"';
+ }
+
+ return rtrim($atts, ',');
+ }
+}
+
/* End of file Common.php */
/* Location: ./system/core/Common.php */ \ No newline at end of file
diff --git a/system/core/Config.php b/system/core/Config.php
index 2f6a9e085..8e4f998ef 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -102,7 +102,7 @@ class CI_Config {
{
$file = ($file === '') ? 'config' : str_replace('.php', '', $file);
$found = $loaded = FALSE;
-
+
$check_locations = defined('ENVIRONMENT')
? array(ENVIRONMENT.'/'.$file, $file)
: array($file);
diff --git a/system/core/Input.php b/system/core/Input.php
index 162e40c85..82482f2aa 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -328,39 +328,113 @@ class CI_Input {
return $this->ip_address;
}
- if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR'))
+ $proxy_ips = config_item('proxy_ips');
+ if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
{
- $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY);
- $proxies = is_array($proxies) ? $proxies : array($proxies);
-
- $this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
- }
- elseif ( ! $this->server('HTTP_CLIENT_IP') && $this->server('REMOTE_ADDR'))
- {
- $this->ip_address = $_SERVER['REMOTE_ADDR'];
- }
- elseif ($this->server('REMOTE_ADDR') && $this->server('HTTP_CLIENT_IP'))
- {
- $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
- }
- elseif ($this->server('HTTP_CLIENT_IP'))
- {
- $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
- }
- elseif ($this->server('HTTP_X_FORWARDED_FOR'))
- {
- $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
+ $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
}
- if ($this->ip_address === FALSE)
- {
- return $this->ip_address = '0.0.0.0';
- }
+ $this->ip_address = $this->server('REMOTE_ADDR');
- if (strpos($this->ip_address, ',') !== FALSE)
+ if ($proxy_ips)
{
- $x = explode(',', $this->ip_address);
- $this->ip_address = trim(end($x));
+ foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header)
+ {
+ if (($spoof = $this->server($header)) !== NULL)
+ {
+ // Some proxies typically list the whole chain of IP
+ // addresses through which the client has reached us.
+ // e.g. client_ip, proxy_ip1, proxy_ip2, etc.
+ if (strpos($spoof, ',') !== FALSE)
+ {
+ $spoof = explode(',', $spoof, 2);
+ $spoof = $spoof[0];
+ }
+
+ if ( ! $this->valid_ip($spoof))
+ {
+ $spoof = NULL;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ if ($spoof)
+ {
+ for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
+ {
+ // Check if we have an IP address or a subnet
+ if (strpos($proxy_ips[$i], '/') === FALSE)
+ {
+ // An IP address (and not a subnet) is specified.
+ // We can compare right away.
+ if ($proxy_ips[$i] === $this->ip_address)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+
+ continue;
+ }
+
+ // We have a subnet ... now the heavy lifting begins
+ isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
+
+ // If the proxy entry doesn't match the IP protocol - skip it
+ if (strpos($proxy_ips[$i], $separator) === FALSE)
+ {
+ continue;
+ }
+
+ // Convert the REMOTE_ADDR IP address to binary, if needed
+ if ( ! isset($ip, $convert_func))
+ {
+ if ($separator === ':')
+ {
+ // Make sure we're have the "full" IPv6 format
+ $ip = str_replace('::', str_repeat(':', 9 - substr_count($this->ip_address, ':')), $this->ip_address);
+ $convert_func = is_php('5.3')
+ ? function ($value)
+ {
+ return str_pad(base_convert($value, 16, 2), 16, '0', STR_PAD_LEFT);
+ }
+ : create_function('$value', 'return str_pad(base_convert($value, 16, 2), 16, "0", STR_PAD_LEFT);');
+ }
+ else
+ {
+ $ip = $this->ip_address;
+ $convert_func = is_php('5.3')
+ ? function ($value)
+ {
+ return str_pad(decbin($value), 8, '0', STR_PAD_LEFT);
+ }
+ : create_function('$value', 'return str_pad(decbin($value), 8, "0", STR_PAD_LEFT);');
+ }
+
+ $ip = implode(array_map($convert_func, explode($separator, $ip)));
+ }
+
+ // Split the netmask length off the network address
+ list($netaddr, $masklen) = explode('/', $proxy_ips[$i], 2);
+
+ // Again, an IPv6 address is most likely in a compressed form
+ if ($separator === ':')
+ {
+ $netaddr = str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr);
+ }
+
+ // Convert to a binary form and finally compare
+ $netaddr = implode(array_map($convert_func, explode($separator, $netaddr)));
+ if (strncmp($ip, $netaddr, $masklen) === 0)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+ }
+ }
}
if ( ! $this->valid_ip($this->ip_address))
@@ -518,7 +592,7 @@ class CI_Input {
$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
// CSRF Protection check
- if ($this->_enable_csrf === TRUE)
+ if ($this->_enable_csrf === TRUE && ! $this->is_cli_request())
{
$this->security->csrf_verify();
}
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 0bc6e844a..75e93608a 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -409,8 +409,8 @@ class CI_Loader {
* 1. The name of the "view" file to be included.
* 2. An associative array of data to be extracted for use in the view.
* 3. TRUE/FALSE - whether to return the data or load it. In
- * some cases it's advantageous to be able to return data so that
- * a developer can process it in some way.
+ * some cases it's advantageous to be able to return data so that
+ * a developer can process it in some way.
*
* @param string
* @param array
@@ -633,13 +633,7 @@ class CI_Loader {
{
$this->driver($driver);
}
- return FALSE;
- }
-
- if ( ! class_exists('CI_Driver_Library'))
- {
- // we aren't instantiating an object here, that'll be done by the Library itself
- require BASEPATH.'libraries/Driver.php';
+ return;
}
if ($library === '')
@@ -785,11 +779,11 @@ class CI_Loader {
$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
$_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view;
- foreach ($this->_ci_view_paths as $view_file => $cascade)
+ foreach ($this->_ci_view_paths as $_ci_view_file => $cascade)
{
- if (file_exists($view_file.$_ci_file))
+ if (file_exists($_ci_view_file.$_ci_file))
{
- $_ci_path = $view_file.$_ci_file;
+ $_ci_path = $_ci_view_file.$_ci_file;
$file_exists = TRUE;
break;
}
@@ -837,10 +831,10 @@ class CI_Loader {
* We buffer the output for two reasons:
* 1. Speed. You get a significant speed boost.
* 2. So that the final rendered template can be post-processed by
- * the output class. Why do we need post processing? For one thing,
- * in order to show the elapsed page load time. Unless we can
- * intercept the content right before it's sent to the browser and
- * then stop the timer it won't be accurate.
+ * the output class. Why do we need post processing? For one thing,
+ * in order to show the elapsed page load time. Unless we can
+ * intercept the content right before it's sent to the browser and
+ * then stop the timer it won't be accurate.
*/
ob_start();
@@ -915,6 +909,13 @@ class CI_Loader {
// Get the filename from the path
$class = substr($class, $last_slash);
+
+ // Check for match and driver base class
+ if (strtolower(trim($subdir, '/')) == strtolower($class) && ! class_exists('CI_Driver_Library'))
+ {
+ // We aren't instantiating an object here, just making the base class available
+ require BASEPATH.'libraries/Driver.php';
+ }
}
// We'll test for both lowercase and capitalized versions of the file name
@@ -996,14 +997,19 @@ class CI_Loader {
$this->_ci_loaded_files[] = $filepath;
return $this->_ci_init_class($class, '', $params, $object_name);
}
-
} // END FOREACH
// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
if ($subdir === '')
{
$path = strtolower($class).'/'.$class;
- return $this->_ci_load_class($path, $params);
+ return $this->_ci_load_class($path, $params, $object_name);
+ }
+ else if (ucfirst($subdir) != $subdir)
+ {
+ // Lowercase subdir failed - retry capitalized
+ $path = ucfirst($subdir).$class;
+ return $this->_ci_load_class($path, $params, $object_name);
}
// If we got this far we were unable to find the requested class.
@@ -1193,6 +1199,15 @@ class CI_Loader {
}
}
+ // Autoload drivers
+ if (isset($autoload['drivers']))
+ {
+ foreach ($autoload['drivers'] as $item)
+ {
+ $this->driver($item);
+ }
+ }
+
// Autoload models
if (isset($autoload['model']))
{
diff --git a/system/core/Output.php b/system/core/Output.php
index 5ec8c4bc0..052367ed6 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -552,13 +552,13 @@ class CI_Output {
fclose($fp);
// Strip out the embedded timestamp
- if ( ! preg_match('/(\d+TS--->)/', $cache, $match))
+ if ( ! preg_match('/^(\d+)TS--->/', $cache, $match))
{
return FALSE;
}
$last_modified = filemtime($cache_path);
- $expire = trim(str_replace('TS--->', '', $match[1]));
+ $expire = $match[1];
// Has the file expired?
if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))
@@ -575,7 +575,7 @@ class CI_Output {
}
// Display the cache
- $this->_display(str_replace($match[0], '', $cache));
+ $this->_display(substr($cache, strlen($match[0])));
log_message('debug', 'Cache file is current. Sending it to browser.');
return TRUE;
}
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index 0a7ec501c..1ff02981b 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -49,30 +49,31 @@ class CI_Utf8 {
{
log_message('debug', 'Utf8 Class Initialized');
- global $CFG;
+ $charset = strtoupper(config_item('charset'));
+
+ // set internal encoding for multibyte string functions if necessary
+ // and set a flag so we don't have to repeatedly use extension_loaded()
+ // or function_exists()
+ if (extension_loaded('mbstring'))
+ {
+ define('MB_ENABLED', TRUE);
+ mb_internal_encoding($charset);
+ }
+ else
+ {
+ define('MB_ENABLED', FALSE);
+ }
+
if (
- @preg_match('/./u', 'é') === 1 // PCRE must support UTF-8
- && function_exists('iconv') // iconv must be installed
- && (bool) @ini_get('mbstring.func_overload') !== TRUE // Multibyte string function overloading cannot be enabled
- && $CFG->item('charset') === 'UTF-8' // Application charset must be UTF-8
+ @preg_match('/./u', 'é') === 1 // PCRE must support UTF-8
+ && function_exists('iconv') // iconv must be installed
+ && MB_ENABLED === TRUE // mbstring must be enabled
+ && $charset === 'UTF-8' // Application charset must be UTF-8
)
{
define('UTF8_ENABLED', TRUE);
log_message('debug', 'UTF-8 Support Enabled');
-
- // set internal encoding for multibyte string functions if necessary
- // and set a flag so we don't have to repeatedly use extension_loaded()
- // or function_exists()
- if (extension_loaded('mbstring'))
- {
- define('MB_ENABLED', TRUE);
- mb_internal_encoding('UTF-8');
- }
- else
- {
- define('MB_ENABLED', FALSE);
- }
}
else
{
@@ -135,7 +136,7 @@ class CI_Utf8 {
{
return @iconv($encoding, 'UTF-8', $str);
}
- elseif (function_exists('mb_convert_encoding'))
+ elseif (MB_ENABLED === TRUE)
{
return @mb_convert_encoding($str, 'UTF-8', $encoding);
}