Commits

Phil Sturgeon committed 81d801c Merge

Changed the 'plural' function so that it doesn't ruin the captalization of your string. It also take into consideration acronyms which are all caps.

Comments (0)

Files changed (51)

 .DS_Store
 
 syntax: regexp
-system/cache/(?!index\.html|\.htaccess)
+application/cache/(?!index\.html|\.htaccess)
+application/logs/(?!index\.html|\.htaccess)
 3b6f3beea1262d35735167ee77c1fa8ea8d78d0c v1.7.2
 0000000000000000000000000000000000000000 v1.7.2
 ca87887086193cf375ea30e7d4e5139dbf330783 v2.0.0
+1941a814526f8aa7186112e6b9bfd868c5c4afbf v2.0.1
+1941a814526f8aa7186112e6b9bfd868c5c4afbf v2.0.1
+0000000000000000000000000000000000000000 v2.0.1
+0000000000000000000000000000000000000000 v2.0.1
+f97a33039a37fc0c3f12e48407ca08e281b6b375 v2.0.1
+f97a33039a37fc0c3f12e48407ca08e281b6b375 v2.0.1
+0000000000000000000000000000000000000000 v2.0.1
+0000000000000000000000000000000000000000 v2.0.1
+52cd3ed4a9ea5c2b0e2bdd38e9822161ef547f9a v2.0.1

application/migrations/001_Create_accounts.php

-<?php defined('BASEPATH') OR exit('No direct script access allowed');
-
-class Migration_Create_accounts extends	CI_Migration {
-	
-	function up() 
-	{	
-		if ( ! $this->db->table_exists('accounts'))
-		{
-			// Setup Keys
-			$this->dbforge->add_key('id', TRUE);
-			
-			$this->dbforge->add_field(array(
-				'id' => array('type' => 'INT', 'constraint' => 5, 'unsigned' => TRUE, 'auto_increment' => TRUE),
-				'company_name' => array('type' => 'VARCHAR', 'constraint' => '200', 'null' => FALSE),
-				'first_name' => array('type' => 'VARCHAR', 'constraint' => '200', 'null' => FALSE),
-				'last_name' => array('type' => 'VARCHAR', 'constraint' => '200', 'null' => FALSE),
-				'phone' => array('type' => 'TEXT', 'null' => FALSE),
-				'email' => array('type' => 'TEXT', 'null' => FALSE),
-				'address' => array('type' => 'TEXT', 'null' => FALSE),
-				'Last_Update' => array('type' => 'DATETIME', 'null' => FALSE)
-			));
-			
-			$this->dbforge->add_field("Created_At TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP");
-			$this->dbforge->create_table('accounts', TRUE);
-		}
-	}
-
-	function down() 
-	{
-		$this->dbforge->drop_table('accounts');
-	}
-}
  * By default development will show errors but testing and live will hide them.
  */
 
+if (defined('ENVIRONMENT'))
+{
 	switch (ENVIRONMENT)
 	{
 		case 'development':
 		default:
 			exit('The application environment is not set correctly.');
 	}
+}
 
 /*
  *---------------------------------------------------------------

system/core/CodeIgniter.php

  *  Load the framework constants
  * ------------------------------------------------------
  */
-	require(APPPATH.'config/constants'.EXT);
+	if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants'.EXT))
+	{
+		require(APPPATH.'config/'.ENVIRONMENT.'/constants'.EXT);
+	}
+	else
+	{
+		require(APPPATH.'config/constants'.EXT);
+	}
 
 /*
  * ------------------------------------------------------
 	}
 
 /*
+ * -----------------------------------------------------
+ * Load the security class for xss and csrf support
+ * -----------------------------------------------------
+ */
+	$SEC =& load_class('Security', 'core');
+
+/*
  * ------------------------------------------------------
  *  Load the Input class and sanitize globals
  * ------------------------------------------------------
 
 
 /* End of file CodeIgniter.php */
-/* Location: ./system/core/CodeIgniter.php */
+/* Location: ./system/core/CodeIgniter.php */

system/core/Common.php

 			@unlink($file);
 			return TRUE;
 		}
-		elseif (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
+		elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
 		{
 			return FALSE;
 		}
 			return $_config[0];
 		}
 
-		$file_path = APPPATH.'config/'.ENVIRONMENT.'/config'.EXT;
+		// Is the config file in the environment folder?
+		if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config'.EXT))
+		{
+			$file_path = APPPATH.'config/config'.EXT;
+		}
 
 		// Fetch the config file
 		if ( ! file_exists($file_path))
 		{
-			$file_path = APPPATH.'config/config'.EXT;
-			
-			if ( ! file_exists($file_path))
-			{
-				exit('The configuration file does not exist.');
-			}
+			exit('The configuration file does not exist.');
 		}
-	
+
 		require($file_path);
 
 		// Does the $config array exist in the file?
 	 * @param	string
 	 * @return	string
 	 */
-	function remove_invisible_characters($str)
+	function remove_invisible_characters($str, $url_encoded = TRUE)
 	{
-		static $non_displayables;
-
-		if ( ! isset($non_displayables))
+		$non_displayables = array();
+		
+		// every control character except newline (dec 10)
+		// carriage return (dec 13), and horizontal tab (dec 09)
+		
+		if ($url_encoded)
 		{
-			// every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09),
-			$non_displayables = array(
-										'/%0[0-8bcef]/',			// url encoded 00-08, 11, 12, 14, 15
-										'/%1[0-9a-f]/',				// url encoded 16-31
-										'/[\x00-\x08]/',			// 00-08
-										'/\x0b/', '/\x0c/',			// 11, 12
-										'/[\x0e-\x1f]/'				// 14-31
-									);
+			$non_displayables[] = '/%0[0-8bcef]/';	// url encoded 00-08, 11, 12, 14, 15
+			$non_displayables[] = '/%1[0-9a-f]/';	// url encoded 16-31
 		}
+		
+		$non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';	// 00-08, 11, 12, 14-31, 127
 
 		do
 		{
-			$cleaned = $str;
-			$str = preg_replace($non_displayables, '', $str);
+			$str = preg_replace($non_displayables, '', $str, -1, $count);
 		}
-		while ($cleaned != $str);
+		while ($count);
 
 		return $str;
 	}

