201007 file upload bug fix
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 8bdb4be..c94e4d4 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -26,31 +26,34 @@
  */
 class CI_Upload {
 	
-	var $max_size		= 0;
-	var $max_width		= 0;
-	var $max_height		= 0;
-	var $max_filename	= 0;
-	var $allowed_types	= "";
-	var $file_temp		= "";
-	var $file_name		= "";
-	var $orig_name		= "";
-	var $file_type		= "";
-	var $file_size		= "";
-	var $file_ext		= "";
-	var $upload_path	= "";
-	var $overwrite		= FALSE;
-	var $encrypt_name	= FALSE;
-	var $is_image		= FALSE;
-	var $image_width	= '';
-	var $image_height	= '';
-	var $image_type		= '';
-	var $image_size_str	= '';
-	var $error_msg		= array();
-	var $mimes			= array();
-	var $remove_spaces	= TRUE;
-	var $xss_clean		= FALSE;
-	var $temp_prefix	= "temp_file_";
-		
+	var $max_size				= 0;
+	var $max_width				= 0;
+	var $max_height				= 0;
+	var $max_filename			= 0;
+	var $allowed_types			= "";
+	var $file_temp				= "";
+	var $file_name				= "";
+	var $orig_name				= "";
+	var $file_type				= "";
+	var $file_size				= "";
+	var $file_ext				= "";
+	var $upload_path			= "";
+	var $overwrite				= FALSE;
+	var $encrypt_name			= FALSE;
+	var $is_image				= FALSE;
+	var $image_width			= '';
+	var $image_height			= '';
+	var $image_type				= '';
+	var $image_size_str			= '';
+	var $error_msg				= array();
+	var $mimes					= array();
+	var $remove_spaces			= TRUE;
+	var $xss_clean				= FALSE;
+	var $temp_prefix			= "temp_file_";
+	var $client_name			= '';
+	
+	var $_file_name_override	= ''; //@PHP4 (should be private)
+	
 	/**
 	 * Constructor
 	 *
@@ -75,6 +78,7 @@
 	 * @param	array
 	 * @return	void
 	 */	
+
 	function initialize($config = array())
 	{
 		$defaults = array(
@@ -101,7 +105,8 @@
 							'mimes'				=> array(),
 							'remove_spaces'		=> TRUE,
 							'xss_clean'			=> FALSE,
-							'temp_prefix'		=> "temp_file_"
+							'temp_prefix'		=> "temp_file_",
+							'client_name'		=> ''
 						);	
 	
 	
@@ -124,6 +129,10 @@
 				$this->$key = $val;
 			}
 		}
+		
+		// if a file_name was provided in the config, use it instead of the user input
+		// supplied file name for all uploads until initialized again
+		$this->_file_name_override = $this->file_name;
 	}
 	
 	// --------------------------------------------------------------------
@@ -185,20 +194,16 @@
 			return FALSE;
 		}
 
+
 		// Set the uploaded data as class variables
 		$this->file_temp = $_FILES[$field]['tmp_name'];		
-		$this->file_name = $this->_prep_filename($_FILES[$field]['name']);
-		$this->file_size = $_FILES[$field]['size'];		
+		$this->file_size = $_FILES[$field]['size'];	
 		$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
 		$this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
-		$this->file_ext	 = $this->get_extension($_FILES[$field]['name']);
+		$this->file_name = $this->_prep_filename($_FILES[$field]['name']);
+		$this->file_ext	 = $this->get_extension($this->file_name);
+		$this->client_name = $this->file_name;
 		
-		// Convert the file size to kilobytes
-		if ($this->file_size > 0)
-		{
-			$this->file_size = round($this->file_size/1024, 2);
-		}
-
 		// Is the file type allowed to be uploaded?
 		if ( ! $this->is_allowed_filetype())
 		{
@@ -206,6 +211,25 @@
 			return FALSE;
 		}
 
