diff options
author | Andrey Andreev <narf@bofh.bg> | 2012-10-12 10:56:34 +0200 |
---|---|---|
committer | Andrey Andreev <narf@bofh.bg> | 2012-10-12 10:56:34 +0200 |
commit | bffe3fb935c8a28e1ccacf56f678a491edcff043 (patch) | |
tree | 5a39ba6907623d5ad46b7d13ef17e360df1dfe5e /system/core | |
parent | 55b82c95be57a6727d45d6ae9652ff612f96bc37 (diff) | |
parent | 9ae82faaad2f6b07a050d79129652b74483d1da0 (diff) |
Merge changes from develop
Diffstat (limited to 'system/core')
-rw-r--r-- | system/core/CodeIgniter.php | 2 | ||||
-rw-r--r-- | system/core/Common.php | 62 | ||||
-rw-r--r-- | system/core/Config.php | 2 | ||||
-rw-r--r-- | system/core/Input.php | 132 | ||||
-rw-r--r-- | system/core/Loader.php | 51 | ||||
-rw-r--r-- | system/core/Output.php | 6 | ||||
-rw-r--r-- | system/core/Utf8.php | 39 |
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); } |