system/core/Config.php

 	function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
 	{
 		$file = ($file == '') ? 'config' : str_replace(EXT, '', $file);
+		$found = FALSE;
 		$loaded = FALSE;
 
 		foreach ($this->_config_paths as $path)
-		{			
-			$file_path = $path.'config/'.ENVIRONMENT.'/'.$file.EXT;
+		{
+			$check_locations = defined('ENVIRONMENT')
+				? array(ENVIRONMENT.'/'.$file, $file)
+				: array($file);
 
-			if (in_array($file_path, $this->is_loaded, TRUE))
+			foreach ($check_locations as $location)
 			{
-				$loaded = TRUE;
+				$file_path = $path.'config/'.$location.EXT;
+
+				if (in_array($file_path, $this->is_loaded, TRUE))
+				{
+					$loaded = TRUE;
+					continue 2;
+				}
+
+				if (file_exists($file_path))
+				{
+					$found = TRUE;
+					break;
+				}
+			}
+
+			if ($found === FALSE)
+			{
 				continue;
 			}
 
-			if ( ! file_exists($file_path))
-			{
-				log_message('debug', 'Config for '.ENVIRONMENT.' environment is not found. Trying global config.');
-				$file_path = $path.'config/'.$file.EXT;
-				
-				if ( ! file_exists($file_path))
-				{
-					continue;
-				}
-			}
-			
 			include($file_path);
 
 			if ( ! isset($config) OR ! is_array($config))
 			{
 				return FALSE;
 			}
-			show_error('The configuration file '.ENVIRONMENT.'/'.$file.EXT.' and '.$file.EXT.' do not exist.');
+			show_error('The configuration file '.$file.EXT.' does not exist.');
 		}
-		
+
 		return TRUE;
 	}
 
 // END CI_Config class
 
 /* End of file Config.php */
-/* Location: ./system/core/Config.php */
+/* Location: ./system/core/Config.php */

system/core/Hooks.php

 		// Grab the "hooks" definition file.
 		// If there are no hooks, we're done.
 
-		@include(APPPATH.'config/hooks'.EXT);
+		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks'.EXT))
+		{
+		    include(APPPATH.'config/'.ENVIRONMENT.'/hooks'.EXT);
+		}
+		elseif (is_file(APPPATH.'config/hooks'.EXT))
+		{
+			include(APPPATH.'config/hooks'.EXT);
+		}
+
 
 		if ( ! isset($hook) OR ! is_array($hook))
 		{

system/core/Input.php

 		$this->_enable_xss		= (config_item('global_xss_filtering') === TRUE);
 		$this->_enable_csrf		= (config_item('csrf_protection') === TRUE);
 
-		// Do we need to load the security class?
-		if ($this->_enable_xss == TRUE OR $this->_enable_csrf == TRUE)
-		{
-			$this->security =& load_class('Security');
-		}
+		global $SEC;
+		$this->security =& $SEC;
 
 		// Do we need the UTF-8 class?
 		if (UTF8_ENABLED === TRUE)
 
 		if ($xss_clean === TRUE)
 		{
-			$_security =& load_class('Security');
-			return $_security->xss_clean($array[$index]);
+			return $this->security->xss_clean($array[$index]);
 		}
 
 		return $array[$index];
 		{
 			$str = $this->uni->clean_string($str);
 		}
+		
+		// Remove control characters
+		$str = remove_invisible_characters($str);
 
 		// Should we filter the input data?
 		if ($this->_enable_xss === TRUE)
 		{
 			if (strpos($str, "\r") !== FALSE)
 			{
-				$str = str_replace(array("\r\n", "\r"), PHP_EOL, $str);
+				$str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
 			}
 		}
 
 
 		if ($xss_clean === TRUE)
 		{
-			$_security =& load_class('Security');
-			return $_security->xss_clean($this->headers[$index]);
+			return $this->security->xss_clean($this->headers[$index]);
 		}
 
 		return $this->headers[$index];		

system/core/Lang.php

 	function line($line = '')
 	{
 		$line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
+
+		// Because killer robots like unicorns!
+		if ($line === FALSE)
+		{
+			log_message('error', 'Could not find the language line "'.$line.'"');
+		}
+
 		return $line;
 	}
 

system/core/Loader.php

 	{
 		if (is_array($library))
 		{
-			foreach ($library as $read)
+			foreach ($library as $class)
 			{
-				$this->library($read);
+				$this->library($class, $params);
 			}
 
 			return;
 			$params = NULL;
 		}
 
-		if (is_array($library))
-		{
-			foreach ($library as $class)
-			{
-				$this->_ci_load_class($class, $params, $object_name);
-			}
-		}
-		else
-		{
-			$this->_ci_load_class($library, $params, $object_name);
-		}
+		$this->_ci_load_class($library, $params, $object_name);
 	}
 
 	// --------------------------------------------------------------------
 					// We test for both uppercase and lowercase, for servers that
 					// are case-sensitive with regard to file names. Check for environment
 					// first, global next
-					if (file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT))
+					if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT))
 					{
 						include_once($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT);
 						break;
 					}
-					elseif (file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT))
+					elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT))
 					{
 						include_once($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT);
 						break;
 	 */
 	function _ci_autoloader()
 	{
-		include_once(APPPATH.'config/autoload'.EXT);
+		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload'.EXT))
+		{
+			include_once(APPPATH.'config/'.ENVIRONMENT.'/autoload'.EXT);
+		}
+		else
+		{
+			include_once(APPPATH.'config/autoload'.EXT);
+		}
+		
 
 		if ( ! isset($autoload))
 		{
 }
 
 /* End of file Loader.php */
-/* Location: ./system/core/Loader.php */
+/* Location: ./system/core/Loader.php */

system/core/Output.php

  */
 class CI_Output {
 
+	public $parse_exec_vars	= TRUE;	// whether or not to parse variables like {elapsed_time} and {memory_usage}
 	protected $final_output;
 	protected $cache_expiration	= 0;
 	protected $headers			= array();
 	protected $mime_types			= array();
 	protected $enable_profiler	= FALSE;
-	protected $parse_exec_vars	= TRUE;	// whether or not to parse variables like {elapsed_time} and {memory_usage}
-
 	protected $_zlib_oc			= FALSE;
 	protected $_profiler_sections = array();
 
 		$this->_zlib_oc = @ini_get('zlib.output_compression');
 
 		// Get mime types for later
-		include APPPATH.'config/mimes'.EXT;
+		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT))
+		{
+		    include APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT;
+		}
+		else
+		{
+			include APPPATH.'config/mimes'.EXT;
+		}
+
+
 		$this->mime_types = $mimes;
-		
+
 		log_message('debug', "Output Class Initialized");
 	}
 
 	function set_output($output)
 	{
 		$this->final_output = $output;
-		
+
 		return $this;
 	}
 
 		$header = 'Content-Type: '.$mime_type;
 
 		$this->headers[] = array($header, TRUE);
