diff options
Diffstat (limited to 'system')
45 files changed, 668 insertions, 522 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 3fe5c0648..c12116236 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -73,11 +73,10 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ------------------------------------------------------ */ set_error_handler('_exception_handler'); + register_shutdown_function('_shutdown_handler'); - if ( ! is_php('5.4')) - { - @ini_set('magic_quotes_runtime', 0); // Kill magic quotes - } + // Kill magic quotes + is_php('5.4') OR @ini_set('magic_quotes_runtime', 0); /* * ------------------------------------------------------ @@ -88,7 +87,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * The subclass prefix allows CI to know if a core class is * being extended via a library in the local application * "libraries" folder. Since CI allows config items to be - * overriden via data set in the main index. php file, + * overriden via data set in the main index.php file, * before proceeding we need to know if a subclass_prefix * override exists. If so, we will set this value now, * before any classes are loaded @@ -165,7 +164,6 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ------------------------------------------------------ */ $RTR =& load_class('Router', 'core'); - $RTR->_set_routing(); // Set any routing overrides that may exist in the main index file if (isset($routing)) @@ -241,12 +239,13 @@ defined('BASEPATH') OR exit('No direct script access allowed'); // Load the local application controller // Note: The Router class automatically validates the controller path using the router->_validate_request(). // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid. - if ( ! file_exists(APPPATH.'controllers/'.$RTR->directory.$RTR->class.'.php')) + $class = ucfirst($RTR->class); + if ( ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php')) { show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'); } - include(APPPATH.'controllers/'.$RTR->directory.$RTR->class.'.php'); + include(APPPATH.'controllers/'.$RTR->directory.$class.'.php'); // Set a mark point for benchmarking $BM->mark('loading_time:_base_classes_end'); @@ -258,9 +257,8 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * None of the methods in the app controller or the * loader class can be called via the URI, nor can - * controller functions that begin with an underscore. + * controller methods that begin with an underscore. */ - $class = $RTR->class; $method = $RTR->method; if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method)) @@ -272,6 +270,8 @@ defined('BASEPATH') OR exit('No direct script access allowed'); $method = 'index'; } + $class = ucfirst($class); + if ( ! class_exists($class, FALSE)) { if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) @@ -310,6 +310,8 @@ defined('BASEPATH') OR exit('No direct script access allowed'); $method = 'index'; } + $class = ucfirst($class); + if ( ! class_exists($class, FALSE)) { if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) diff --git a/system/core/Common.php b/system/core/Common.php index d88b0867b..56008efe8 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -82,7 +82,7 @@ if ( ! function_exists('is_really_writable')) function is_really_writable($file) { // If we're on a Unix server with safe_mode off we call is_writable - if (DIRECTORY_SEPARATOR === '/' && (bool) @ini_get('safe_mode') === FALSE) + if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR (bool) @ini_get('safe_mode') === FALSE)) { return is_writable($file); } @@ -224,56 +224,51 @@ if ( ! function_exists('get_config')) * @param array * @return array */ - function &get_config($replace = array()) + function &get_config(Array $replace = array()) { static $_config; - if (isset($_config)) + if (empty($_config)) { - return $_config[0]; - } + $file_path = APPPATH.'config/config.php'; + $found = FALSE; + if (file_exists($file_path)) + { + $found = TRUE; + require($file_path); + } - $file_path = APPPATH.'config/config.php'; - $found = FALSE; - if (file_exists($file_path)) - { - $found = TRUE; - require($file_path); - } + // Is the config file in the environment folder? + if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) + { + require($file_path); + } + elseif ( ! $found) + { + set_status_header(503); + echo 'The configuration file does not exist.'; + exit(EXIT_CONFIG); + } - // Is the config file in the environment folder? - if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) - { - require($file_path); - } - elseif ( ! $found) - { - set_status_header(503); - echo 'The configuration file does not exist.'; - exit(EXIT_CONFIG); - } + // Does the $config array exist in the file? + if ( ! isset($config) OR ! is_array($config)) + { + set_status_header(503); + echo 'Your config file does not appear to be formatted correctly.'; + exit(EXIT_CONFIG); + } - // Does the $config array exist in the file? - if ( ! isset($config) OR ! is_array($config)) - { - set_status_header(503); - echo 'Your config file does not appear to be formatted correctly.'; - exit(EXIT_CONFIG); + // references cannot be directly assigned to static variables, so we use an array + $_config[0] =& $config; } - // Are any values being dynamically replaced? - if (count($replace) > 0) + // Are any values being dynamically added or replaced? + foreach ($replace as $key => $val) { - foreach ($replace as $key => $val) - { - if (isset($config[$key])) - { - $config[$key] = $val; - } - } + $_config[0][$key] = $val; } - return $_config[0] =& $config; + return $_config[0]; } } @@ -289,20 +284,15 @@ if ( ! function_exists('config_item')) */ function config_item($item) { - static $_config_item = array(); + static $_config; - if ( ! isset($_config_item[$item])) + if (empty($_config)) { - $config =& get_config(); - - if ( ! isset($config[$item])) - { - return FALSE; - } - $_config_item[$item] = $config[$item]; + // references cannot be directly assigned to static variables, so we use an array + $_config[0] =& get_config(); } - return $_config_item[$item]; + return isset($_config[0][$item]) ? $_config[0][$item] : FALSE; } } @@ -439,29 +429,19 @@ if ( ! function_exists('log_message')) * * @param string the error level: 'error', 'debug' or 'info' * @param string the error message - * @param bool whether the error is a native PHP error * @return void */ - function log_message($level, $message, $php_error = FALSE) + function log_message($level, $message) { - static $_log, $_log_threshold; - - if ($_log_threshold === NULL) - { - $_log_threshold = config_item('log_threshold'); - } - - if ($_log_threshold === 0) - { - return; - } + static $_log; if ($_log === NULL) { - $_log =& load_class('Log', 'core'); + // references cannot be directly assigned to static variables, so we use an array + $_log[0] =& load_class('Log', 'core'); } - $_log->write_log($level, $message, $php_error); + $_log[0]->write_log($level, $message); } } @@ -543,7 +523,7 @@ if ( ! function_exists('set_status_header')) $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : FALSE; - if (strpos(php_sapi_name(), 'cgi') === 0) + if (strpos(PHP_SAPI, 'cgi') === 0) { header('Status: '.$code.' '.$text, TRUE); } @@ -561,23 +541,23 @@ if ( ! function_exists('_exception_handler')) /** * Exception Handler * - * This is the custom exception handler that is declaired at the top - * of Codeigniter.php. The main reason we use this is to permit + * This is the custom exception handler that is declared at the top + * of CodeIgniter.php. The main reason we use this is to permit * PHP errors to be logged in our own log files since the user may * not have access to server logs. Since this function * effectively intercepts PHP errors, however, we also need * to display errors based on the current error_reporting level. * We do that with the use of a PHP error template. * - * @param int - * @param string - * @param string - * @param int + * @param int $severity + * @param string $message + * @param string $filepath + * @param int $line * @return void */ function _exception_handler($severity, $message, $filepath, $line) { - $is_error = ((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity; + $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); // When an error occurred, set the status header to '500 Internal Server Error' // to indicate to the client something went wrong. @@ -617,6 +597,34 @@ if ( ! function_exists('_exception_handler')) } } +// ------------------------------------------------------------------------ + +if ( ! function_exists('_shutdown_handler')) +{ + /** + * Shutdown Handler + * + * This is the shutdown handler that is declared at the top + * of CodeIgniter.php. The main reason we use this is to simulate + * a complete custom exception handler. + * + * E_STRICT is purposivly neglected because such events may have + * been caught. Duplication or none? None is preferred for now. + * + * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a + * @return void + */ + function _shutdown_handler() + { + $last_error = function_exists('error_get_last') ? error_get_last() : NULL; + if (isset($last_error) && + ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) + { + _exception_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); + } + } +} + // -------------------------------------------------------------------- if ( ! function_exists('remove_invisible_characters')) diff --git a/system/core/Config.php b/system/core/Config.php index 7e64444bc..109ee6424 100644 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -184,16 +184,16 @@ class CI_Config { * * @param string $item Config item name * @param string $index Index name - * @return string|bool The configuration item or FALSE on failure + * @return string|null The configuration item or NULL if the item doesn't exist */ public function item($item, $index = '') { if ($index == '') { - return isset($this->config[$item]) ? $this->config[$item] : FALSE; + return isset($this->config[$item]) ? $this->config[$item] : NULL; } - return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : FALSE; + return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : NULL; } // -------------------------------------------------------------------- @@ -202,13 +202,13 @@ class CI_Config { * Fetch a config file item with slash appended (if not empty) * * @param string $item Config item name - * @return string|bool The configuration item or FALSE on failure + * @return string|null The configuration item or NULL if the item doesn't exist */ public function slash_item($item) { if ( ! isset($this->config[$item])) { - return FALSE; + return NULL; } elseif (trim($this->config[$item]) === '') { diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index 9c68d06a5..d7e5ed4d9 100644 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -91,7 +91,7 @@ class CI_Exceptions { public function log_exception($severity, $message, $filepath, $line) { $severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity; - log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE); + log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line); } // -------------------------------------------------------------------- diff --git a/system/core/Input.php b/system/core/Input.php index 0ef81128e..8c32e459e 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -47,7 +47,7 @@ class CI_Input { public $ip_address = FALSE; /** - * User agent strin + * User agent string * * @var string */ @@ -261,7 +261,7 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function get_post($index = '', $xss_clean = FALSE) + public function post_get($index = '', $xss_clean = FALSE) { return isset($_POST[$index]) ? $this->post($index, $xss_clean) @@ -271,6 +271,22 @@ class CI_Input { // -------------------------------------------------------------------- /** + * Fetch an item from GET data with fallback to POST + * + * @param string $index Index for item to be fetched from $_GET or $_POST + * @param bool $xss_clean Whether to apply XSS filtering + * @return mixed + */ + public function get_post($index = '', $xss_clean = FALSE) + { + return isset($_GET[$index]) + ? $this->get($index, $xss_clean) + : $this->post($index, $xss_clean); + } + + // -------------------------------------------------------------------- + + /** * Fetch an item from the COOKIE array * * @param string $index Index for item to be fetched from $_COOKIE @@ -677,7 +693,14 @@ class CI_Input { foreach ($_COOKIE as $key => $val) { - $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE) + { + $_COOKIE[$cookie_key] = $this->_clean_input_data($val); + } + else + { + unset($_COOKIE[$key]); + } } } @@ -690,7 +713,7 @@ class CI_Input { $this->security->csrf_verify(); } - log_message('debug', 'Global POST and COOKIE data sanitized'); + log_message('debug', 'Global POST, GET and COOKIE data sanitized'); } // -------------------------------------------------------------------- @@ -760,15 +783,25 @@ class CI_Input { * only named with alpha-numeric text and a few other items. * * @param string $str Input string - * @return string + * @param string $fatal Whether to terminate script exection + * or to return FALSE if an invalid + * key is encountered + * @return string|bool */ - protected function _clean_input_keys($str) + protected function _clean_input_keys($str, $fatal = TRUE) { if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str)) { - set_status_header(503); - echo 'Disallowed Key Characters.'; - exit(EXIT_USER_INPUT); + if ($fatal === TRUE) + { + return FALSE; + } + else + { + set_status_header(503); + echo 'Disallowed Key Characters.'; + exit(EXIT_USER_INPUT); + } } // Clean UTF-8 if supported @@ -872,7 +905,7 @@ class CI_Input { */ public function is_cli_request() { - return (php_sapi_name() === 'cli' OR defined('STDIN')); + return (PHP_SAPI === 'cli' OR defined('STDIN')); } // -------------------------------------------------------------------- diff --git a/system/core/Loader.php b/system/core/Loader.php index 70a6b6fa6..70c1e4154 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -76,13 +76,6 @@ class CI_Loader { protected $_ci_helper_paths = array(APPPATH, BASEPATH); /** - * List of loaded base classes - * - * @var array - */ - protected $_base_classes = array(); // Set by the controller class - - /** * List of cached variables * * @var array @@ -120,6 +113,8 @@ class CI_Loader { 'user_agent' => 'agent' ); + // -------------------------------------------------------------------- + /** * Class constructor * @@ -129,7 +124,8 @@ class CI_Loader { */ public function __construct() { - $this->_ci_ob_level = ob_get_level(); + $this->_ci_ob_level = ob_get_level(); + $this->_ci_classes =& is_loaded(); log_message('debug', 'Loader Class Initialized'); } @@ -147,7 +143,6 @@ class CI_Loader { */ public function initialize() { - $this->_base_classes =& is_loaded(); $this->_ci_autoloader(); } @@ -165,7 +160,7 @@ class CI_Loader { */ public function is_loaded($class) { - return isset($this->_ci_classes[$class]) ? $this->_ci_classes[$class] : FALSE; + return array_search(ucfirst($class), $this->_ci_classes, TRUE); } // -------------------------------------------------------------------- @@ -183,7 +178,11 @@ class CI_Loader { */ public function library($library = '', $params = NULL, $object_name = NULL) { - if (is_array($library)) + if (empty($library)) + { + return; + } + elseif (is_array($library)) { foreach ($library as $class) { @@ -193,11 +192,6 @@ class CI_Loader { return; } - if ($library === '' OR isset($this->_base_classes[$library])) - { - return; - } - if ($params !== NULL && ! is_array($params)) { $params = NULL; @@ -228,7 +222,7 @@ class CI_Loader { { foreach ($model as $key => $value) { - $this->model(is_int($key) ? $value : $key, $value); + is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); } return; } @@ -261,33 +255,32 @@ class CI_Loader { show_error('The model name you are loading is the name of a resource that is already being used: '.$name); } - $model = strtolower($model); - - foreach ($this->_ci_model_paths as $mod_path) + if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) { - if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) + if ($db_conn === TRUE) { - continue; + $db_conn = ''; } - if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) - { - if ($db_conn === TRUE) - { - $db_conn = ''; - } + $CI->load->database($db_conn, FALSE, TRUE); + } - $CI->load->database($db_conn, FALSE, TRUE); - } + if ( ! class_exists('CI_Model', FALSE)) + { + load_class('Model', 'core'); + } - if ( ! class_exists('CI_Model', FALSE)) + $model = ucfirst(strtolower($model)); + + foreach ($this->_ci_model_paths as $mod_path) + { + if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) { - load_class('Model', 'core'); + continue; } require_once($mod_path.'models/'.$path.$model.'.php'); - $model = ucfirst($model); $CI->$name = new $model(); $this->_ci_models[] = $name; return; @@ -422,7 +415,7 @@ class CI_Loader { * to be extracted for use in the view * @param bool $return Whether to return the view output * or leave it to the Output class - * @return void + * @return void|string */ public function view($view, $vars = array(), $return = FALSE) { @@ -478,6 +471,20 @@ class CI_Loader { // -------------------------------------------------------------------- /** + * Clear Cached Variables + * + * Clears the cached variables. + * + * @return void + */ + public function clear_vars() + { + $this->_ci_cached_vars = array(); + } + + // -------------------------------------------------------------------- + + /** * Get Variable * * Check if a variable is set and retrieve it. @@ -1118,30 +1125,35 @@ class CI_Loader { // Set the variable name we will assign the class to // Was a custom class name supplied? If so we'll use it - $class = strtolower($class); - - if ($object_name === NULL) + if (empty($object_name)) { - $classvar = isset($this->_ci_varmap[$class]) ? $this->_ci_varmap[$class] : $class; + $object_name = strtolower($class); + if (isset($this->_ci_varmap[$object_name])) + { + $object_name = $this->_ci_varmap[$object_name]; + } } - else + + // Don't overwrite existing properties + $CI =& get_instance(); + if (isset($CI->$object_name)) { - $classvar = $object_name; + if ($CI->$object_name instanceof $name) + { + log_message('debug', $class." has already been instantiated as '".$object_name."'. Second attempt aborted."); + return; + } + + show_error("Resource '".$object_name."' already exists and is not a ".$class." instance."); } // Save the class name and object name - $this->_ci_classes[$class] = $classvar; + $this->_ci_classes[$object_name] = $class; // Instantiate the class - $CI =& get_instance(); - if ($config !== NULL) - { - $CI->$classvar = new $name($config); - } - else - { - $CI->$classvar = new $name(); - } + $CI->$object_name = isset($config) + ? new $name($config) + : new $name(); } // -------------------------------------------------------------------- @@ -1198,6 +1210,15 @@ class CI_Loader { } } + // Autoload drivers + if (isset($autoload['drivers'])) + { + foreach ($autoload['drivers'] as $item) + { + $this->driver($item); + } + } + // Load libraries if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) { @@ -1215,15 +1236,6 @@ 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/Log.php b/system/core/Log.php index e4d72b544..b2327b8f0 100644 --- a/system/core/Log.php +++ b/system/core/Log.php @@ -140,10 +140,9 @@ class CI_Log { * * @param string the error level: 'error', 'debug' or 'info' * @param string the error message - * @param bool whether the error is a native PHP error * @return bool */ - public function write_log($level, $msg, $php_error = FALSE) + public function write_log($level, $msg) { if ($this->_enabled === FALSE) { diff --git a/system/core/Output.php b/system/core/Output.php index 06d7a866b..04209d920 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -841,13 +841,42 @@ class CI_Output { $output = substr_replace($output, '', 0, $pos); // Remove closing tag and save it for later - $pos = strpos($output, '</'); - $closing_tag = substr($output, $pos, strlen($output)); + $pos = strrpos($output, '</'); + $closing_tag = substr($output, $pos); $output = substr_replace($output, '', $pos); } // Remove CSS comments - $output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!i', '', $output); + $output = preg_replace('@/\*([^/][^*]*\*)*/(?!.+?["\'])@i', '', $output); + + // Remove Javascript inline comments + if ($has_tags === TRUE && strpos(strtolower($open_tag), 'script') !== FALSE) + { + $lines = preg_split('/\r?\n|\n?\r/', $output); + foreach ($lines as &$line) + { + $in_string = $in_dstring = FALSE; + for ($i = 0, $len = strlen($line); $i < $len; $i++) + { + if ( ! $in_string && ! $in_dstring && substr($line, $i, 2) === '//') + { + $line = substr($line, 0, $i); + break; + } + + if ($line[$i] === "'" && ! $in_dstring) + { + $in_string = ! $in_string; + } + elseif ($line[$i] === '"' && ! $in_string) + { + $in_dstring = ! $in_dstring; + } + } + } + + $output = implode("\n", $lines); + } // Remove spaces around curly brackets, colons, // semi-colons, parenthesis, commas @@ -899,11 +928,11 @@ class CI_Output { } } - if ($value === "'") + if ($value === "'" && ! $in_dstring) { $in_string = ! $in_string; } - elseif ($value === '"') + elseif ($value === '"' && ! $in_string) { $in_dstring = ! $in_dstring; } diff --git a/system/core/Router.php b/system/core/Router.php index c86ab9c20..0f7278ae6 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -82,6 +82,18 @@ class CI_Router { public $default_controller; /** + * Translate URI dashes + * + * Determines whether dashes in controller & method segments + * should be automatically replaced by underscores. + * + * @var bool + */ + public $translate_uri_dashes = FALSE; + + // -------------------------------------------------------------------- + + /** * Class constructor * * Runs the route mapping function. @@ -92,6 +104,7 @@ class CI_Router { { $this->config =& load_class('Config', 'core'); $this->uri =& load_class('URI', 'core'); + $this->_set_routing(); log_message('debug', 'Router Class Initialized'); } @@ -105,7 +118,7 @@ class CI_Router { * * @return void */ - public function _set_routing() + protected function _set_routing() { // Are query strings enabled in the config file? Normally CI doesn't utilize query strings // since URI segments are more search-engine friendly, but they can optionally be used. @@ -143,12 +156,14 @@ class CI_Router { include(APPPATH.'config/'.ENVIRONMENT.'/routes.php'); } - $this->routes = (empty($route) OR ! is_array($route)) ? array() : $route; - unset($route); - - // Set the default controller so we can display it in the event - // the URI doesn't correlated to a valid controller. - $this->default_controller = empty($this->routes['default_controller']) ? FALSE : $this->routes['default_controller']; + // Validate & get reserved routes + if (isset($route) && is_array($route)) + { + isset($route['default_controller']) && $this->default_controller = $route['default_controller']; + isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes']; + unset($route['default_controller'], $route['translate_uri_dashes']); + $this->routes = $route; + } // Were there any query string segments? If so, we'll validate them and bail out since we're done. if (count($segments) > 0) @@ -191,8 +206,6 @@ class CI_Router { $method = 'index'; } - $this->set_class($class); - $this->set_method($method); $this->_set_request(array($class, $method)); // re-index the routed segments array so it starts with 1 rather than 0 @@ -221,8 +234,16 @@ class CI_Router { return $this->_set_default_controller(); } - $this->set_class($segments[0]); + if ($this->translate_uri_dashes === TRUE) + { + $segments[0] = str_replace('-', '_', $segments[0]); + if (isset($segments[1])) + { + $segments[1] = str_replace('-', '_', $segments[1]); + } + } + $this->set_class($segments[0]); isset($segments[1]) OR $segments[1] = 'index'; $this->set_method($segments[1]); @@ -249,13 +270,11 @@ class CI_Router { return $segments; } - $temp = str_replace('-', '_', $segments[0]); + $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); // Does the requested controller exist in the root folder? - if (file_exists(APPPATH.'controllers/'.$temp.'.php')) + if (file_exists(APPPATH.'controllers/'.$test.'.php')) { - $segments[0] = $temp; - empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]); return $segments; } @@ -266,11 +285,10 @@ class CI_Router { $this->set_directory(array_shift($segments)); if (count($segments) > 0) { - $segments[0] = str_replace('-', '_', $segments[0]); - empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]); + $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); - // Does the requested controller exist in the sub-folder? - if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$segments[0].'.php')) + // Does the requested controller exist in the sub-directory? + if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$test.'.php')) { if ( ! empty($this->routes['404_override'])) { @@ -287,7 +305,7 @@ class CI_Router { { // Is the method being specified in the route? $segments = explode('/', $this->default_controller); - if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$segments[0].'.php')) + if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($segments[0]).'.php')) { $this->directory = ''; } @@ -333,10 +351,10 @@ class CI_Router { return $this->_set_request(explode('/', $this->routes[$uri])); } - // Loop through the route array looking for wild-cards + // Loop through the route array looking for wildcards foreach ($this->routes as $key => $val) { - // Convert wild-cards to RegEx + // Convert wildcards to RegEx $key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key); // Does the RegEx match? diff --git a/system/core/Security.php b/system/core/Security.php index 196d61144..9423f825c 100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -38,6 +38,30 @@ defined('BASEPATH') OR exit('No direct script access allowed'); class CI_Security { /** + * List of sanitize filename strings + * + * @var array + */ + public $filename_bad_chars = array( + '../', '<!--', '-->', '<', '>', + "'", '"', '&', '$', '#', + '{', '}', '[', ']', '=', + ';', '?', '%20', '%22', + '%3c', // < + '%253c', // < + '%3e', // > + '%0e', // > + '%28', // ( + '%29', // ) + '%2528', // ( + '%26', // & + '%24', // $ + '%3f', // ? + '%3b', // ; + '%3d' // = + ); + + /** * XSS Hash * * Random Hash for protecting URLs. @@ -529,9 +553,9 @@ class CI_Security { { $matches = $matches1 = 0; + $str = preg_replace('~(�*[0-9a-f]{2,5});?~iS', '$1;', $str, -1, $matches); + $str = preg_replace('~(&#\d{2,4});?~S', '$1;', $str, -1, $matches1); $str = html_entity_decode($str, ENT_COMPAT, $charset); - $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str, -1, $matches); - $str = preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str, -1, $matches1); } while ($matches OR $matches1); @@ -549,24 +573,7 @@ class CI_Security { */ public function sanitize_filename($str, $relative_path = FALSE) { - $bad = array( - '../', '<!--', '-->', '<', '>', - "'", '"', '&', '$', '#', - '{', '}', '[', ']', '=', - ';', '?', '%20', '%22', - '%3c', // < - '%253c', // < - '%3e', // > - '%0e', // > - '%28', // ( - '%29', // ) - '%2528', // ( - '%26', // & - '%24', // $ - '%3f', // ? - '%3b', // ; - '%3d' // = - ); + $bad = $this->filename_bad_chars; if ( ! $relative_path) { @@ -596,7 +603,7 @@ class CI_Security { */ public function strip_image_tags($str) { - return preg_replace(array('#<img\s+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img\s+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str); + return preg_replace(array('#<img[\s/]+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img[\s/]+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str); } // ---------------------------------------------------------------- @@ -877,7 +884,7 @@ class CI_Security { { if ($this->_csrf_hash === '') { - // If the cookie exists we will use it's value. + // If the cookie exists we will use its 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 @@ -887,7 +894,7 @@ class CI_Security { return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name]; } - $this->_csrf_hash = md5(uniqid(rand(), TRUE)); + $this->_csrf_hash = md5(uniqid(mt_rand(), TRUE)); $this->csrf_set_cookie(); } diff --git a/system/database/DB.php b/system/database/DB.php index 83d973304..8742800c8 100644 --- a/system/database/DB.php +++ b/system/database/DB.php @@ -76,9 +76,13 @@ function &DB($params = '', $query_builder_override = NULL) $active_group = $params; } - if ( ! isset($active_group) OR ! isset($db[$active_group])) + if ( ! isset($active_group)) { - show_error('You have specified an invalid database connection group.'); + show_error('You have not specified a database connection group via $active_group in your config/database.php file.'); + } + elseif ( ! isset($db[$active_group])) + { + show_error('You have specified an invalid database connection group ('.$active_group.') in your config/database.php file.'); } $params = $db[$active_group]; diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 593d78ba4..9aa6c5de5 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -561,7 +561,6 @@ abstract class CI_DB_driver { if ($sql === '') { log_message('error', 'Invalid query: '.$sql); - return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; } elseif ( ! is_bool($return_object)) @@ -625,7 +624,14 @@ abstract class CI_DB_driver { // if transactions are enabled. If we don't call this here // the error message will trigger an exit, causing the // transactions to remain in limbo. - $this->_trans_depth > 0 && $this->trans_complete(); + if ($this->_trans_depth !== 0) + { + do + { + $this->trans_complete(); + } + while ($this->_trans_depth !== 0); + } // Display errors return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql)); @@ -1136,7 +1142,7 @@ abstract class CI_DB_driver { else { /* We have no other choice but to just get the first element's key. - * Due to array_shift() accepting it's argument by reference, if + * Due to array_shift() accepting its argument by reference, if * E_STRICT is on, this would trigger a warning. So we'll have to * assign it first. */ @@ -1376,7 +1382,9 @@ abstract class CI_DB_driver { $fields[$this->protect_identifiers($key)] = $this->escape($val); } - return $this->_update($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields); + $sql = $this->_update($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields); + $this->_reset_write(); + return $sql; } // -------------------------------------------------------------------- diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index 292621b66..a36501eb6 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -385,7 +385,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $alias = $this->_create_alias_from_table(trim($select)); } - $sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->escape_identifiers(trim($alias)); + $sql = $type.'('.$this->protect_identifiers(trim($select)).') AS '.$this->escape_identifiers(trim($alias)); $this->qb_select[] = $sql; $this->qb_no_escape[] = NULL; @@ -1138,7 +1138,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * ORDER BY * * @param string $orderby - * @param string $direction ASC or DESC + * @param string $direction ASC, DESC or RANDOM * @param bool $escape * @return CI_DB_query_builder */ @@ -1152,7 +1152,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // Do we have a seed value? $orderby = ctype_digit((string) $orderby) - ? $orderby = sprintf($this->_random_keyword[1], $orderby) + ? sprintf($this->_random_keyword[1], $orderby) : $this->_random_keyword[0]; } elseif (empty($orderby)) @@ -1846,6 +1846,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, 100), $this->protect_identifiers($index))); $affected_rows += $this->affected_rows(); + $this->qb_where = array(); } $this->_reset_write(); diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index ef2cb8a8d..0f3c6fc62 100644 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -241,9 +241,10 @@ class CI_DB_mysqli_driver extends CI_DB { // even if the queries produce a successful result. $this->_trans_failure = ($test_mode === TRUE); - $this->simple_query('SET AUTOCOMMIT=0'); - $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK - return TRUE; + $this->conn_id->autocommit(FALSE); + return is_php('5.5') + ? $this->conn_id->begin_transaction() + : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK } // -------------------------------------------------------------------- @@ -261,9 +262,13 @@ class CI_DB_mysqli_driver extends CI_DB { return TRUE; } - $this->simple_query('COMMIT'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + if ($this->conn_id->commit()) + { + $this->conn_id->autocommit(TRUE); + return TRUE; + } + + return FALSE; } // -------------------------------------------------------------------- @@ -281,9 +286,13 @@ class CI_DB_mysqli_driver extends CI_DB { return TRUE; } - $this->simple_query('ROLLBACK'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + if ($this->conn_id->rollback()) + { + $this->conn_id->autocommit(TRUE); + return TRUE; + } + + return FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php index 0ec8b53b8..020a3a4ba 100644 --- a/system/database/drivers/oci8/oci8_driver.php +++ b/system/database/drivers/oci8/oci8_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -327,12 +327,8 @@ class CI_DB_oci8_driver extends CI_DB { { if ($package === '' OR $procedure === '' OR ! is_array($params)) { - if ($this->db_debug) - { - log_message('error', 'Invalid query: '.$package.'.'.$procedure); - return $this->display_error('db_invalid_query'); - } - return FALSE; + log_message('error', 'Invalid query: '.$package.'.'.$procedure); + return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; } // build the query string diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php index fd1d28787..ce09b62bc 100644 --- a/system/database/drivers/oci8/oci8_result.php +++ b/system/database/drivers/oci8/oci8_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php index fa89661b1..184a8df33 100644 --- a/system/database/drivers/pdo/pdo_driver.php +++ b/system/database/drivers/pdo/pdo_driver.php @@ -69,7 +69,7 @@ class CI_DB_pdo_driver extends CI_DB { { parent::__construct($params); - if (preg_match('/([^;]+):/', $this->dsn, $match) && count($match) === 2) + if (preg_match('/([^:]+):/', $this->dsn, $match) && count($match) === 2) { // If there is a minimum valid dsn string pattern found, we're done // This is for general PDO users, who tend to have a full DSN string. @@ -77,7 +77,7 @@ class CI_DB_pdo_driver extends CI_DB { return; } // Legacy support for DSN specified in the hostname field - elseif (preg_match('/([^;]+):/', $this->hostname, $match) && count($match) === 2) + elseif (preg_match('/([^:]+):/', $this->hostname, $match) && count($match) === 2) { $this->dsn = $this->hostname; $this->hostname = NULL; diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php index a39045eb7..c49549961 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php @@ -103,7 +103,7 @@ class CI_DB_pdo_4d_forge extends CI_DB_4d_forge { { if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) { - return parent::_alter_table($alter_table, $table, $field); + return parent::_alter_table($alter_type, $table, $field); } // No method of modifying columns is supported diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php index fdeefc9c5..fda3f238b 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php @@ -130,6 +130,19 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { // -------------------------------------------------------------------- /** + * Determines if a query is a "write" type. + * + * @param string An SQL query string + * @return bool + */ + public function is_write_type($sql) + { + return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); + } + + // -------------------------------------------------------------------- + + /** * "Smart" Escape String * * Escapes data based on type @@ -153,7 +166,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { * ORDER BY * * @param string $orderby - * @param string $direction ASC or DESC + * @param string $direction ASC, DESC or RANDOM * @param bool $escape * @return object */ diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index d35e351fc..b72fb873a 100644 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -311,6 +311,19 @@ class CI_DB_postgre_driver extends CI_DB { // -------------------------------------------------------------------- /** + * Determines if a query is a "write" type. + * + * @param string An SQL query string + * @return bool + */ + public function is_write_type($sql) + { + return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); + } + + // -------------------------------------------------------------------- + + /** * Platform-dependant string escape * * @param string @@ -318,7 +331,7 @@ class CI_DB_postgre_driver extends CI_DB { */ protected function _escape_str($str) { - return pg_escape_string($str); + return pg_escape_string($this->conn_id, $str); } // -------------------------------------------------------------------- @@ -333,7 +346,11 @@ class CI_DB_postgre_driver extends CI_DB { */ public function escape($str) { - if (is_bool($str)) + if (is_php('5.4.4') && (is_string($str) OR (is_object($str) && method_exists($str, '__toString')))) + { + return pg_escape_literal($this->conn_id, $str); + } + elseif (is_bool($str)) { return ($str) ? 'TRUE' : 'FALSE'; } @@ -499,7 +516,7 @@ class CI_DB_postgre_driver extends CI_DB { * ORDER BY * * @param string $orderby - * @param string $direction ASC or DESC + * @param string $direction ASC, DESC or RANDOM * @param bool $escape * @return object */ diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index f3b9c6cc4..ea46f97b3 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -43,15 +43,31 @@ if ( ! function_exists('create_captcha')) /** * Create CAPTCHA * - * @param array array of data for the CAPTCHA - * @param string path to create the image in - * @param string URL to the CAPTCHA image folder - * @param string server path to font + * @param array $data data for the CAPTCHA + * @param string $img_path path to create the image in + * @param string $img_url URL to the CAPTCHA image folder + * @param string $font_path server path to font * @return string */ function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '') { - $defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200, 'word_length' => 8, 'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'); + $defaults = array( + 'word' => '', + 'img_path' => '', + 'img_url' => '', + 'img_width' => '150', + 'img_height' => '30', + 'font_path' => '', + 'expiration' => 7200, + 'word_length' => 8, + 'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', + 'colors' => array( + 'background' => array(255,255,255), + 'border' => array(153,102,102), + 'text' => array(204,153,153), + 'grid' => array(255,182,182) + ) + ); foreach ($defaults as $key => $val) { @@ -110,9 +126,9 @@ if ( ! function_exists('create_captcha')) // Determine angle and position // ----------------------------------- $length = strlen($word); - $angle = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0; - $x_axis = rand(6, (360/$length)-16); - $y_axis = ($angle >= 0) ? rand($img_height, $img_width) : rand(6, $img_height); + $angle = ($length >= 6) ? mt_rand(-($length-6), ($length-6)) : 0; + $x_axis = mt_rand(6, (360/$length)-16); + $y_axis = ($angle >= 0) ? mt_rand($img_height, $img_width) : mt_rand(6, $img_height); // Create image // PHP.net recommends imagecreatetruecolor(), but it isn't always available @@ -122,15 +138,19 @@ if ( ! function_exists('create_captcha')) // ----------------------------------- // Assign colors - // ----------------------------------- - $bg_color = imagecolorallocate($im, 255, 255, 255); - $border_color = imagecolorallocate($im, 153, 102, 102); - $text_color = imagecolorallocate($im, 204, 153, 153); - $grid_color = imagecolorallocate($im, 255, 182, 182); - $shadow_color = imagecolorallocate($im, 255, 240, 240); + // ---------------------------------- + + is_array($colors) OR $colors = $defaults['colors']; + + foreach (array_keys($defaults['colors']) as $key) + { + // Check for a possible missing value + is_array($colors[$key]) OR $colors[$key] = $defaults['colors'][$key]; + $colors[$key] = imagecolorallocate($im, $colors[$key][0], $colors[$key][1], $colors[$key][2]); + } - // Create the rectangle - ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color); + // Create the rectangle + ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $colors['background']); // ----------------------------------- // Create the spiral pattern @@ -151,7 +171,7 @@ if ( ! function_exists('create_captcha')) $rad1 = $radius * (($i + 1) / $points); $x1 = ($rad1 * cos($theta)) + $x_axis; $y1 = ($rad1 * sin($theta)) + $y_axis; - imageline($im, $x, $y, $x1, $y1, $grid_color); + imageline($im, $x, $y, $x1, $y1, $colors['grid']); $theta -= $thetac; } @@ -163,13 +183,13 @@ if ( ! function_exists('create_captcha')) if ($use_font === FALSE) { $font_size = 5; - $x = rand(0, $img_width / ($length / 3)); + $x = mt_rand(0, $img_width / ($length / 3)); $y = 0; } else { $font_size = 16; - $x = rand(0, $img_width / ($length / 1.5)); + $x = mt_rand(0, $img_width / ($length / 1.5)); $y = $font_size + 2; } @@ -177,20 +197,20 @@ if ( ! function_exists('create_captcha')) { if ($use_font === FALSE) { - $y = rand(0 , $img_height / 2); - imagestring($im, $font_size, $x, $y, $word[$i], $text_color); + $y = mt_rand(0 , $img_height / 2); + imagestring($im, $font_size, $x, $y, $word[$i], $colors['text']); $x += ($font_size * 2); } else { - $y = rand($img_height / 2, $img_height - 3); - imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, $word[$i]); + $y = mt_rand($img_height / 2, $img_height - 3); + imagettftext($im, $font_size, $angle, $x, $y, $colors['text'], $font_path, $word[$i]); $x += $font_size; } } // Create the border - imagerectangle($im, 0, 0, $img_width - 1, $img_height - 1, $border_color); + imagerectangle($im, 0, 0, $img_width - 1, $img_height - 1, $colors['border']); // ----------------------------------- // Generate the image diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php index 41a7ab635..c3a8d3c9e 100644 --- a/system/helpers/date_helper.php +++ b/system/helpers/date_helper.php @@ -677,7 +677,7 @@ if ( ! function_exists('date_range')) $is_unix = ! ( ! $is_unix OR $is_unix === 'days'); // Validate input and try strtotime() on invalid timestamps/intervals, just in case - if ( ( ! ctype_digit((string) $unix_start) && ($unix_start = @strtotime($unix_time)) === FALSE) + if ( ( ! ctype_digit((string) $unix_start) && ($unix_start = @strtotime($unix_start)) === FALSE) OR ( ! ctype_digit((string) $mixed) && ($is_unix === FALSE OR ($mixed = @strtotime($mixed)) === FALSE)) OR ($is_unix === TRUE && $mixed < $unix_start)) { @@ -686,7 +686,7 @@ if ( ! function_exists('date_range')) if ($is_unix && ($unix_start == $mixed OR date($format, $unix_start) === date($format, $mixed))) { - return array($start_date); + return array(date($format, $unix_start)); } $range = array(); diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index 1b8efff27..4b45a62d0 100644 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -275,7 +275,7 @@ if ( ! function_exists('get_file_info')) switch ($key) { case 'name': - $fileinfo['name'] = substr(strrchr($file, DIRECTORY_SEPARATOR), 1); + $fileinfo['name'] = basename($file); break; case 'server_path': $fileinfo['server_path'] = $file; diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 2002d4269..85f1f4e01 100644 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -50,15 +50,10 @@ if ( ! function_exists('form_open')) * @param array a key/value pair hidden data * @return string */ - function form_open($action = '', $attributes = '', $hidden = array()) + function form_open($action = '', $attributes = array(), $hidden = array()) { $CI =& get_instance(); - if ($attributes === '') - { - $attributes = 'method="post"'; - } - // If an action is not a full URL then turn it into one if ($action && strpos($action, '://') === FALSE) { @@ -70,10 +65,22 @@ if ( ! function_exists('form_open')) $action = $CI->config->site_url($CI->uri->uri_string()); } - $form = '<form action="'.$action.'"'._attributes_to_string($attributes, TRUE).">\n"; + $attributes = _attributes_to_string($attributes); + + if (stripos($attributes, 'method=') === FALSE) + { + $attributes .= ' method="post"'; + } + + if (stripos($attributes, 'accept-charset=') === FALSE) + { + $attributes .= ' accept-charset="'.strtolower(config_item('charset')).'"'; + } + + $form = '<form action="'.$action.'"'.$attributes.">\n"; // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites - if ($CI->config->item('csrf_protection') === TRUE && ! (strpos($action, $CI->config->base_url()) === FALSE OR strpos($form, 'method="get"'))) + if ($CI->config->item('csrf_protection') === TRUE && ! (strpos($action, $CI->config->base_url()) === FALSE OR stripos($form, 'method="get"'))) { $hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash(); } @@ -321,11 +328,8 @@ if ( ! function_exists('form_dropdown')) { $selected = array($_POST[$name]); } - - if ($extra != '') - { - $extra = ' '.$extra; - } + + $extra = _attributes_to_string($extra); $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : ''; @@ -542,12 +546,12 @@ if ( ! function_exists('form_fieldset')) * use form_fieldset_close() * * @param string The legend text - * @param string Additional attributes + * @param array Additional attributes * @return string */ function form_fieldset($legend_text = '', $attributes = array()) { - $fieldset = '<fieldset'._attributes_to_string($attributes, FALSE).">\n"; + $fieldset = '<fieldset'._attributes_to_string($attributes).">\n"; if ($legend_text !== '') { return $fieldset.'<legend>'.$legend_text."</legend>\n"; @@ -668,37 +672,22 @@ if ( ! function_exists('set_select')) */ function set_select($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) + { + return $CI->form_validation->set_select($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' selected="selected"' : ''; + } + elseif (is_array($input) && in_array($value, $input, TRUE)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' selected="selected"'; - } - return ''; - } - - $field = $_POST[$field]; - - if (is_array($field)) - { - if ( ! in_array($value, $field)) - { - return ''; - } - } - elseif (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - return ' selected="selected"'; } - return $OBJ->set_select($field, $value, $default); + return ($input === $value) ? ' selected="selected"' : ''; } } @@ -719,37 +708,22 @@ if ( ! function_exists('set_checkbox')) */ function set_checkbox($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) + { + return $CI->form_validation->set_checkbox($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' checked="checked"' : ''; + } + elseif (is_array($input) && in_array($value, $input, TRUE)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' checked="checked"'; - } - return ''; - } - - $field = $_POST[$field]; - - if (is_array($field)) - { - if ( ! in_array($value, $field)) - { - return ''; - } - } - elseif (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - return ' checked="checked"'; } - return $OBJ->set_checkbox($field, $value, $default); + return ($input === $value) ? ' checked="checked"' : ''; } } @@ -763,47 +737,25 @@ if ( ! function_exists('set_radio')) * Let's you set the selected value of a radio field via info in the POST array. * If Form Validation is active it retrieves the info from the validation class * - * @param string - * @param string - * @param bool + * @param string $field + * @param string $value + * @param bool $default * @return string */ function set_radio($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' checked="checked"'; - } - return ''; - } - - $field = $_POST[$field]; - - if (is_array($field)) - { - if ( ! in_array($value, $field)) - { - return ''; - } - } - else - { - if (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - } - - return ' checked="checked"'; + return $CI->form_validation->set_radio($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' checked="checked"' : ''; } - return $OBJ->set_radio($field, $value, $default); + return ($input === $value) ? ' checked="checked"' : ''; } } @@ -920,45 +872,24 @@ if ( ! function_exists('_attributes_to_string')) * Helper function used by some of the form helpers * * @param mixed - * @param bool * @return string */ - function _attributes_to_string($attributes, $formtag = FALSE) + function _attributes_to_string($attributes) { - if (is_string($attributes) && strlen($attributes) > 0) + if (empty($attributes)) { - if ($formtag === TRUE && strpos($attributes, 'method=') === FALSE) - { - $attributes .= ' method="post"'; - } - - if ($formtag === TRUE && strpos($attributes, 'accept-charset=') === FALSE) - { - $attributes .= ' accept-charset="'.strtolower(config_item('charset')).'"'; - } - - return ' '.$attributes; + return ''; } - if (is_object($attributes) && count($attributes) > 0) + if (is_object($attributes)) { $attributes = (array) $attributes; } - if (is_array($attributes) && ($formtag === TRUE OR count($attributes) > 0)) + if (is_array($attributes)) { $atts = ''; - if ( ! isset($attributes['method']) && $formtag === TRUE) - { - $atts .= ' method="post"'; - } - - if ( ! isset($attributes['accept-charset']) && $formtag === TRUE) - { - $atts .= ' accept-charset="'.strtolower(config_item('charset')).'"'; - } - foreach ($attributes as $key => $val) { $atts .= ' '.$key.'="'.$val.'"'; @@ -966,6 +897,13 @@ if ( ! function_exists('_attributes_to_string')) return $atts; } + + if (is_string($attributes)) + { + return ' '.$attributes; + } + + return FALSE; } } @@ -988,7 +926,7 @@ if ( ! function_exists('_get_validation_object')) // We set this as a variable since we're returning by reference. $return = FALSE; - if (FALSE !== ($object = $CI->load->is_loaded('form_validation'))) + if (FALSE !== ($object = $CI->load->is_loaded('Form_validation'))) { if ( ! isset($CI->$object) OR ! is_object($CI->$object)) { diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php index 80a27876f..ece39584b 100644 --- a/system/helpers/html_helper.php +++ b/system/helpers/html_helper.php @@ -109,7 +109,7 @@ if ( ! function_exists('_list')) * @param int * @return string */ - function _list($type = 'ul', $list, $attributes = '', $depth = 0) + function _list($type = 'ul', $list = array(), $attributes = '', $depth = 0) { // If an array wasn't submitted there's nothing to do... if ( ! is_array($list)) diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index d0fab3fe0..fbb4a1b24 100644 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -46,13 +46,20 @@ if ( ! function_exists('site_url')) * Create a local URL based on your basepath. Segments can be passed via the * first parameter either as a string or an array. * - * @param string + * @param string $uri + * @param string $protocol * @return string */ - function site_url($uri = '') + function site_url($uri = '', $protocol = NULL) { - $CI =& get_instance(); - return $CI->config->site_url($uri); + $uri = get_instance()->config->site_url($uri); + + if (isset($protocol)) + { + return $protocol.substr($uri, strpos($uri, '://')); + } + + return $uri; } } @@ -67,13 +74,20 @@ if ( ! function_exists('base_url')) * Segments can be passed in as a string or an array, same as site_url * or a URL to a file can be passed in, e.g. to an image file. * - * @param string + * @param string $uri + * @param string $protocol * @return string */ - function base_url($uri = '') + function base_url($uri = '', $protocol = NULL) { - $CI =& get_instance(); - return $CI->config->base_url($uri); + $uri = get_instance()->config->base_url($uri); + + if (isset($protocol)) + { + return $protocol.substr($uri, strpos($uri, '://')); + } + + return $uri; } } diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php index e1089f755..537897eaf 100644 --- a/system/libraries/Cache/Cache.php +++ b/system/libraries/Cache/Cache.php @@ -106,7 +106,7 @@ class CI_Cache extends CI_Driver_Library { isset($config['key_prefix']) && $this->key_prefix = $config['key_prefix']; - if (isset($config['backup']) && in_array('cache_'.$config['backup'], $this->valid_drivers)) + if (isset($config['backup']) && in_array($config['backup'], $this->valid_drivers)) { $this->_backup_driver = $config['backup']; } @@ -123,6 +123,7 @@ class CI_Cache extends CI_Driver_Library { else { // Backup is supported. Set it to primary. + log_message('debug', 'Cache adapter "'.$this->_adapter.'" is unavailable. Falling back to "'.$this->_backup_driver.'" backup adapter.'); $this->_adapter = $this->_backup_driver; } } diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php index 127a220a7..a84e7d2d3 100644 --- a/system/libraries/Cache/drivers/Cache_apc.php +++ b/system/libraries/Cache/drivers/Cache_apc.php @@ -150,7 +150,7 @@ class CI_Cache_apc extends CI_Driver { { if ( ! extension_loaded('apc') OR ! (bool) @ini_get('apc.enabled')) { - log_message('error', 'The APC PHP extension must be loaded to use APC Cache.'); + log_message('debug', 'The APC PHP extension must be loaded to use APC Cache.'); return FALSE; } diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php index 246a7a264..d2a3a489d 100644 --- a/system/libraries/Cache/drivers/Cache_memcached.php +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -51,9 +51,9 @@ class CI_Cache_memcached extends CI_Driver { */ protected $_memcache_conf = array( 'default' => array( - 'default_host' => '127.0.0.1', - 'default_port' => 11211, - 'default_weight' => 1 + 'host' => '127.0.0.1', + 'port' => 11211, + 'weight' => 1 ) ); @@ -173,7 +173,8 @@ class CI_Cache_memcached extends CI_Driver { { if (is_array($CI->config->config['memcached'])) { - $this->_memcache_conf = NULL; + $defaults = $this->_memcache_conf['default']; + $this->_memcache_conf = array(); foreach ($CI->config->config['memcached'] as $name => $conf) { @@ -196,22 +197,11 @@ class CI_Cache_memcached extends CI_Driver { return FALSE; } - foreach ($this->_memcache_conf as $name => $cache_server) + foreach ($this->_memcache_conf as $cache_server) { - if ( ! array_key_exists('hostname', $cache_server)) - { - $cache_server['hostname'] = $this->_memcache_conf['default']['default_host']; - } - - if ( ! array_key_exists('port', $cache_server)) - { - $cache_server['port'] = $this->_memcache_conf['default']['default_port']; - } - - if ( ! array_key_exists('weight', $cache_server)) - { - $cache_server['weight'] = $this->_memcache_conf['default']['default_weight']; - } + isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host']; + isset($cache_server['port']) OR $cache_server['port'] = $defaults['host']; + isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight']; if (get_class($this->_memcached) === 'Memcache') { @@ -250,7 +240,7 @@ class CI_Cache_memcached extends CI_Driver { { if ( ! extension_loaded('memcached') && ! extension_loaded('memcache')) { - log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.'); + log_message('debug', 'The Memcached Extension must be loaded to use Memcached Cache.'); return FALSE; } diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php index 484f284f1..40823fcb4 100644 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -168,7 +168,7 @@ class CI_Cache_redis extends CI_Driver } else { - log_message('error', 'The Redis extension must be loaded to use Redis cache.'); + log_message('debug', 'The Redis extension must be loaded to use Redis cache.'); return FALSE; } } diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php index d749978f5..80d3ac13d 100644 --- a/system/libraries/Cache/drivers/Cache_wincache.php +++ b/system/libraries/Cache/drivers/Cache_wincache.php @@ -150,7 +150,7 @@ class CI_Cache_wincache extends CI_Driver { { if ( ! extension_loaded('wincache')) { - log_message('error', 'The Wincache PHP extension must be loaded to use Wincache Cache.'); + log_message('debug', 'The Wincache PHP extension must be loaded to use Wincache Cache.'); return FALSE; } diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 11ee29041..efdbfd7c1 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -399,9 +399,9 @@ class CI_Email { else { $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - $this->_safe_mode = (bool) @ini_get('safe_mode'); } + $this->_safe_mode = ( ! is_php('5.4') && (bool) @ini_get('safe_mode')); $this->charset = strtoupper($this->charset); log_message('debug', 'Email Class Initialized'); @@ -451,7 +451,6 @@ class CI_Email { $this->clear(); $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - $this->_safe_mode = (bool) @ini_get('safe_mode'); return $this; } @@ -1265,7 +1264,7 @@ class CI_Email { } else { - $this->_finalbody = $hdr . $this->newline . $this->newline . $this->_body; + $this->_finalbody = $hdr.$this->newline.$this->newline.$this->_body; } return; @@ -1275,11 +1274,11 @@ class CI_Email { if ($this->send_multipart === FALSE) { $hdr .= 'Content-Type: text/html; charset='.$this->charset.$this->newline - .'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline; + .'Content-Transfer-Encoding: quoted-printable'; } else { - $hdr .= 'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'.$this->newline.$this->newline; + $hdr .= 'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'; $body .= $this->_get_mime_message().$this->newline.$this->newline .'--'.$this->_alt_boundary.$this->newline @@ -1300,7 +1299,7 @@ class CI_Email { } else { - $this->_finalbody = $hdr.$this->_finalbody; + $this->_finalbody = $hdr.$this->newline.$this->newline.$this->_finalbody; } if ($this->send_multipart !== FALSE) @@ -1312,25 +1311,25 @@ class CI_Email { case 'plain-attach' : - $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'.$this->newline.$this->newline; + $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'; if ($this->_get_protocol() === 'mail') { $this->_header_str .= $hdr; } - $body .= $this->_get_mime_message().$this->newline.$this->newline + $body .= $this->_get_mime_message().$this->newline + .$this->newline .'--'.$this->_atc_boundary.$this->newline - .'Content-Type: text/plain; charset='.$this->charset.$this->newline - .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline - + .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline + .$this->newline .$this->_body.$this->newline.$this->newline; break; case 'html-attach' : - $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'.$this->newline.$this->newline; + $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'; if ($this->_get_protocol() === 'mail') { @@ -1400,7 +1399,9 @@ class CI_Email { } $body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--'; - $this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr.$body; + $this->_finalbody = ($this->_get_protocol() === 'mail') + ? $body + : $hdr.$this->newline.$this->newline.$body; return TRUE; } @@ -2140,7 +2141,7 @@ class CI_Email { if (in_array('headers', $include, TRUE)) { - $raw_data = $this->_header_str."\n"; + $raw_data = htmlspecialchars($this->_header_str)."\n"; } if (in_array('subject', $include, TRUE)) diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index 40ba01202..8b9bfa897 100644 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -583,7 +583,7 @@ class CI_Form_validation { // If the field is blank, but NOT required, no further tests are necessary $callback = FALSE; - if ( ! in_array('required', $rules) && $postdata === NULL) + if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === '')) { // Before we bail out, does the rule contain a callback? if (preg_match('/(callback_\w+(\[.*?\])?)/', implode(' ', $rules), $match)) @@ -598,7 +598,7 @@ class CI_Form_validation { } // Isset Test. Typically this rule will only apply to checkboxes. - if ($postdata === NULL && $callback === FALSE) + if (($postdata === NULL OR $postdata === '') && $callback === FALSE) { if (in_array('isset', $rules, TRUE) OR in_array('required', $rules)) { diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php index 773a58384..26a16850c 100644 --- a/system/libraries/Javascript.php +++ b/system/libraries/Javascript.php @@ -172,7 +172,7 @@ class CI_Javascript { */ public function focus($element = 'this', $js = '') { - return $this->js->__add_event($focus, $js); + return $this->js->_focus($element, $js); } // -------------------------------------------------------------------- @@ -187,9 +187,9 @@ class CI_Javascript { * @param string - Javascript code for mouse out * @return string */ - public function hover($element = 'this', $over, $out) + public function hover($element = 'this', $over = '', $out = '') { - return $this->js->__hover($element, $over, $out); + return $this->js->_hover($element, $over, $out); } // -------------------------------------------------------------------- diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php index b6e0434b2..ab78e8b2e 100644 --- a/system/libraries/Javascript/Jquery.php +++ b/system/libraries/Javascript/Jquery.php @@ -225,7 +225,7 @@ class CI_Jquery extends CI_Javascript { * @param string - Javascript code for mouse out * @return string */ - protected function _hover($element = 'this', $over, $out) + protected function _hover($element = 'this', $over = '', $out = '') { $event = "\n\t$(".$this->_prep_element($element).").hover(\n\t\tfunction()\n\t\t{\n\t\t\t{$over}\n\t\t}, \n\t\tfunction()\n\t\t{\n\t\t\t{$out}\n\t\t});\n"; @@ -715,7 +715,7 @@ class CI_Jquery extends CI_Javascript { * @return string */ - protected function _updater($container = 'this', $controller, $options = '') + protected function _updater($container = 'this', $controller = '', $options = '') { $container = $this->_prep_element($container); $controller = (strpos('://', $controller) === FALSE) ? $controller : $this->CI->config->site_url($controller); @@ -923,7 +923,6 @@ class CI_Jquery extends CI_Javascript { if (is_array($js)) { $js = implode("\n\t\t", $js); - } $event = "\n\t$(".$this->_prep_element($element).').'.$event."(function(){\n\t\t{$js}\n\t});\n"; @@ -937,7 +936,7 @@ class CI_Jquery extends CI_Javascript { * Compile * * As events are specified, they are stored in an array - * This funciton compiles them all for output on a page + * This function compiles them all for output on a page * * @param string $view_var * @param bool $script_tags diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index 10fb29dbd..c6ffd03d4 100644 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -354,7 +354,8 @@ class CI_Pagination { public function create_links() { // If our item count or per-page total is zero there is no need to continue. - if ($this->total_rows === 0 OR $this->per_page === 0) + // Note: DO NOT change the operator to === here! + if ($this->total_rows == 0 OR $this->per_page == 0) { return ''; } diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php index 1c26bd2b2..c1f1ad73b 100644 --- a/system/libraries/Parser.php +++ b/system/libraries/Parser.php @@ -38,14 +38,14 @@ defined('BASEPATH') OR exit('No direct script access allowed'); class CI_Parser { /** - * Left delimeter character for psuedo vars + * Left delimiter character for pseudo vars * * @var string */ public $l_delim = '{'; /** - * Right delimeter character for psuedo vars + * Right delimiter character for pseudo vars * * @var string */ diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index 3c7ce5406..50ba1673f 100644 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -264,7 +264,7 @@ class CI_Profiler { foreach ($db->queries as $key => $val) { $time = number_format($db->query_times[$key], 4); - $val = highlight_code($val, ENT_QUOTES); + $val = highlight_code($val); foreach ($highlight as $bold) { @@ -307,10 +307,7 @@ class CI_Profiler { foreach ($_GET as $key => $val) { - if ( ! is_numeric($key)) - { - $key = "'".$key."'"; - } + is_int($key) OR $key = "'".$key."'"; $output .= '<tr><td style="width:50%;color:#000;background-color:#ddd;padding:5px;">$_GET[' .$key.'] </td><td style="width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;">' @@ -338,7 +335,7 @@ class CI_Profiler { ."\n" .'<legend style="color:#009900;"> '.$this->CI->lang->line('profiler_post_data')." </legend>\n"; - if (count($_POST) === 0) + if (count($_POST) === 0 && count($_FILES) === 0) { $output .= '<div style="color:#009900;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_post').'</div>'; } @@ -348,10 +345,7 @@ class CI_Profiler { foreach ($_POST as $key => $val) { - if ( ! is_numeric($key)) - { - $key = "'".$key."'"; - } + is_int($key) OR $key = "'".$key."'"; $output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">$_POST[' .$key.'] </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">'; @@ -368,6 +362,21 @@ class CI_Profiler { $output .= "</td></tr>\n"; } + foreach ($_FILES as $key => $val) + { + is_int($key) OR $key = "'".$key."'"; + + $output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">$_FILES[' + .$key.'] </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">'; + + if (is_array($val) OR is_object($val)) + { + $output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>'; + } + + $output .= "</td></tr>\n"; + } + $output .= "</table>\n"; } @@ -447,7 +456,7 @@ class CI_Profiler { .' (<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_httpheaders_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show')."</span>)</legend>\n\n\n" .'<table style="width:100%;display:none;" id="ci_profiler_httpheaders_table">'."\n"; - foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header) + foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR', 'HTTP_DNT') as $header) { $val = isset($_SERVER[$header]) ? $_SERVER[$header] : ''; $output .= '<tr><td style="vertical-align:top;width:50%;padding:5px;color:#900;background-color:#ddd;">' diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index c7f6f828c..659a0269e 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -60,11 +60,18 @@ class CI_Session extends CI_Driver_Library { public $params = array(); /** + * Valid drivers list + * + * @var array + */ + public $valid_drivers = array('native', 'cookie'); + + /** * Current driver in use * * @var string */ - protected $current = NULL; + public $current = NULL; /** * User data @@ -105,36 +112,26 @@ class CI_Session extends CI_Driver_Library { log_message('debug', 'CI_Session Class Initialized'); - // Get valid drivers list - $this->valid_drivers = array( - 'native', - 'cookie' - ); - $key = 'sess_valid_drivers'; - $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key); - if ($drivers) + // Add possible extra entries to our valid drivers list + $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $CI->config->item('sess_valid_drivers'); + if ( ! empty($drivers)) { - // Add driver names to valid list - foreach ((array) $drivers as $driver) - { - if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) - { - $this->valid_drivers[] = $driver; - } - } + $drivers = array_map('strtolower', (array) $drivers); + $this->valid_drivers = array_merge($this->valid_drivers, array_diff($drivers, $this->valid_drivers)); } // Get driver to load - $key = 'sess_driver'; - $driver = isset($params[$key]) ? $params[$key] : $CI->config->item($key); + $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $CI->config->item('sess_driver'); if ( ! $driver) { + log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'."); $driver = 'cookie'; } - if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) + if ( ! in_array($driver, $this->valid_drivers)) { - $this->valid_drivers[] = $driver; + log_message('error', 'Session: Configured driver name is not valid, aborting.'); + return; } // Save a copy of parameters in case drivers need access diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 7174d63c8..d3d22d03a 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -402,6 +402,7 @@ class CI_Session_cookie extends CI_Session_driver { // Is the session data we unserialized an array with the correct format? if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity'])) { + log_message('debug', 'Session: Wrong cookie data format'); $this->sess_destroy(); return FALSE; } @@ -409,6 +410,7 @@ class CI_Session_cookie extends CI_Session_driver { // Is the session current? if (($session['last_activity'] + $this->sess_expiration) < $this->now OR $session['last_activity'] > $this->now) { + log_message('debug', 'Session: Expired'); $this->sess_destroy(); return FALSE; } @@ -416,6 +418,7 @@ class CI_Session_cookie extends CI_Session_driver { // Does the IP match? if ($this->sess_match_ip === TRUE && $session['ip_address'] !== $this->CI->input->ip_address()) { + log_message('debug', 'Session: IP address mismatch'); $this->sess_destroy(); return FALSE; } @@ -424,6 +427,7 @@ class CI_Session_cookie extends CI_Session_driver { if ($this->sess_match_useragent === TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120))) { + log_message('debug', 'Session: User Agent string mismatch'); $this->sess_destroy(); return FALSE; } @@ -459,6 +463,7 @@ class CI_Session_cookie extends CI_Session_driver { // No result? Kill it! if (empty($query) OR $query->num_rows() === 0) { + log_message('debug', 'Session: No match found in our database'); $this->sess_destroy(); return FALSE; } @@ -498,6 +503,8 @@ class CI_Session_cookie extends CI_Session_driver { 'last_activity' => $this->now, ); + log_message('debug', 'Session: Creating new session ('.$this->userdata['session_id'].')'); + // Check for database if ($this->sess_use_database === TRUE) { @@ -536,6 +543,8 @@ class CI_Session_cookie extends CI_Session_driver { { // Get new id $this->userdata['session_id'] = $this->_make_sess_id(); + + log_message('debug', 'Session: Regenerate ID'); } // Check for database diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index fb5ce1906..c237ad059 100644 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -117,18 +117,21 @@ class CI_Session_native extends CI_Session_driver { if (isset($_SESSION['last_activity']) && (($_SESSION['last_activity'] + $expire) < $now OR $_SESSION['last_activity'] > $now)) { // Expired - destroy + log_message('debug', 'Session: Expired'); $destroy = TRUE; } elseif ($config['sess_match_ip'] === TRUE && isset($_SESSION['ip_address']) && $_SESSION['ip_address'] !== $this->CI->input->ip_address()) { // IP doesn't match - destroy + log_message('debug', 'Session: IP address mismatch'); $destroy = TRUE; } elseif ($config['sess_match_useragent'] === TRUE && isset($_SESSION['user_agent']) && $_SESSION['user_agent'] !== trim(substr($this->CI->input->user_agent(), 0, 50))) { // Agent doesn't match - destroy + log_message('debug', 'Session: User Agent string mismatch'); $destroy = TRUE; } @@ -145,9 +148,10 @@ class CI_Session_native extends CI_Session_driver { && ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now) { // Changing the session ID amidst a series of AJAX calls causes problems - if( ! $this->CI->input->is_ajax_request()) + if ( ! $this->CI->input->is_ajax_request()) { // Regenerate ID, but don't destroy session + log_message('debug', 'Session: Regenerate ID'); $this->sess_regenerate(FALSE); } } diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 5861df584..060973847 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -463,7 +463,7 @@ class CI_Upload { } // Are the image dimensions within the allowed size? - // Note: This can fail if the server has an open_basdir restriction. + // Note: This can fail if the server has an open_basedir restriction. if ( ! $this->is_allowed_dimensions()) { $this->set_error('upload_invalid_dimensions'); @@ -1090,18 +1090,14 @@ class CI_Upload { $CI =& get_instance(); $CI->lang->load('upload'); - if (is_array($msg)) + if ( ! is_array($msg)) { - foreach ($msg as $val) - { - $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val); - $this->error_msg[] = $msg; - log_message('error', $msg); - } + $msg = array($msg); } - else + + foreach ($msg as $val) { - $msg = ($CI->lang->line($msg) === FALSE) ? $msg : $CI->lang->line($msg); + $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val); $this->error_msg[] = $msg; log_message('error', $msg); } @@ -1249,7 +1245,7 @@ class CI_Upload { } } - if ( (bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec')) + if ((bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec')) { $mime = @shell_exec($cmd); if (strlen($mime) > 0) diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index 2f6f81909..50ac9be98 100644 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -471,13 +471,24 @@ class CI_User_agent { */ public function is_referral() { - if (empty($_SERVER['HTTP_REFERER'])) + static $result; + + if ( ! isset($result)) { - return FALSE; + if (empty($_SERVER['HTTP_REFERER'])) + { + $result = FALSE; + } + else + { + $referer_host = @parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); + $own_host = parse_url(config_item('base_url'), PHP_URL_HOST); + + $result = ($referer_host && $referer_host !== $own_host); + } } - $referer = parse_url($_SERVER['HTTP_REFERER']); - return ! (empty($referer['host']) && strpos(config_item('base_url'), $referer['host']) !== FALSE); + return $result; } // -------------------------------------------------------------------- diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index 9e60791ae..16c5b0ed8 100644 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -446,7 +446,7 @@ class CI_Xmlrpc { { while (list($k) = each($value[0])) { - $value[0][$k] = $this->values_parsing($value[0][$k], TRUE); + $value[0][$k] = $this->values_parsing($value[0][$k]); } } diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php index 6608f050e..2ce457844 100644 --- a/system/libraries/Zip.php +++ b/system/libraries/Zip.php @@ -103,12 +103,12 @@ class CI_Zip { * * Lets you add a virtual directory into which you can place files. * - * @param mixed the directory name. Can be string or array + * @param mixed $directory the directory name. Can be string or array * @return void */ public function add_dir($directory) { - foreach ( (array) $directory as $dir) + foreach ((array) $directory as $dir) { if ( ! preg_match('|.+/$|', $dir)) { @@ -127,7 +127,7 @@ class CI_Zip { * * If this is a newly created file/dir, we will set the time to 'now' * - * @param string path to file + * @param string $dir path to file * @return array filemtime/filemdate */ protected function _get_mod_time($dir) @@ -146,9 +146,9 @@ class CI_Zip { /** * Add Directory * - * @param string the directory name - * @param int - * @param int + * @param string $dir the directory name + * @param int $file_mtime + * @param int $file_mdate * @return void */ protected function _add_dir($dir, $file_mtime, $file_mdate) @@ -199,8 +199,8 @@ class CI_Zip { * in the filename it will be placed within a directory. Make * sure you use add_dir() first to create the folder. * - * @param mixed - * @param string + * @param mixed $filepath A single filepath or an array of file => data pairs + * @param string $data Single file contents * @return void */ public function add_data($filepath, $data = NULL) @@ -225,10 +225,10 @@ class CI_Zip { /** * Add Data to Zip * - * @param string the file name/path - * @param string the data to be encoded - * @param int - * @param int + * @param string $filepath the file name/path + * @param string $data the data to be encoded + * @param int $file_mtime + * @param int $file_mdate * @return void */ protected function _add_data($filepath, $data, $file_mtime, $file_mdate) @@ -278,8 +278,8 @@ class CI_Zip { /** * Read the contents of a file and add it to the zip * - * @param string - * @param bool + * @param string $path + * @param bool $preserve_filepath * @return bool */ public function read_file($path, $preserve_filepath = FALSE) @@ -313,9 +313,9 @@ class CI_Zip { * sub-folders) and creates a zip based on it. Whatever directory structure * is in the original file path will be recreated in the zip file. * - * @param string path to source - * @param bool - * @param bool + * @param string $path path to source directory + * @param bool $preserve_filepath + * @param string $root_path * @return bool */ public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL) @@ -389,7 +389,7 @@ class CI_Zip { * * Lets you write a file * - * @param string the file name + * @param string $filepath the file name * @return bool */ public function archive($filepath) @@ -412,7 +412,7 @@ class CI_Zip { /** * Download * - * @param string the file name + * @param string $filename the file name * @return void */ public function download($filename = 'backup.zip') |