+		// if we're overriding, let's now make sure the new name and type is allowed
+		if ($this->_file_name_override != '')
+		{
+			$this->file_name = $this->_prep_filename($this->_file_name_override);
+			$this->file_ext  = $this->get_extension($this->file_name);
+
+			if ( ! $this->is_allowed_filetype(TRUE))
+			{
+				$this->set_error('upload_invalid_filetype');
+				return FALSE;				
+			}
+		}
+		
+		// Convert the file size to kilobytes
+		if ($this->file_size > 0)
+		{
+			$this->file_size = round($this->file_size/1024, 2);
+		}
+
 		// Is the file size within the allowed maximum?
 		if ( ! $this->is_allowed_filesize())
 		{
@@ -255,6 +279,21 @@
 		}
 
 		/*
+		 * Run the file through the XSS hacking filter
+		 * This helps prevent malicious code from being
+		 * embedded within a file.  Scripts can easily
+		 * be disguised as images or other file types.
+		 */
+		if ($this->xss_clean)
+		{
+			if ($this->do_xss_clean() === FALSE)
+			{
+				$this->set_error('upload_unable_to_write_file');
+				return FALSE;
+			}
+		}
+
+		/*
 		 * Move the file to the final destination
 		 * To deal with different server configurations
 		 * we'll attempt to use copy() first.  If that fails
@@ -269,21 +308,6 @@
 				 return FALSE;
 			}
 		}
-		
-		/*
-		 * Run the file through the XSS hacking filter
-		 * This helps prevent malicious code from being
-		 * embedded within a file.  Scripts can easily
-		 * be disguised as images or other file types.
-		 */
-		if ($this->xss_clean)
-		{
-			if ($this->do_xss_clean() === FALSE)
-			{
-				$this->set_error('upload_unable_to_write_file');
-				return FALSE;
-			}
-		}
 
 		/*
 		 * Set the finalized image dimensions
@@ -316,6 +340,7 @@
 						'full_path'			=> $this->upload_path.$this->file_name,
 						'raw_name'			=> str_replace($this->file_ext, '', $this->file_name),
 						'orig_name'			=> $this->orig_name,
+						'client_name'		=> $this->client_name,
 						'file_ext'			=> $this->file_ext,
 						'file_size'			=> $this->file_size,
 						'is_image'			=> $this->is_image(),
@@ -558,7 +583,7 @@
 	 * @access	public
 	 * @return	bool
 	 */	
-	function is_allowed_filetype()
+	function is_allowed_filetype($ignore_mime = FALSE)
 	{
 		if ($this->allowed_types == '*')
 		{
@@ -570,36 +595,42 @@
 			$this->set_error('upload_no_file_types');
 			return FALSE;
 		}
-
-		$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
-
-		foreach ($this->allowed_types as $val)
+		
+		$ext = strtolower(ltrim($this->file_ext, '.'));
+		
+		if ( ! in_array($ext, $this->allowed_types))
 		{
-			$mime = $this->mimes_types(strtolower($val));
+			return FALSE;
+		}
 
-			// Images get some additional checks
-			if ($this->file_ext == '.'.$val &&  in_array($val, $image_types))
+		// Images get some additional checks		
+		$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
+		
+		if (in_array($ext, $image_types))
+		{
+			if (getimagesize($this->file_temp) === FALSE)
 			{
-				if (getimagesize($this->file_temp) === FALSE)
-				{
-					return FALSE;
-				}
-			}
-
-			if (is_array($mime))
+				return FALSE;
+			}			
+		}
+		
+		if ($ignore_mime === TRUE)
+		{
+			return TRUE;
+		}
+		
+		$mime = $this->mimes_types($ext);
+				
+		if (is_array($mime))
+		{
+			if (in_array($this->file_type, $mime, TRUE))
 			{
-				if (in_array($this->file_type, $mime, TRUE))
-				{
-					return TRUE;
-				}
-			}
-			else
-			{
-				if ($mime == $this->file_type)
-				{
-					return TRUE;
-				}	
-			}		
+				return TRUE;
+			}			
+		}
+		elseif ($mime == $this->file_type)
+		{
+				return TRUE;
 		}
 		
 		return FALSE;
@@ -801,7 +832,7 @@
 	 */	
 	function do_xss_clean()
 	{		
-		$file = $this->upload_path.$this->file_name;
+		$file = $this->file_temp;
 		
 		if (filesize($file) == 0)
 		{
@@ -968,7 +999,7 @@
 
 		foreach ($parts as $part)
 		{
-			if ($this->mimes_types(strtolower($part)) === FALSE)
+			if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
 			{
 				$filename .= '.'.$part.'_';
 			}
@@ -978,13 +1009,6 @@
 			}
 		}
 
-		// file name override, since the exact name is provided, no need to
-		// run it through a $this->mimes check.
-		if ($this->file_name != '')
-		{
-			$filename = $this->file_name;
-		}
-
 		$filename .= '.'.$ext;
 		
 		return $filename;