-		
+
 		return $this;
 	}
 

system/core/Router.php

 		}
 
 		// Load the routes.php file.
-		@include(APPPATH.'config/routes'.EXT);
+		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes'.EXT))
+		{
+			include(APPPATH.'config/'.ENVIRONMENT.'/routes'.EXT);
+		}
+		elseif (is_file(APPPATH.'config/routes'.EXT))
+		{
+			include(APPPATH.'config/routes'.EXT);
+		}
+		
 		$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
 		unset($route);
 

system/core/Security.php

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Security Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Security
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/security.html
+ */
+class CI_Security {
+	
+	protected $_xss_hash			= '';
+	protected $_csrf_hash			= '';
+	protected $_csrf_expire			= 7200;  // Two hours (in seconds)
+	protected $_csrf_token_name		= 'ci_csrf_token';
+	protected $_csrf_cookie_name	= 'ci_csrf_token';
+
+	/* never allowed, string replacement */
+	protected $_never_allowed_str = array(
+					'document.cookie'	=> '[removed]',
+					'document.write'	=> '[removed]',
+					'.parentNode'		=> '[removed]',
+					'.innerHTML'		=> '[removed]',
+					'window.location'	=> '[removed]',
+					'-moz-binding'		=> '[removed]',
+					'<!--'				=> '&lt;!--',
+					'-->'				=> '--&gt;',
+					'<![CDATA['			=> '&lt;![CDATA['
+	);
+
+	/* never allowed, regex replacement */
+	protected $_never_allowed_regex = array(
+					"javascript\s*:"			=> '[removed]',
+					"expression\s*(\(|&\#40;)"	=> '[removed]', // CSS and IE
+					"vbscript\s*:"				=> '[removed]', // IE, surprise!
+					"Redirect\s+302"			=> '[removed]'
+	);
+	
+	/**
+	 * Constructor
+	 */
+	public function __construct()
+	{
+		// Append application specific cookie prefix to token name
+		$this->_csrf_cookie_name = (config_item('cookie_prefix')) ? config_item('cookie_prefix').$this->_csrf_token_name : $this->_csrf_token_name;
+
+		// Set the CSRF hash
+		$this->_csrf_set_hash();
+
+		log_message('debug', "Security Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Verify Cross Site Request Forgery Protection
+	 *
+	 * @return	object
+	 */
+	public function csrf_verify()
+	{
+		// If no POST data exists we will set the CSRF cookie
+		if (count($_POST) == 0)
+		{
+			return $this->csrf_set_cookie();
+		}
+
+		// 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]))
+		{
+			$this->csrf_show_error();
+		}
+
+		// Do the tokens match?
+		if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
+		{
+			$this->csrf_show_error();
+		}
+
+		// We kill this since we're done and we don't want to 
+		// polute the _POST array
+		unset($_POST[$this->_csrf_token_name]);
+
+		// Nothing should last forever
+		unset($_COOKIE[$this->_csrf_cookie_name]);
+		$this->_csrf_set_hash();
+		$this->csrf_set_cookie();
+
+		log_message('debug', "CSRF token verified ");
+		
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Cross Site Request Forgery Protection Cookie
+	 *
+	 * @return	object
+	 */
+	public function csrf_set_cookie()
+	{
+		$expire = time() + $this->_csrf_expire;
+		$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
+
+		if ($secure_cookie)
+		{
+			$req = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : FALSE;
+
+			if ( ! $req OR $req == 'off')
+			{
+				return FALSE;
+			}
+		}
+
+		setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
+
+		log_message('debug', "CRSF cookie Set");
+		
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show CSRF Error
+	 *
+	 * @return	void
+	 */
+	public function csrf_show_error()
+	{
+		show_error('The action you have requested is not allowed.');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get CSRF Hash 
+	 *
+	 * Getter Method 
+	 *
+	 * @return 	string 	self::_csrf_hash
+	 */
+	public function get_csrf_hash()
+	{
+		return $this->_csrf_hash;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get CSRF Token Name
+	 *
+	 * Getter Method
+	 *
+	 * @return 	string 	self::csrf_token_name
+	 */
+	public function get_csrf_token_name()
+	{
+		return $this->_csrf_token_name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * XSS Clean
+	 *
+	 * Sanitizes data so that Cross Site Scripting Hacks can be
+	 * prevented.  This function does a fair amount of work but
+	 * it is extremely thorough, designed to prevent even the
+	 * most obscure XSS attempts.  Nothing is ever 100% foolproof,
+	 * of course, but I haven't been able to get anything passed
+	 * the filter.
+	 *
+	 * Note: This function should only be used to deal with data
+	 * upon submission.  It's not something that should
+	 * be used for general runtime processing.
+	 *
+	 * This function was based in part on some code and ideas I
+	 * got from Bitflux: http://channel.bitflux.ch/wiki/XSS_Prevention
+	 *
+	 * To help develop this script I used this great list of
+	 * vulnerabilities along with a few other hacks I've
+	 * harvested from examining vulnerabilities in other programs:
+	 * http://ha.ckers.org/xss.html
+	 *
+	 * @param	mixed	string or array
+	 * @return	string
+	 */
+	public function xss_clean($str, $is_image = FALSE)
+	{
+		/*
+		 * Is the string an array?
+		 *
+		 */
+		if (is_array($str))
+		{
+			while (list($key) = each($str))
+			{
+				$str[$key] = $this->xss_clean($str[$key]);
+			}
+
+			return $str;
+		}
+
+		/*
+		 * Remove Invisible Characters
+		 */
+		$str = remove_invisible_characters($str);
+
+		// Validate Entities in URLs
+		$str = $this->_validate_entities($str);
+
+		/*
+		 * URL Decode
+		 *
+		 * Just in case stuff like this is submitted:
+		 *
+		 * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
+		 *
+		 * Note: Use rawurldecode() so it does not remove plus signs
+		 *
+		 */
+		$str = rawurldecode($str);
+
+		/*
+		 * Convert character entities to ASCII
+		 *
+		 * This permits our tests below to work reliably.
+		 * We only convert entities that are within tags since
+		 * these are the ones that will pose security problems.
+		 *
+		 */
+
+		$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
+	
+		$str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_decode_entity'), $str);
+
+		/*
+		 * Remove Invisible Characters Again!
+		 */
+		$str = remove_invisible_characters($str);
+
+		/*
+		 * Convert all tabs to spaces
+		 *
+		 * This prevents strings like this: ja	vascript
+		 * NOTE: we deal with spaces between characters later.
+		 * NOTE: preg_replace was found to be amazingly slow here on 
+		 * large blocks of data, so we use str_replace.
+		 */
+
+		if (strpos($str, "\t") !== FALSE)
+		{
+			$str = str_replace("\t", ' ', $str);
+		}
+
+		/*
+		 * Capture converted string for later comparison
+		 */
+		$converted_string = $str;
+
+		// Remove Strings that are never allowed
+		$str = $this->_do_never_allowed($str);
+
+		/*
+		 * Makes PHP tags safe
+		 *
+		 * Note: XML tags are inadvertently replaced too:
+		 *
+		 * <?xml
+		 *
+		 * But it doesn't seem to pose a problem.
+		 */
+		if ($is_image === TRUE)
+		{
+			// Images have a tendency to have the PHP short opening and 
+			// closing tags every so often so we skip those and only 
+			// do the long opening tags.
+			$str = preg_replace('/<\?(php)/i', "&lt;?\\1", $str);
+		}
+		else
+		{
+			$str = str_replace(array('<?', '?'.'>'),  array('&lt;?', '?&gt;'), $str);
+		}
+
+		/*
+		 * Compact any exploded words
+		 *
+		 * This corrects words like:  j a v a s c r i p t
+		 * These words are compacted back to their correct state.
+		 */
+		$words = array(
+				'javascript', 'expression', 'vbscript', 'script', 
+				'applet', 'alert', 'document', 'write', 'cookie', 'window'
+			);
+			
+		foreach ($words as $word)
+		{
+			$temp = '';
+
+			for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)
+			{
+				$temp .= substr($word, $i, 1)."\s*";
+			}
+
+			// We only want to do this when it is followed by a non-word character
+			// That way valid stuff like "dealer to" does not become "dealerto"
+			$str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
+		}
+
+		/*
+		 * Remove disallowed Javascript in links or img tags
+		 * We used to do some version comparisons and use of stripos for PHP5, 
+		 * but it is dog slow compared to these simplified non-capturing 
+		 * preg_match(), especially if the pattern exists in the string
+		 */
+		do
+		{
+			$original = $str;
+
+			if (preg_match("/<a/i", $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);
+			}
+
+			if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))
+			{
+				$str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);
+			}
+		}
+		while($original != $str);
+
+		unset($original);
+
+		// Remove evil attributes such as style, onclick and xmlns
+		$str = $this->_remove_evil_attributes($str, $is_image);
+
+		/*
+		 * Sanitize naughty HTML elements
+		 *
+		 * If a tag containing any of the words in the list
+		 * below is found, the tag gets converted to entities.
+		 *
+		 * So this: <blink>
+		 * Becomes: &lt;blink&gt;
+		 */
+		$naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
+		$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
+
+		/*
+		 * Sanitize naughty scripting elements
+		 *
+		 * Similar to above, only instead of looking for
+		 * tags it looks for PHP and JavaScript commands
+		 * that are disallowed.  Rather than removing the
+		 * code, it simply converts the parenthesis to entities
+		 * rendering the code un-executable.
+		 *
+		 * For example:	eval('some code')
+		 * Becomes:		eval&#40;'some code'&#41;
+		 */
+		$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);
+
+
+		// Final clean up
+		// This adds a bit of extra precaution in case
+		// something got through the above filters
+		$str = $this->_do_never_allowed($str);
+
+		/*
+		 * Images are Handled in a Special Way
+		 * - Essentially, we want to know that after all of the character 
+		 * conversion is done whether any unwanted, likely XSS, code was found.  
+		 * If not, we return TRUE, as the image is clean.
+		 * However, if the string post-conversion does not matched the 
+		 * string post-removal of XSS, then it fails, as there was unwanted XSS 
+		 * code found and removed/changed during processing.
+		 */
+
+		if ($is_image === TRUE)
+		{
+			return ($str == $converted_string) ? TRUE: FALSE;
+		}
+
+		log_message('debug', "XSS Filtering completed");
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Random Hash for protecting URLs
+	 *
+	 * @return	string
+	 */
+	public function xss_hash()
+	{
+		if ($this->_xss_hash == '')
+		{
+			if (phpversion() >= 4.2)
+			{
+				mt_srand();
+			}
+			else
+			{
+				mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);
+			}
+
+			$this->_xss_hash = md5(time() + mt_rand(0, 1999999999));
+		}
+
+		return $this->_xss_hash;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * HTML Entities Decode
+	 *
+	 * This function is a replacement for html_entity_decode()
+	 *
+	 * In some versions of PHP the native function does not work
+	 * when UTF-8 is the specified character set, so this gives us
+	 * a work-around.  More info here:
+	 * http://bugs.php.net/bug.php?id=25670
+	 *
+	 * NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the
+	 * character set, and the PHP developers said they were not back porting the
+	 * fix to versions other than PHP 5.x.
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	public function entity_decode($str, $charset='UTF-8')
+	{
+		if (stristr($str, '&') === FALSE) return $str;
+
+		// The reason we are not using html_entity_decode() by itself is because
+		// while it is not technically correct to leave out the semicolon
+		// at the end of an entity most browsers will still interpret the entity
+		// correctly.  html_entity_decode() does not convert entities without
+		// semicolons, so we are left with our own little solution here. Bummer.
+
+		if (function_exists('html_entity_decode') && 
+			(strtolower($charset) != 'utf-8'))
+		{
+			$str = html_entity_decode($str, ENT_COMPAT, $charset);
+			$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
+			return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
+		}
+
+		// Numeric Entities
+		$str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str);
+		$str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str);
+
+		// Literal Entities - Slightly slow so we do another check
+		if (stristr($str, '&') === FALSE)
+		{
+			$str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES)));
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Filename Security
+	 *
+	 * @param	string
+	 * @return	string
+	 */
+	public function sanitize_filename($str, $relative_path = FALSE)
+	{
+		$bad = array(
+						"../",
+						"<!--",
+						"-->",
+						"<",
+						">",
+						"'",
+						'"',
+						'&',
+						'$',
+						'#',
+						'{',
+						'}',
+						'[',
+						']',
+						'=',
+						';',
+						'?',
+						"%20",
+						"%22",
+						"%3c",		// <
+						"%253c",	// <
+						"%3e",		// >
+						"%0e",		// >
+						"%28",		// (
+						"%29",		// )
+						"%2528",	// (
+						"%26",		// &
+						"%24",		// $
+						"%3f",		// ?
+						"%3b",		// ;
+						"%3d"		// =
+					);
+		
+		if ( ! $relative_path)
+		{
+			$bad[] = './';
+			$bad[] = '/';
+		}
+
+		$str = remove_invisible_characters($str, FALSE);
+		return stripslashes(str_replace($bad, '', $str));
+	}
+
+	// ----------------------------------------------------------------
+
+	/**
+	 * Compact Exploded Words
+	 *
+	 * Callback function for xss_clean() to remove whitespace from
+	 * things like j a v a s c r i p t
+	 *
+	 * @param	type
+	 * @return	type
+	 */
+	protected function _compact_exploded_words($matches)
+	{
+		return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
+	}
+
+	// --------------------------------------------------------------------
+	
+	/*
+	 * Remove Evil HTML Attributes (like evenhandlers and style)
+	 *
+	 * It removes the evil attribute and either:
+	 * 	- Everything up until a space
+	 *		For example, everything between the pipes:
+	 *		<a |style=document.write('hello');alert('world');| class=link>
+	 * 	- Everything inside the quotes 
+	 *		For example, everything between the pipes:
+	 *		<a |style="document.write('hello'); alert('world');"| class="link">
+	 *
+	 * @param string $str The string to check
+	 * @param boolean $is_image TRUE if this is an image
+	 * @return string The string with the evil attributes removed
+	 */
+	protected function _remove_evil_attributes($str, $is_image)
+	{
+		// All javascript event handlers (e.g. onload, onclick, onmouseover), style, and xmlns
+		$evil_attributes = array('on\w*', 'style', 'xmlns');
+
+		if ($is_image === TRUE)
+		{
+			/*
+			 * Adobe Photoshop puts XML metadata into JFIF images, 
+			 * including namespacing, so we have to allow this for images.
+			 */
+			unset($evil_attributes[array_search('xmlns', $evil_attributes)]);
+		}
+		
+		do {
+			$str = preg_replace(
+				"#<(/?[^><]+?)([^A-Za-z\-])(".implode('|', $evil_attributes).")(\s*=\s*)([\"][^>]*?[\"]|[\'][^>]*?[\']|[^>]*?)([\s><])([><]*)#i",
+				"<$1$6",
+				$str, -1, $count
+			);
+		} while ($count);
+		
+		return $str;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sanitize Naughty HTML
+	 *
+	 * Callback function for xss_clean() to remove naughty HTML elements
+	 *
+	 * @param	array
+	 * @return	string
+	 */
+	protected function _sanitize_naughty_html($matches)
+	{
+		// encode opening brace
+		$str = '&lt;'.$matches[1].$matches[2].$matches[3];
+
+		// encode captured opening or closing brace to prevent recursive vectors
+		$str .= str_replace(array('>', '<'), array('&gt;', '&lt;'), 
+							$matches[4]);
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * JS Link Removal
+	 *
+	 * Callback function for xss_clean() to sanitize links
+	 * This limits the PCRE backtracks, making it more performance friendly
+	 * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
+	 * PHP 5.2+ on link-heavy strings
+	 *
+	 * @param	array
+	 * @return	string
+	 */
+	protected function _js_link_removal($match)
+	{
+		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
+		
+		return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * JS Image Removal
+	 *
+	 * Callback function for xss_clean() to sanitize image tags
+	 * This limits the PCRE backtracks, making it more performance friendly
+	 * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
+	 * PHP 5.2+ on image tag heavy strings
+	 *
+	 * @param	array
+	 * @return	string
+	 */
+	protected function _js_img_removal($match)
+	{
+		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
+		
+		return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Attribute Conversion
+	 *
+	 * Used as a callback for XSS Clean
+	 *
+	 * @param	array
+	 * @return	string
+	 */
+	protected function _convert_attribute($match)
+	{
+		return str_replace(array('>', '<', '\\'), array('&gt;', '&lt;', '\\\\'), $match[0]);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Filter Attributes
+	 *
+	 * Filters tag attributes for consistency and safety
+	 *
+	 * @param	string
+	 * @return	string
+	 */
+	protected function _filter_attributes($str)
+	{
+		$out = '';
+
+		if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))
+		{
+			foreach ($matches[0] as $match)
+			{
+				$out .= preg_replace("#/\*.*?\*/#s", '', $match);
+			}
+		}
+
+		return $out;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * HTML Entity Decode Callback
+	 *
+	 * Used as a callback for XSS Clean
+	 *
+	 * @param	array
+	 * @return	string
+	 */
+	protected function _decode_entity($match)
+	{
+		return $this->entity_decode($match[0], strtoupper(config_item('charset')));
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Validate URL entities
+	 *
+	 * Called by xss_clean()
+	 *
+	 * @param 	string	
+	 * @return 	string
+	 */
+	protected function _validate_entities($str)
+	{
+		/*
+		 * Protect GET variables in URLs
+		 */
+		
+		 // 901119URL5918AMP18930PROTECT8198
+		
+		$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str);
+
+		/*
+		 * Validate standard character entities
+		 *
+		 * Add a semicolon if missing.  We do this to enable
+		 * the conversion of entities to ASCII later.
+		 *
+		 */
+		$str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str);
+
+		/*
+		 * Validate UTF16 two byte encoding (x00)
+		 *
+		 * Just as above, adds a semicolon if missing.
+		 *
+		 */
+		$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);
+
+		/*
+		 * Un-Protect GET variables in URLs
+		 */
+		$str = str_replace($this->xss_hash(), '&', $str);
+		
+		return $str;
+	}
+
+	// ----------------------------------------------------------------------
+
+	/**
+	 * Do Never Allowed
+	 *
+	 * A utility function for xss_clean()
+	 *
+	 * @param 	string
+	 * @return 	string
+	 */
+	protected function _do_never_allowed($str)
+	{
+		foreach ($this->_never_allowed_str as $key => $val)
+		{
+			$str = str_replace($key, $val, $str);
+		}
+
+		foreach ($this->_never_allowed_regex as $key => $val)
+		{
+			$str = preg_replace("#".$key."#i", $val, $str);
+		}
+		
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Cross Site Request Forgery Protection Cookie
+	 *
+	 * @return	string
+	 */
+	protected function _csrf_set_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] != '')
+			{
+				return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
+			}
+			
+			return $this->_csrf_hash = md5(uniqid(rand(), TRUE));
+		}
+
+		return $this->_csrf_hash;
+	}
+
+}
+// END Security Class
+
+/* End of file Security.php */
+/* Location: ./system/libraries/Security.php */

