diff options
author | Andrey Andreev <narf@bofh.bg> | 2012-10-05 21:45:41 +0200 |
---|---|---|
committer | Andrey Andreev <narf@bofh.bg> | 2012-10-05 21:45:41 +0200 |
commit | 5b5021812ea6dc859312e00b6b0f078eea54c88d (patch) | |
tree | 0a8840ee0429cc405cb597438a73d03bca970c1a /system/core | |
parent | 49d08053257b55db511eaca08b8ab5d12149f3b6 (diff) | |
parent | dbad54e09a39a77c7404dee9ca1a6b34299469d0 (diff) |
Merge upstream branch
Diffstat (limited to 'system/core')
-rw-r--r--[-rwxr-xr-x] | system/core/Benchmark.php | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/CodeIgniter.php | 29 | ||||
-rw-r--r-- | system/core/Common.php | 140 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Config.php | 58 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Exceptions.php | 4 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Hooks.php | 6 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Input.php | 73 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Lang.php | 18 | ||||
-rw-r--r-- | system/core/Loader.php | 87 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Model.php | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Output.php | 237 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Router.php | 4 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/Security.php | 36 | ||||
-rw-r--r--[-rwxr-xr-x] | system/core/URI.php | 68 | ||||
-rw-r--r-- | system/core/Utf8.php | 2 |
15 files changed, 527 insertions, 237 deletions
diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php index bb630f40b..2fabdf46e 100755..100644 --- a/system/core/Benchmark.php +++ b/system/core/Benchmark.php @@ -79,7 +79,7 @@ class CI_Benchmark { */ public function elapsed_time($point1 = '', $point2 = '', $decimals = 4) { - if ($point1 == '') + if ($point1 === '') { return '{elapsed_time}'; } diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 00db6e13a..8159b19f5 100755..100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -73,9 +73,9 @@ */ set_error_handler('_exception_handler'); - if ( ! is_php('5.3')) + if ( ! is_php('5.4')) { - @set_magic_quotes_runtime(0); // Kill magic quotes + @ini_set('magic_quotes_runtime', 0); // Kill magic quotes } /* @@ -94,24 +94,13 @@ * Note: Since the config file data is cached it doesn't * hurt to load it here. */ - if (isset($assign_to_config['subclass_prefix']) && $assign_to_config['subclass_prefix'] != '') + if ( ! empty($assign_to_config['subclass_prefix'])) { get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix'])); } /* * ------------------------------------------------------ - * Set a liberal script execution time limit - * ------------------------------------------------------ - */ - if (function_exists('set_time_limit') && @ini_get('safe_mode') == 0 - && php_sapi_name() !== 'cli') // Do not override the Time Limit value if running from Command Line - { - @set_time_limit(300); - } - -/* - * ------------------------------------------------------ * Start the timer... tick tock tick tock... * ------------------------------------------------------ */ @@ -193,7 +182,7 @@ * ------------------------------------------------------ */ if ($EXT->call_hook('cache_override') === FALSE - && $OUT->_display_cache($CFG, $URI) == TRUE) + && $OUT->_display_cache($CFG, $URI) === TRUE) { exit; } @@ -393,15 +382,5 @@ */ $EXT->call_hook('post_system'); -/* - * ------------------------------------------------------ - * Close the DB connection if one exists - * ------------------------------------------------------ - */ - if (class_exists('CI_DB') && isset($CI->db) && ! $CI->db->pconnect) - { - $CI->db->close(); - } - /* End of file CodeIgniter.php */ /* Location: ./system/core/CodeIgniter.php */
\ No newline at end of file diff --git a/system/core/Common.php b/system/core/Common.php index 8b897776f..981af4559 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -44,13 +44,13 @@ if ( ! function_exists('is_php')) /** * Determines if the current version of PHP is greater then the supplied value * - * Since there are a few places where we conditionally test for PHP > 5 + * Since there are a few places where we conditionally test for PHP > 5.3 * we'll set a static variable. * * @param string * @return bool TRUE if the current version is $version or higher */ - function is_php($version = '5.0.0') + function is_php($version = '5.3.0') { static $_is_php; $version = (string) $version; @@ -172,7 +172,7 @@ if ( ! function_exists('load_class')) if ($name === FALSE) { // Note: We use exit() rather then show_error() in order to avoid a - // self-referencing loop with the Excptions class + // self-referencing loop with the Exceptions class set_status_header(503); exit('Unable to locate the specified class: '.$class.'.php'); } @@ -200,7 +200,7 @@ if ( ! function_exists('is_loaded')) { static $_is_loaded = array(); - if ($class != '') + if ($class !== '') { $_is_loaded[strtolower($class)] = $class; } @@ -231,21 +231,25 @@ if ( ! function_exists('get_config')) return $_config[0]; } - // Is the config file in the environment folder? - if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) + $file_path = APPPATH.'config/config.php'; + $found = FALSE; + if (file_exists($file_path)) { - $file_path = APPPATH.'config/config.php'; + $found = TRUE; + require($file_path); } - // Fetch the config file - if ( ! file_exists($file_path)) + // Is the config file in the environment folder? + if (defined('ENVIRONMENT') && file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) + { + require($file_path); + } + elseif ( ! $found) { set_status_header(503); exit('The configuration file does not exist.'); } - require($file_path); - // Does the $config array exist in the file? if ( ! isset($config) OR ! is_array($config)) { @@ -300,6 +304,32 @@ if ( ! function_exists('config_item')) // ------------------------------------------------------------------------ +if ( ! function_exists('get_mimes')) +{ + /** + * Returns the MIME types array from config/mimes.php + * + * @return array + */ + function &get_mimes() + { + static $_mimes = array(); + + if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) + { + $_mimes = include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); + } + elseif (is_file(APPPATH.'config/mimes.php')) + { + $_mimes = include(APPPATH.'config/mimes.php'); + } + + return $_mimes; + } +} + +// ------------------------------------------------------------------------ + if ( ! function_exists('show_error')) { /** @@ -366,7 +396,7 @@ if ( ! function_exists('log_message')) { static $_log; - if (config_item('log_threshold') == 0) + if (config_item('log_threshold') === 0) { return; } @@ -401,6 +431,7 @@ if ( ! function_exists('set_status_header')) 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', + 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', @@ -432,19 +463,23 @@ if ( ! function_exists('set_status_header')) 505 => 'HTTP Version Not Supported' ); - if ($code == '' OR ! is_numeric($code)) + if (empty($code) OR ! is_numeric($code)) { show_error('Status codes must be numeric', 500); } - if (isset($stati[$code]) && $text == '') - { - $text = $stati[$code]; - } + is_int($code) OR $code = (int) $code; - if ($text == '') + if (empty($text)) { - show_error('No status text available. Please check your status code number or supply your own message text.', 500); + if (isset($stati[$code])) + { + $text = $stati[$code]; + } + else + { + show_error('No status text available. Please check your status code number or supply your own message text.', 500); + } } $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : FALSE; @@ -453,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); } } } @@ -487,29 +518,19 @@ if ( ! function_exists('_exception_handler')) */ function _exception_handler($severity, $message, $filepath, $line) { - // We don't bother with "strict" notices since they tend to fill up - // the log file with excess information that isn't normally very helpful. - // For example, if you are running PHP 5 and you use version 4 style - // class functions (without prefixes like "public", "private", etc.) - // you'll get notices telling you that these have been deprecated. - if ($severity == E_STRICT) - { - return; - } - $_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. - if (($severity & error_reporting()) == $severity) + 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); @@ -572,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 c07ffa591..8e4f998ef 100755..100644 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -43,7 +43,7 @@ class CI_Config { * * @var array */ - public $config = array(); + public $config = array(); /** * List of all loaded config files @@ -100,15 +100,15 @@ class CI_Config { */ public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) { - $file = ($file == '') ? 'config' : str_replace('.php', '', $file); + $file = ($file === '') ? 'config' : str_replace('.php', '', $file); $found = $loaded = FALSE; + $check_locations = defined('ENVIRONMENT') + ? array(ENVIRONMENT.'/'.$file, $file) + : array($file); + foreach ($this->_config_paths as $path) { - $check_locations = defined('ENVIRONMENT') - ? array(ENVIRONMENT.'/'.$file, $file) - : array($file); - foreach ($check_locations as $location) { $file_path = $path.'config/'.$location.'.php'; @@ -172,7 +172,7 @@ class CI_Config { { return FALSE; } - show_error('The configuration file '.$file.'.php'.' does not exist.'); + show_error('The configuration file '.$file.'.php does not exist.'); } return TRUE; @@ -211,7 +211,7 @@ class CI_Config { { return FALSE; } - elseif (trim($this->config[$item]) == '') + elseif (trim($this->config[$item]) === '') { return ''; } @@ -225,25 +225,39 @@ class CI_Config { * Site URL * Returns base_url . index_page [. uri_string] * - * @param string the URI string + * @param mixed the URI string or an array of segments * @return string */ public function site_url($uri = '') { - if ($uri == '') + if (empty($uri)) { return $this->slash_item('base_url').$this->item('index_page'); } - if ($this->item('enable_query_strings') == FALSE) + $uri = $this->_uri_string($uri); + + if ($this->item('enable_query_strings') === FALSE) { - $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix'); - return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix; + $suffix = ($this->item('url_suffix') === FALSE) ? '' : $this->item('url_suffix'); + + if ($suffix !== '' && ($offset = strpos($uri, '?')) !== FALSE) + { + $uri = substr($uri, 0, $offset).$suffix.substr($uri, $offset); + } + else + { + $uri .= $suffix; + } + + return $this->slash_item('base_url').$this->slash_item('index_page').$uri; } - else + elseif (strpos($uri, '?') === FALSE) { - return $this->slash_item('base_url').$this->item('index_page').'?'.$this->_uri_string($uri); + $uri = '?'.$uri; } + + return $this->slash_item('base_url').$this->item('index_page').$uri; } // ------------------------------------------------------------- @@ -257,7 +271,7 @@ class CI_Config { */ public function base_url($uri = '') { - return $this->slash_item('base_url').ltrim($this->_uri_string($uri),'/'); + return $this->slash_item('base_url').ltrim($this->_uri_string($uri), '/'); } // ------------------------------------------------------------- @@ -270,7 +284,7 @@ class CI_Config { */ protected function _uri_string($uri) { - if ($this->item('enable_query_strings') == FALSE) + if ($this->item('enable_query_strings') === FALSE) { if (is_array($uri)) { @@ -280,15 +294,7 @@ class CI_Config { } elseif (is_array($uri)) { - $i = 0; - $str = ''; - foreach ($uri as $key => $val) - { - $prefix = ($i === 0) ? '' : '&'; - $str .= $prefix.$key.'='.$val; - $i++; - } - return $str; + return http_build_query($uri); } return $uri; diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index 965a717ad..bd9178dbd 100755..100644 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -143,7 +143,7 @@ class CI_Exceptions { ob_end_flush(); } ob_start(); - include(APPPATH.'errors/'.$template.'.php'); + include(VIEWPATH.'errors/'.$template.'.php'); $buffer = ob_get_contents(); ob_end_clean(); return $buffer; @@ -177,7 +177,7 @@ class CI_Exceptions { ob_end_flush(); } ob_start(); - include(APPPATH.'errors/error_php.php'); + include(VIEWPATH.'errors/error_php.php'); $buffer = ob_get_contents(); ob_end_clean(); echo $buffer; diff --git a/system/core/Hooks.php b/system/core/Hooks.php index 5bbb0009a..afbf4b453 100755..100644 --- a/system/core/Hooks.php +++ b/system/core/Hooks.php @@ -39,7 +39,7 @@ class CI_Hooks { /** - * Determines wether hooks are enabled + * Determines whether hooks are enabled * * @var bool */ @@ -53,7 +53,7 @@ class CI_Hooks { public $hooks = array(); /** - * Determines wether hook is in progress, used to prevent infinte loops + * Determines whether hook is in progress, used to prevent infinte loops * * @var bool */ @@ -72,7 +72,7 @@ class CI_Hooks { // If hooks are not enabled in the config file // there is nothing else to do - if ($CFG->item('enable_hooks') == FALSE) + if ($CFG->item('enable_hooks') === FALSE) { return; } diff --git a/system/core/Input.php b/system/core/Input.php index e916ac66d..657fce625 100755..100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -135,7 +135,7 @@ class CI_Input { { if ( ! isset($array[$index])) { - return FALSE; + return NULL; } if ($xss_clean === TRUE) @@ -263,23 +263,27 @@ class CI_Input { } } - if ($prefix == '' && config_item('cookie_prefix') != '') + if ($prefix === '' && config_item('cookie_prefix') !== '') { $prefix = config_item('cookie_prefix'); } + if ($domain == '' && config_item('cookie_domain') != '') { $domain = config_item('cookie_domain'); } - if ($path == '/' && config_item('cookie_path') !== '/') + + if ($path === '/' && config_item('cookie_path') !== '/') { $path = config_item('cookie_path'); } - if ($secure == FALSE && config_item('cookie_secure') != FALSE) + + if ($secure === FALSE && config_item('cookie_secure') !== FALSE) { $secure = config_item('cookie_secure'); } - if ($httponly == FALSE && config_item('cookie_httponly') != FALSE) + + if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE) { $httponly = config_item('cookie_httponly'); } @@ -326,10 +330,37 @@ class CI_Input { if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR')) { + $has_ranges = strpos($proxies, '/') !== FALSE; $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']; + if ($has_ranges) + { + $long_ip = ip2long($_SERVER['REMOTE_ADDR']); + $bit_32 = 1 << 32; + + // Go through each of the IP Addresses to check for and + // test against range notation + foreach ($proxies as $ip) + { + list($address, $mask_length) = explode('/', $ip, 2); + + // Generate the bitmask for a 32 bit IP Address + $bitmask = $bit_32 - (1 << (32 - (int) $mask_length)); + if (($long_ip & $bitmask) === $address) + { + $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; + break; + } + } + + } + else + { + $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')) { @@ -356,7 +387,7 @@ class CI_Input { if (strpos($this->ip_address, ',') !== FALSE) { $x = explode(',', $this->ip_address); - $this->ip_address = trim(end($x)); + $this->ip_address = trim($x[0]); } if ( ! $this->valid_ip($this->ip_address)) @@ -372,14 +403,26 @@ class CI_Input { /** * Validate IP Address * - * Updated version suggested by Geert De Deckere - * * @param string + * @param string 'ipv4' or 'ipv6' * @return bool */ - public function valid_ip($ip) + public function valid_ip($ip, $which = '') { - return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); + switch (strtolower($which)) + { + case 'ipv4': + $which = FILTER_FLAG_IPV4; + break; + case 'ipv6': + $which = FILTER_FLAG_IPV6; + break; + default: + $which = NULL; + break; + } + + return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which); } // -------------------------------------------------------------------- @@ -459,7 +502,7 @@ class CI_Input { } // Is $_GET data allowed? If not we'll set the $_GET to an empty array - if ($this->_allow_get_array == FALSE) + if ($this->_allow_get_array === FALSE) { $_GET = array(); } @@ -502,7 +545,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->security->csrf_verify(); } @@ -559,7 +602,7 @@ class CI_Input { } // Standardize newlines if needed - if ($this->_standardize_newlines == TRUE && strpos($str, "\r") !== FALSE) + if ($this->_standardize_newlines === TRUE && strpos($str, "\r") !== FALSE) { return str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str); } @@ -659,7 +702,7 @@ class CI_Input { if ( ! isset($this->headers[$index])) { - return FALSE; + return NULL; } return ($xss_clean === TRUE) diff --git a/system/core/Lang.php b/system/core/Lang.php index 5cb0cad71..3001f1b13 100755..100644 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -65,37 +65,37 @@ class CI_Lang { /** * Load a language file * - * @param mixed the name of the language file to be loaded. Can be an array + * @param mixed the name of the language file to be loaded * @param string the language (english, etc.) * @param bool return loaded array of translations * @param bool add suffix to $langfile * @param string alternative path to look for language file * @return mixed */ - public function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '') + public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '') { $langfile = str_replace('.php', '', $langfile); - if ($add_suffix == TRUE) + if ($add_suffix === TRUE) { $langfile = str_replace('_lang', '', $langfile).'_lang'; } $langfile .= '.php'; - if ($idiom == '') + if ($idiom === '') { $config =& get_config(); $idiom = ( ! empty($config['language'])) ? $config['language'] : 'english'; } - if ($return == FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom) + if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom) { return; } // Determine where the language file is and load it - if ($alt_path != '' && file_exists($alt_path.'language/'.$idiom.'/'.$langfile)) + if ($alt_path !== '' && file_exists($alt_path.'language/'.$idiom.'/'.$langfile)) { include($alt_path.'language/'.$idiom.'/'.$langfile); } @@ -124,14 +124,14 @@ class CI_Lang { { log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile); - if ($return == TRUE) + if ($return === TRUE) { return array(); } return; } - if ($return == TRUE) + if ($return === TRUE) { return $lang; } @@ -153,7 +153,7 @@ class CI_Lang { */ public function line($line = '') { - $value = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; + $value = ($line === '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; // Because killer robots like unicorns! if ($value === FALSE) diff --git a/system/core/Loader.php b/system/core/Loader.php index 3eb09e6ab..75e93608a 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -208,7 +208,7 @@ class CI_Loader { return; } - if ($library == '' OR isset($this->_base_classes[$library])) + if ($library === '' OR isset($this->_base_classes[$library])) { return FALSE; } @@ -237,14 +237,14 @@ class CI_Loader { { if (is_array($model)) { - foreach ($model as $babe) + foreach ($model as $class) { - $this->model($babe); + $this->model($class); } return; } - if ($model == '') + if ($model === '') { return; } @@ -261,7 +261,7 @@ class CI_Loader { $model = substr($model, $last_slash); } - if ($name == '') + if (empty($name)) { $name = $model; } @@ -329,7 +329,7 @@ class CI_Loader { $CI =& get_instance(); // Do we even need to load the database class? - if (class_exists('CI_DB') && $return == FALSE && $query_builder == NULL && isset($CI->db) && is_object($CI->db)) + if (class_exists('CI_DB') && $return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db)) { return FALSE; } @@ -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 @@ -452,7 +452,7 @@ class CI_Loader { */ public function vars($vars = array(), $val = '') { - if ($val != '' && is_string($vars)) + if ($val !== '' && is_string($vars)) { $vars = array($vars => $val); } @@ -633,16 +633,10 @@ 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 == '') + if ($library === '') { return FALSE; } @@ -668,7 +662,7 @@ class CI_Loader { * @param bool * @return void */ - public function add_package_path($path, $view_cascade=TRUE) + public function add_package_path($path, $view_cascade = TRUE) { $path = rtrim($path, '/').'/'; @@ -714,7 +708,7 @@ class CI_Loader { { $config =& $this->_ci_get_component('config'); - if ($path == '') + if ($path === '') { array_shift($this->_ci_library_paths); array_shift($this->_ci_model_paths); @@ -775,7 +769,7 @@ class CI_Loader { $file_exists = FALSE; // Set the path to the requested file - if ($_ci_path != '') + if (is_string($_ci_path) && $_ci_path !== '') { $_ci_x = explode('/', $_ci_path); $_ci_file = end($_ci_x); @@ -783,13 +777,13 @@ class CI_Loader { else { $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); - $_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view; + $_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; } @@ -820,7 +814,7 @@ class CI_Loader { /* * Extract and cache variables * - * You can either set variables using the dedicated $this->load_vars() + * You can either set variables using the dedicated $this->load->vars() * function or via the second parameter of this function. We'll merge * the two types and cache them so that views that are embedded within * other views can have access to these variables. @@ -837,17 +831,17 @@ 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(); // If the PHP installation does not support short tags we'll // do a little string replacement, changing the short tags // to standard PHP echo statements. - if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE && config_item('rewrite_short_tags') == TRUE) + if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE && config_item('rewrite_short_tags') === TRUE) { echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('<?=', '<?php echo ', file_get_contents($_ci_path)))); } @@ -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,19 +997,24 @@ 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 == '') + 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. // We do not issue errors if the load call failed due to a duplicate request - if ($is_duplicate == FALSE) + if ($is_duplicate === FALSE) { log_message('error', 'Unable to load the requested class: '.$class); show_error('Unable to load the requested class: '.$class); @@ -1067,7 +1073,7 @@ class CI_Loader { } } - if ($prefix == '') + if ($prefix === '') { if (class_exists('CI_'.$class)) { @@ -1091,7 +1097,7 @@ class CI_Loader { if ( ! class_exists($name)) { log_message('error', 'Non-existent class: '.$name); - show_error('Non-existent class: '.$class); + show_error('Non-existent class: '.$name); } // Set the variable name we will assign the class to @@ -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/Model.php b/system/core/Model.php index 9bc9f879f..9bc9f879f 100755..100644 --- a/system/core/Model.php +++ b/system/core/Model.php diff --git a/system/core/Output.php b/system/core/Output.php index c8feb4e67..052367ed6 100755..100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -64,10 +64,17 @@ class CI_Output { * * @var array */ - public $mime_types = array(); + public $mimes = array(); /** - * Determines wether profiler is enabled + * Mime-type for the current page + * + * @var string + */ + protected $mime_type = 'text/html'; + + /** + * Determines whether profiler is enabled * * @var book */ @@ -78,7 +85,7 @@ class CI_Output { * * @var bool */ - protected $_zlib_oc = FALSE; + protected $_zlib_oc = FALSE; /** * List of profiler sections @@ -101,20 +108,11 @@ class CI_Output { */ public function __construct() { - $this->_zlib_oc = @ini_get('zlib.output_compression'); + $this->_zlib_oc = (bool) @ini_get('zlib.output_compression'); // Get mime types for later - if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) - { - include APPPATH.'config/'.ENVIRONMENT.'/mimes.php'; - } - else - { - include APPPATH.'config/mimes.php'; - } + $this->mimes =& get_mimes(); - - $this->mime_types = $mimes; log_message('debug', 'Output Class Initialized'); } @@ -183,7 +181,7 @@ class CI_Output { * how to permit header data to be saved with the cache data... * * @param string - * @param bool + * @param bool * @return void */ public function set_header($header, $replace = TRUE) @@ -192,7 +190,7 @@ class CI_Output { // but it will not modify the content-length header to compensate for // the reduction, causing the browser to hang waiting for more data. // We'll just skip content-length in those cases. - if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0) + if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0) { return; } @@ -209,16 +207,16 @@ class CI_Output { * @param string extension of the file we're outputting * @return void */ - public function set_content_type($mime_type) + public function set_content_type($mime_type, $charset = NULL) { if (strpos($mime_type, '/') === FALSE) { $extension = ltrim($mime_type, '.'); // Is this extension supported? - if (isset($this->mime_types[$extension])) + if (isset($this->mimes[$extension])) { - $mime_type =& $this->mime_types[$extension]; + $mime_type =& $this->mimes[$extension]; if (is_array($mime_type)) { @@ -227,7 +225,15 @@ class CI_Output { } } - $header = 'Content-Type: '.$mime_type; + $this->mime_type = $mime_type; + + if (empty($charset)) + { + $charset = config_item('charset'); + } + + $header = 'Content-Type: '.$mime_type + .(empty($charset) ? NULL : '; charset='.strtolower($charset)); $this->headers[] = array($header, TRUE); return $this; @@ -295,6 +301,12 @@ class CI_Output { */ public function set_profiler_sections($sections) { + if (isset($sections['query_toggle_count'])) + { + $this->_profiler_sections['query_toggle_count'] = (int) $sections['query_toggle_count']; + unset($sections['query_toggle_count']); + } + foreach ($sections as $section => $enable) { $this->_profiler_sections[$section] = ($enable !== FALSE); @@ -330,7 +342,7 @@ class CI_Output { * with any server headers and profile data. It also stops the * benchmark timer so the page rendering speed and memory usage can be shown. * - * @param string + * @param string * @return mixed */ public function _display($output = '') @@ -349,13 +361,22 @@ class CI_Output { // -------------------------------------------------------------------- // Set the output data - if ($output == '') + if ($output === '') { $output =& $this->final_output; } // -------------------------------------------------------------------- + // Is minify requested? + if ($CFG->item('minify_output') === TRUE) + { + $output = $this->minify($output, $this->mime_type); + } + + + // -------------------------------------------------------------------- + // Do we need to write a cache file? Only if the controller does not have its // own _output() method and we are not dealing with a cache file, which we // can determine by the existence of the $CI object above @@ -373,7 +394,7 @@ class CI_Output { if ($this->parse_exec_vars === TRUE) { - $memory = function_exists('memory_get_usage') ? round(memory_get_usage()/1024/1024, 2).'MB' : '0'; + $memory = round(memory_get_usage() / 1024 / 1024, 2).'MB'; $output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output); } @@ -381,7 +402,7 @@ class CI_Output { // -------------------------------------------------------------------- // Is compression requested? - if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE + if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc === FALSE && extension_loaded('zlib') && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { @@ -416,7 +437,7 @@ class CI_Output { // Do we need to generate profile data? // If so, load the Profile class and run it. - if ($this->enable_profiler == TRUE) + if ($this->enable_profiler === TRUE) { $CI->load->library('profiler'); if ( ! empty($this->_profiler_sections)) @@ -453,14 +474,14 @@ class CI_Output { /** * Write a Cache File * - * @param string + * @param string * @return void */ public function _write_cache($output) { $CI =& get_instance(); $path = $CI->config->item('cache_path'); - $cache_path = ($path == '') ? APPPATH.'cache/' : $path; + $cache_path = ($path === '') ? APPPATH.'cache/' : $path; if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) { @@ -496,6 +517,9 @@ class CI_Output { @chmod($cache_path, FILE_WRITE_MODE); log_message('debug', 'Cache file written: '.$cache_path); + + // Send HTTP cache-control headers to browser to match file cache settings. + $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); } // -------------------------------------------------------------------- @@ -503,13 +527,13 @@ class CI_Output { /** * Update/serve a cached file * - * @param object config class - * @param object uri class - * @return void + * @param object config class + * @param object uri class + * @return bool */ public function _display_cache(&$CFG, &$URI) { - $cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path'); + $cache_path = ($CFG->item('cache_path') === '') ? APPPATH.'cache/' : $CFG->item('cache_path'); // Build the file path. The file name is an MD5 hash of the full URI $uri = $CFG->item('base_url').$CFG->item('index_page').$URI->uri_string; @@ -528,25 +552,168 @@ 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; } - // Has the file expired? If so we'll delete it. - if (time() >= trim(str_replace('TS--->', '', $match[1])) && is_really_writable($cache_path)) + $last_modified = filemtime($cache_path); + $expire = $match[1]; + + // Has the file expired? + if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path)) { + // If so we'll delete it. @unlink($filepath); log_message('debug', 'Cache file has expired. File deleted.'); return FALSE; } + else + { + // Or else send the HTTP cache control headers. + $this->set_cache_header($last_modified, $expire); + } // 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; } + // -------------------------------------------------------------------- + + /** + * Set the HTTP headers to match the server-side file cache settings + * in order to reduce bandwidth. + * + * @param int timestamp of when the page was last modified + * @param int timestamp of when should the requested page expire from cache + * @return void + */ + public function set_cache_header($last_modified, $expiration) + { + $max_age = $expiration - $_SERVER['REQUEST_TIME']; + + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $last_modified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) + { + $this->set_status_header(304); + exit; + } + else + { + header('Pragma: public'); + header('Cache-Control: max-age=' . $max_age . ', public'); + header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); + header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); + } + } + + // -------------------------------------------------------------------- + + /** + * Reduce excessive size of HTML content. + * + * @param string + * @param string + * @return string + */ + public function minify($output, $type = 'text/html') + { + switch ($type) + { + case 'text/html': + + $size_before = strlen($output); + + if ($size_before === 0) + { + return ''; + } + + // Find all the <pre>,<code>,<textarea>, and <javascript> tags + // We'll want to return them to this unprocessed state later. + preg_match_all('{<pre.+</pre>}msU', $output, $pres_clean); + preg_match_all('{<code.+</code>}msU', $output, $codes_clean); + preg_match_all('{<textarea.+</textarea>}msU', $output, $textareas_clean); + preg_match_all('{<script.+</script>}msU', $output, $javascript_clean); + + // Minify the CSS in all the <style> tags. + preg_match_all('{<style.+</style>}msU', $output, $style_clean); + foreach ($style_clean[0] as $s) + { + $output = str_replace($s, $this->minify($s, 'text/css'), $output); + } + + // Minify the javascript in <script> tags. + foreach ($javascript_clean[0] as $s) + { + $javascript_mini[] = $this->minify($s, 'text/javascript'); + } + + // Replace multiple spaces with a single space. + $output = preg_replace('!\s{2,}!', ' ', $output); + + // Remove comments (non-MSIE conditionals) + $output = preg_replace('{\s*<!--[^\[].*-->\s*}msU', '', $output); + + // Remove spaces around block-level elements. + $output = preg_replace('/\s*(<\/?(html|head|title|meta|script|link|style|body|h[1-6]|div|p|br)[^>]*>)\s*/is', '$1', $output); + + // Replace mangled <pre> etc. tags with unprocessed ones. + + if ( ! empty($pres_clean)) + { + preg_match_all('{<pre.+</pre>}msU', $output, $pres_messed); + $output = str_replace($pres_messed[0], $pres_clean[0], $output); + } + + if ( ! empty($codes_clean)) + { + preg_match_all('{<code.+</code>}msU', $output, $codes_messed); + $output = str_replace($codes_messed[0], $codes_clean[0], $output); + } + + if ( ! empty($codes_clean)) + { + preg_match_all('{<textarea.+</textarea>}msU', $output, $textareas_messed); + $output = str_replace($textareas_messed[0], $textareas_clean[0], $output); + } + + if (isset($javascript_mini)) + { + preg_match_all('{<script.+</script>}msU', $output, $javascript_messed); + $output = str_replace($javascript_messed[0], $javascript_mini, $output); + } + + $size_removed = $size_before - strlen($output); + $savings_percent = round(($size_removed / $size_before * 100)); + + log_message('debug', 'Minifier shaved '.($size_removed / 1000).'KB ('.$savings_percent.'%) off final HTML output.'); + + break; + + case 'text/css': + + //Remove CSS comments + $output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $output); + + // Remove spaces around curly brackets, colons, + // semi-colons, parenthesis, commas + $output = preg_replace('!\s*(:|;|,|}|{|\(|\))\s*!', '$1', $output); + + break; + + case 'text/javascript': + + // Currently leaves JavaScript untouched. + break; + + default: break; + } + + return $output; + } + } /* End of file Output.php */ diff --git a/system/core/Router.php b/system/core/Router.php index 5ea13797b..5bc053045 100755..100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -435,7 +435,7 @@ class CI_Router { */ public function fetch_method() { - return ($this->method == $this->fetch_class()) ? 'index' : $this->method; + return ($this->method === $this->fetch_class()) ? 'index' : $this->method; } // -------------------------------------------------------------------- @@ -483,7 +483,7 @@ class CI_Router { $this->set_directory($routing['directory']); } - if (isset($routing['controller']) && $routing['controller'] != '') + if ( ! empty($routing['controller'])) { $this->set_class($routing['controller']); } diff --git a/system/core/Security.php b/system/core/Security.php index 81b6602ae..b22d2cf19 100755..100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -162,7 +162,7 @@ class CI_Security { // Do the tokens exist in both the _POST and _COOKIE arrays? if ( ! isset($_POST[$this->_csrf_token_name]) OR ! isset($_COOKIE[$this->_csrf_cookie_name]) - OR $_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match? + OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match? { $this->csrf_show_error(); } @@ -191,6 +191,7 @@ class CI_Security { * Set Cross Site Request Forgery Protection Cookie * * @return object + * @codeCoverageIgnore */ public function csrf_set_cookie() { @@ -394,20 +395,20 @@ class CI_Security { if (preg_match('/<a/i', $str)) { - $str = preg_replace_callback('#<a\s+([^>]*?)(>|$)#si', array($this, '_js_link_removal'), $str); + $str = preg_replace_callback('#<a\s+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); } if (preg_match('/<img/i', $str)) { - $str = preg_replace_callback('#<img\s+([^>]*?)(\s?/?>|$)#si', array($this, '_js_img_removal'), $str); + $str = preg_replace_callback('#<img\s+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str); } - if (preg_match('/(script|xss)/i', $str)) + if (preg_match('/script|xss/i', $str)) { - $str = preg_replace('#<(/*)(script|xss)(.*?)\>#si', '[removed]', $str); + $str = preg_replace('#</*(?:script|xss).*?>#si', '[removed]', $str); } } - while($original != $str); + while ($original !== $str); unset($original); @@ -474,7 +475,7 @@ class CI_Security { */ public function xss_hash() { - if ($this->_xss_hash == '') + if ($this->_xss_hash === '') { mt_srand(); $this->_xss_hash = md5(time() + mt_rand(0, 1999999999)); @@ -560,6 +561,19 @@ class CI_Security { // ---------------------------------------------------------------- /** + * Strip Image Tags + * + * @param string + * @return string + */ + public function strip_image_tags($str) + { + return preg_replace(array('#<img\s+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img\s+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str); + } + + // ---------------------------------------------------------------- + + /** * Compact Exploded Words * * Callback function for xss_clean() to remove whitespace from @@ -669,7 +683,7 @@ class CI_Security { protected function _js_link_removal($match) { return str_replace($match[1], - preg_replace('#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si', + 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])) ), @@ -692,7 +706,7 @@ class CI_Security { protected function _js_img_removal($match) { return str_replace($match[1], - preg_replace('#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si', + 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])) ), @@ -824,14 +838,14 @@ class CI_Security { */ protected function _csrf_set_hash() { - if ($this->_csrf_hash == '') + if ($this->_csrf_hash === '') { // If the cookie exists we will use it's value. // We don't necessarily want to regenerate it with // each page load since a page could contain embedded // sub-pages causing this feature to fail 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]; } diff --git a/system/core/URI.php b/system/core/URI.php index e66cb6dc5..6a8b1a5ac 100755..100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -111,23 +111,23 @@ class CI_URI { // Is there a PATH_INFO variable? // Note: some servers seem to have trouble with getenv() so we'll test it two ways - $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); - if (trim($path, '/') != '' && $path !== '/'.SELF) + $path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); + if (trim($path, '/') !== '' && $path !== '/'.SELF) { $this->_set_uri_string($path); return; } // No PATH_INFO?... What about QUERY_STRING? - $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); - if (trim($path, '/') != '') + $path = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); + if (trim($path, '/') !== '') { $this->_set_uri_string($path); return; } // As a last ditch effort lets try using the $_GET array - if (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') != '') + if (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') !== '') { $this->_set_uri_string(key($_GET)); return; @@ -163,7 +163,7 @@ class CI_URI { * @param string * @return void */ - public function _set_uri_string($str) + protected function _set_uri_string($str) { // Filter out control characters $str = remove_invisible_characters($str, FALSE); @@ -177,8 +177,8 @@ class CI_URI { /** * Detects the URI * - * This function will detect the URI automatically and fix the query string - * if necessary. + * This function will detect the URI automatically + * and fix the query string if necessary. * * @return string */ @@ -189,23 +189,27 @@ class CI_URI { return ''; } - $uri = $_SERVER['REQUEST_URI']; - if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) + if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) { - $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME'])); + $uri = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); } - elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) + elseif (strpos($_SERVER['REQUEST_URI'], dirname($_SERVER['SCRIPT_NAME'])) === 0) { - $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); + $uri = substr($_SERVER['REQUEST_URI'], strlen(dirname($_SERVER['SCRIPT_NAME']))); + } + else + { + $uri = $_SERVER['REQUEST_URI']; } // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct // URI is found, and also fixes the QUERY_STRING server var and $_GET array. - if (strncmp($uri, '?/', 2) === 0) + if (strpos($uri, '?/') === 0) { $uri = substr($uri, 2); } - $parts = preg_split('#\?#i', $uri, 2); + + $parts = explode('?', $uri, 2); $uri = $parts[0]; if (isset($parts[1])) { @@ -218,12 +222,12 @@ class CI_URI { $_GET = array(); } - if ($uri == '/' OR empty($uri)) + if ($uri === '/' OR empty($uri)) { return '/'; } - $uri = parse_url($uri, PHP_URL_PATH); + $uri = parse_url('pseudo://hostname/'.$uri, PHP_URL_PATH); // Do some final cleaning of the URI and return it return str_replace(array('//', '../'), '/', trim($uri, '/')); @@ -270,11 +274,11 @@ class CI_URI { */ public function _filter_uri($str) { - if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE) + if ($str !== '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') === FALSE) { // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern - if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str)) + if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', urldecode($str))) { show_error('The URI you submitted has disallowed characters.', 400); } @@ -298,9 +302,11 @@ class CI_URI { */ public function _remove_url_suffix() { - if ($this->config->item('url_suffix') != '') + $suffix = (string) $this->config->item('url_suffix'); + + if ($suffix !== '' && ($offset = strrpos($this->uri_string, $suffix)) !== FALSE) { - $this->uri_string = preg_replace('|'.preg_quote($this->config->item('url_suffix')).'$|', '', $this->uri_string); + $this->uri_string = substr_replace($this->uri_string, '', $offset, strlen($suffix)); } } @@ -321,7 +327,7 @@ class CI_URI { // Filter segments for security $val = trim($this->_filter_uri($val)); - if ($val != '') + if ($val !== '') { $this->segments[] = $val; } @@ -358,10 +364,10 @@ class CI_URI { * This function returns the URI segment based on the number provided. * * @param int - * @param bool + * @param mixed * @return string */ - public function segment($n, $no_result = FALSE) + public function segment($n, $no_result = NULL) { return isset($this->segments[$n]) ? $this->segments[$n] : $no_result; } @@ -376,10 +382,10 @@ class CI_URI { * same result as $this->segment() * * @param int - * @param bool + * @param mixed * @return string */ - public function rsegment($n, $no_result = FALSE) + public function rsegment($n, $no_result = NULL) { return isset($this->rsegments[$n]) ? $this->rsegments[$n] : $no_result; } @@ -462,7 +468,7 @@ class CI_URI { { return (count($default) === 0) ? array() - : array_fill_keys($default, FALSE); + : array_fill_keys($default, NULL); } $segments = array_slice($this->$segment_array(), ($n - 1)); @@ -477,7 +483,7 @@ class CI_URI { } else { - $retval[$seg] = FALSE; + $retval[$seg] = NULL; $lastval = $seg; } @@ -490,7 +496,7 @@ class CI_URI { { if ( ! array_key_exists($val, $retval)) { - $retval[$val] = FALSE; + $retval[$val] = NULL; } } } @@ -511,7 +517,7 @@ class CI_URI { public function assoc_to_uri($array) { $temp = array(); - foreach ( (array) $array as $key => $val) + foreach ((array) $array as $key => $val) { $temp[] = $key; $temp[] = $val; @@ -644,7 +650,7 @@ class CI_URI { */ public function ruri_string() { - return '/'.implode('/', $this->rsegment_array()); + return implode('/', $this->rsegment_array()); } } diff --git a/system/core/Utf8.php b/system/core/Utf8.php index a6faa84ec..0a7ec501c 100644 --- a/system/core/Utf8.php +++ b/system/core/Utf8.php @@ -54,7 +54,7 @@ class CI_Utf8 { if ( @preg_match('/./u', 'é') === 1 // PCRE must support UTF-8 && function_exists('iconv') // iconv must be installed - && @ini_get('mbstring.func_overload') != 1 // Multibyte string function overloading cannot be enabled + && (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 ) { |