system/core/URI.php

 			// Is the request coming from the command line?
 			if (defined('STDIN'))
 			{
-				$this->uri_string = $this->_parse_cli_args();
+				$this->_set_uri_string($this->_parse_cli_args());
 				return;
 			}
 
 			// Let's try the REQUEST_URI first, this will work in most situations
 			if ($uri = $this->_detect_uri())
 			{
-				$this->uri_string = $uri;
+				$this->_set_uri_string($uri);
 				return;
 			}
 
 			$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
 			if (trim($path, '/') != '' && $path != "/".SELF)
 			{
-				$this->uri_string = $path;
+				$this->_set_uri_string($path);
 				return;
 			}
 
 			$path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
 			if (trim($path, '/') != '')
 			{
-				$this->uri_string = $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), '/') != '')
 			{
-				$this->uri_string = key($_GET);
+				$this->_set_uri_string(key($_GET));
 				return;
 			}
 
 			// We've exhausted all our options...
 			$this->uri_string = '';
-		}
-		else
-		{
-			$uri = strtoupper($this->config->item('uri_protocol'));
-
-			if ($uri == 'REQUEST_URI')
-			{
-				$this->uri_string = $this->_detect_uri();
-				return;
-			}
-			elseif ($uri == 'CLI')
-			{
-				$this->uri_string = $this->_parse_cli_args();
-				return;
-			}
-
-			$this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
+			return;
 		}
 
+		$uri = strtoupper($this->config->item('uri_protocol'));
+
+		if ($uri == 'REQUEST_URI')
+		{
+			$this->_set_uri_string($this->_detect_uri());
+			return;
+		}
+		elseif ($uri == 'CLI')
+		{
+			$this->_set_uri_string($this->_parse_cli_args());
+			return;
+		}
+
+		$path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
+		$this->_set_uri_string($path);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set the URI String
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _set_uri_string($str)
+	{
+		// Filter out control characters
+		$str = remove_invisible_characters($str, FALSE);
+		
 		// If the URI contains only a slash we'll kill it
-		if ($this->uri_string == '/')
-		{
-			$this->uri_string = '';
-		}
+		$this->uri_string = ($str == '/') ? '' : $str;
 	}
 
 	// --------------------------------------------------------------------

system/core/Utf8.php

 	 */
 	function safe_ascii_for_xml($str)
 	{
-		return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $str);
+		return remove_invisible_characters($str, FALSE);
 	}
 
 	// --------------------------------------------------------------------

system/database/DB.php

 	// Load the DB config file if a DSN string wasn't passed
 	if (is_string($params) AND strpos($params, '://') === FALSE)
 	{
-		
-		$file_path = APPPATH.'config/'.ENVIRONMENT.'/database'.EXT;
-		
-		if ( ! file_exists($file_path))
+		// Is the config file in the environment folder?
+		if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database'.EXT))
 		{
-			log_message('debug', 'Database config for '.ENVIRONMENT.' environment is not found. Trying global config.');
-			$file_path = APPPATH.'config/database'.EXT;
-			
-			if ( ! file_exists($file_path))
+			if ( ! file_exists($file_path = APPPATH.'config/database'.EXT))
 			{
-				continue;
+				show_error('The configuration file database'.EXT.' does not exist.');
 			}
 		}
 		

system/database/DB_active_rec.php

 
 		if ($query->num_rows() == 0)
 		{
-			return '0';
+			return 0;
 		}
 
 		$row = $query->row();
-		return $row->numrows;
+		return (int) $row->numrows;
 	}
 
 	// --------------------------------------------------------------------

system/database/drivers/mssql/mssql_driver.php

 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(	array('%', '_', $this->_like_escape_chr),
-								array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
-								$str);
+			$str = str_replace(
+				array($this->_like_escape_chr, '%', '_'),
+				array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+				$str
+			);
 		}
 
 		return $str;

system/helpers/download_helper.php

 		$extension = end($x);
 
 		// Load the mime types
-		@include(APPPATH.'config/mimes'.EXT);
+		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT))
+		{
+			include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT);
+		}
+		elseif (is_file(APPPATH.'config/mimes'.EXT))
+		{
+			include(APPPATH.'config/mimes'.EXT);
+		}
 
 		// Set a default mime if we can't find it
 		if ( ! isset($mimes[$extension]))

system/helpers/file_helper.php

 
 		if ( ! is_array($mimes))
 		{
-			if ( ! require_once(APPPATH.'config/mimes.php'))
+			if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT))
+			{
+				include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT);
+			}
+			elseif (is_file(APPPATH.'config/mimes'.EXT))
+			{
+				include(APPPATH.'config/mimes'.EXT);
+			}
+
+			if ( ! is_array($mimes))
 			{
 				return FALSE;
 			}

system/helpers/form_helper.php

 			$attributes = 'method="post"';
 		}
 
+		// If an action is not a full URL then turn it into one
 		if ($action && strpos($action, '://') === FALSE)
 		{
 			$action = $CI->config->site_url($action);
 		}
 
+		// If no action is provided then set to the current url
+		$action OR $action = $CI->config->site_url($CI->uri->uri_string());
+
 		$form = '<form action="'.$action.'"';
 
 		$form .= _attributes_to_string($attributes, TRUE);

system/helpers/html_helper.php

 
 		if ( ! is_array($_doctypes))
 		{
-			if ( ! require_once(APPPATH.'config/doctypes.php'))
+			if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/doctypes'.EXT))
+			{
+				include(APPPATH.'config/'.ENVIRONMENT.'/doctypes'.EXT);
+			}
+			elseif (is_file(APPPATH.'config/doctypes'.EXT))
+			{
+				include(APPPATH.'config/doctypes'.EXT);
+			}
+
+			if ( ! is_array($_doctypes))
 			{
 				return FALSE;
 			}

system/helpers/security_helper.php

 /**
  * Hash encode a string
  *
- * This is simply an alias for do_hash()
- * dohash() is now deprecated
- */
-if ( ! function_exists('dohash'))
-{
-	function dohash($str, $type = 'sha1')
-	{
-		return do_hash($str, $type);
-	}
-}
-
-// --------------------------------------------------------------------
-
-/**
- * Hash encode a string
- *
  * @access	public
  * @param	string
  * @return	string
 	{
 		if ($type == 'sha1')
 		{
-			if ( ! function_exists('sha1'))
-			{
-				if ( ! function_exists('mhash'))
-				{
-					require_once(BASEPATH.'libraries/Sha1'.EXT);
-					$SH = new CI_SHA;
-					return $SH->generate($str);
-				}
-				else
-				{
-					return bin2hex(mhash(MHASH_SHA1, $str));
-				}
-			}
-			else
-			{
-				return sha1($str);
-			}
+			return sha1($str);
 		}
 		else
 		{

system/helpers/smiley_helper.php

 {
 	function _get_smiley_array()
 	{
-		if ( ! file_exists(APPPATH.'config/smileys'.EXT))
+		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys'.EXT))
 		{
-			return FALSE;
+		    include(APPPATH.'config/'.ENVIRONMENT.'/smileys'.EXT);
+		}
+		elseif (file_exists(APPPATH.'config/smileys'.EXT))
+		{
+			include(APPPATH.'config/smileys'.EXT);
+		}
+		
+		if (isset($smileys) AND is_array($smileys))
+		{
+			return $smileys;
 		}
 
-		include(APPPATH.'config/smileys'.EXT);
-
-		if ( ! isset($smileys) OR ! is_array($smileys))
-		{
-			return FALSE;
-		}
-
-		return $smileys;
+		return FALSE;
 	}
 }
 

system/helpers/text_helper.php

 {
 	function convert_accented_characters($str)
 	{
-		if ( ! file_exists(APPPATH.'config/foreign_chars'.EXT))
+		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars'.EXT))
 		{
-			return $str;
+			include(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars'.EXT);
 		}
-
-		include APPPATH.'config/foreign_chars'.EXT;
+		elseif (is_file(APPPATH.'config/foreign_chars'.EXT))
+		{
+			include(APPPATH.'config/foreign_chars'.EXT);
+		}
 
 		if ( ! isset($foreign_characters))
 		{

system/helpers/typography_helper.php

 {
 	function entity_decode($str, $charset='UTF-8')
 	{
-		$CI =& get_instance();
-		$CI->load->library('security');
-		return $CI->security->entity_decode($str, $charset);
+		global $SEC;
+		return $SEC->entity_decode($str, $charset);
 	}
 }
 

system/language/english/form_validation_lang.php

 $lang['matches']			= "The %s field does not match the %s field.";
 $lang['is_natural']			= "The %s field must contain only positive numbers.";
 $lang['is_natural_no_zero']	= "The %s field must contain a number greater than zero.";
+$lang['decimal']			= "The %s field must contain a decimal number.";
+$lang['less_than']			= "The %s field must contain a number less than %s.";
+$lang['greater_than']		= "The %s field must contain a number greater than %s.";
 
 
 /* End of file form_validation_lang.php */

system/language/english/ftp_lang.php

 <?php
 
-$lang['ftp_no_connection']			= "Unable to locate a valid connection ID.  Please make sure you are connected before peforming any file routines.";
+$lang['ftp_no_connection']			= "Unable to locate a valid connection ID. Please make sure you are connected before peforming any file routines.";
 $lang['ftp_unable_to_connect']		= "Unable to connect to your FTP server using the supplied hostname.";
-$lang['ftp_unable_to_login']		= "Unable to login to your FTP server.  Please check your username and password.";
+$lang['ftp_unable_to_login']		= "Unable to login to your FTP server. Please check your username and password.";
 $lang['ftp_unable_to_makdir']		= "Unable to create the directory you have specified.";
 $lang['ftp_unable_to_changedir']	= "Unable to change directories.";
-$lang['ftp_unable_to_chmod']		= "Unable to set file permissions.  Please check your path.  Note: This feature is only available in PHP 5 or higher.";
-$lang['ftp_unable_to_upload']		= "Unable to upload the specified file.  Please check your path.";
-$lang['ftp_unable_to_download']		= "Unable to download the specified file.  Please check your path.";
-$lang['ftp_no_source_file']			= "Unable to locate the source file.  Please check your path.";
+$lang['ftp_unable_to_chmod']		= "Unable to set file permissions. Please check your path. Note: This feature is only available in PHP 5 or higher.";
+$lang['ftp_unable_to_upload']		= "Unable to upload the specified file. Please check your path.";
+$lang['ftp_unable_to_download']		= "Unable to download the specified file. Please check your path.";
+$lang['ftp_no_source_file']			= "Unable to locate the source file. Please check your path.";
 $lang['ftp_unable_to_rename']		= "Unable to rename the file.";
 $lang['ftp_unable_to_delete']		= "Unable to delete the file.";
-$lang['ftp_unable_to_move']			= "Unable to move the file.  Please make sure the destination directory exists.";
+$lang['ftp_unable_to_move']			= "Unable to move the file. Please make sure the destination directory exists.";
 
 
 /* End of file ftp_lang.php */

system/libraries/Cache/Cache.php

  * @author		ExpressionEngine Dev Team
  * @link		
  */
-class Cache extends CI_Driver_Library {
+class CI_Cache extends CI_Driver_Library {
 	
 	protected $valid_drivers 	= array(
-				'cache_apc', 'cache_file', 'cache_memcached', 'cache_dummy'
-		);
+		'cache_apc', 'cache_file', 'cache_memcached', 'cache_dummy'
+	);
 
 	protected $_cache_path		= NULL;		// Path of cache files (if file-based cache)
 	protected $_adapter			= 'dummy';

system/libraries/Cache/drivers/Cache_apc.php

  * @link		
  */
 
-class Cache_apc extends CI_Driver {
+class CI_Cache_apc extends CI_Driver {
 
 	/**
 	 * Get 

system/libraries/Cache/drivers/Cache_dummy.php

  * @link		
  */
 
-class Cache_dummy extends CI_Driver {
+class CI_Cache_dummy extends CI_Driver {
 
 	/**
 	 * Get 

system/libraries/Cache/drivers/Cache_file.php

  * @link		
  */
 
-class Cache_file extends CI_Driver {
+class CI_Cache_file extends CI_Driver {
 
 	protected $_cache_path;
 

system/libraries/Cache/drivers/Cache_memcached.php

  * @link		
  */
 
-class Cache_memcached extends CI_Driver {
+class CI_Cache_memcached extends CI_Driver {
 
 	private $_memcached;	// Holds the memcached object
 

system/libraries/Driver.php

 		// The class will be prefixed with the parent lib
 		$child_class = $this->lib_name.'_'.$child;
 
-		if (in_array(strtolower($child_class), array_map('strtolower', $this->valid_drivers)))
+		// Remove the CI_ prefix and lowercase
+		$lib_name = strtolower(preg_replace('/^CI_/', '', $this->lib_name));
+		$driver_name = strtolower(preg_replace('/^CI_/', '', $child_class));
+
+		if (in_array($driver_name, array_map('strtolower', $this->valid_drivers)))
 		{
 			// check and see if the driver is in a separate file
 			if ( ! class_exists($child_class))
 				// check application path first
 				foreach (array(APPPATH, BASEPATH) as $path)
 				{
-					// and check for case sensitivity of both the parent and child libs
-					foreach (array(ucfirst($this->lib_name), strtolower($this->lib_name)) as $lib)
+					// loves me some nesting!
+					foreach (array(ucfirst($driver_name), $driver_name) as $class)
 					{
-						// loves me some nesting!
-						foreach (array(ucfirst($child_class), strtolower($child_class)) as $class)
+						$filepath = $path.'libraries/'.$lib_name.'/drivers/'.$class.EXT;
+
+						if (file_exists($filepath))
 						{
-							$filepath = $path.'libraries/'.$this->lib_name.'/drivers/'.$child_class.EXT;
-
-							if (file_exists($filepath))
-							{
-								include_once $filepath;
-								break;
-							}
+							include_once $filepath;
+							break;
 						}
 					}
 				}

system/libraries/Form_validation.php

 	 */
 	function xss_clean($str)
 	{
-		if ( ! isset($this->CI->security))
-		{
-			$this->CI->load->library('security');
-		}
-
 		return $this->CI->security->xss_clean($str);
 	}
 

system/libraries/Javascript.php

 		}
 		elseif (is_string($result) OR $is_key)
 		{
-			return '"'.str_replace(array('\\', "\t", "\n", "\r", '"'), array('\\\\', '\\t', '\\n', "\\r", '\"'), $result).'"';
+			return '"'.str_replace(array('\\', "\t", "\n", "\r", '"', '/'), array('\\\\', '\\t', '\\n', "\\r", '\"', '\/'), $result).'"';			
 		}
 		elseif (is_scalar($result))
 		{

system/libraries/Security.php

-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP 5.1.6 or newer
- *
- * @package		CodeIgniter
- * @author		ExpressionEngine Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
- * @license		http://codeigniter.com/user_guide/license.html
- * @link		http://codeigniter.com
- * @since		Version 1.0
- * @filesource
- */
-
-// ------------------------------------------------------------------------
-
-/**
- * Security Class
- *
- * @package		CodeIgniter
- * @subpackage	Libraries
- * @category	Security
- * @author		ExpressionEngine Dev Team
- * @link		http://codeigniter.com/user_guide/libraries/sessions.html
- */
-class CI_Security {
-
-	public $xss_hash			= '';
-	public $csrf_hash			= '';
-	public $csrf_expire			= 7200;  // Two hours (in seconds)
-	public $csrf_token_name		= 'ci_csrf_token';
-	public $csrf_cookie_name	= 'ci_csrf_token';
-
-	/* never allowed, string replacement */
-	public $never_allowed_str = array(
-									'document.cookie'	=> '[removed]',
-									'document.write'	=> '[removed]',
-									'.parentNode'		=> '[removed]',
-									'.innerHTML'		=> '[removed]',
-									'window.location'	=> '[removed]',
-									'-moz-binding'		=> '[removed]',
-									'<!--'				=> '&lt;!--',
-									'-->'				=> '--&gt;',
-									'<![CDATA['			=> '&lt;![CDATA['
-									);
-	/* never allowed, regex replacement */
-	public $never_allowed_regex = array(
-										"javascript\s*:"			=> '[removed]',
-										"expression\s*(\(|&\#40;)"	=> '[removed]', // CSS and IE
-										"vbscript\s*:"				=> '[removed]', // IE, surprise!
-										"Redirect\s+302"			=> '[removed]'
-									);
-
-	public function __construct()
-	{
-		$this->csrf_token_name = (config_item('csrf_token_name')) ? config_item('csrf_token_name') : 'csrf_token_name';
-		$this->csrf_cookie_name = (config_item('csrf_cookie_name')) ? config_item('csrf_cookie_name') : 'csrf_cookie_name';
-		$this->csrf_expire = (config_item('csrf_expire')) ? config_item('csrf_expire') : 7200;
-
-		// Append application specific cookie prefix to token name
-		$this->csrf_cookie_name = (config_item('cookie_prefix')) ? config_item('cookie_prefix').$this->csrf_token_name : $this->csrf_token_name;
-
-		// Set the CSRF hash
-		$this->_csrf_set_hash();
-
-		log_message('debug', "Security Class Initialized");
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Verify Cross Site Request Forgery Protection
-	 *
-	 * @access	public
-	 * @return	null
-	 */
-	public function csrf_verify()
-	{
-		// If no POST data exists we will set the CSRF cookie
-		if (count($_POST) == 0)
-		{
-			return $this->csrf_set_cookie();
-		}
-
-		// 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]))
-		{
-			$this->csrf_show_error();
-		}
-
-		// Do the tokens match?
-		if ($_POST[$this->csrf_token_name] != $_COOKIE[$this->csrf_cookie_name])
-		{
-			$this->csrf_show_error();
-		}
-
-		// We kill this since we're done and we don't want to polute the _POST array
-		unset($_POST[$this->csrf_token_name]);
-
-		// Nothing should last forever
-		unset($_COOKIE[$this->csrf_cookie_name]);
-		$this->_csrf_set_hash();
-		$this->csrf_set_cookie();
-
-		log_message('debug', "CSRF token verified ");
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Set Cross Site Request Forgery Protection Cookie
-	 *
-	 * @access	public
-	 * @return	null
-	 */
-	public function csrf_set_cookie()
-	{
-		$expire = time() + $this->csrf_expire;
-		$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
-
-		setcookie($this->csrf_cookie_name, $this->csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
-
-		log_message('debug', "CRSF cookie Set");
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Set Cross Site Request Forgery Protection Cookie
-	 *
-	 * @access	private
-	 * @return	null
-	 */
-	private function _csrf_set_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]) AND $_COOKIE[$this->csrf_cookie_name] != '')
-			{
-				$this->csrf_hash = $_COOKIE[$this->csrf_cookie_name];
-			}
-			else
-			{
-				$this->csrf_hash = md5(uniqid(rand(), TRUE));
-			}
-		}
-
-		return $this->csrf_hash;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Show CSRF Error
-	 *
-	 * @access	public
-	 * @return	null
-	 */
-	public function csrf_show_error()
-	{
-		show_error('The action you have requested is not allowed.');
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * XSS Clean
-	 *
-	 * Sanitizes data so that Cross Site Scripting Hacks can be
-	 * prevented.  This function does a fair amount of work but
-	 * it is extremely thorough, designed to prevent even the
-	 * most obscure XSS attempts.  Nothing is e