Commits

Derek Jones committed c39315f

201007 file upload bug fix

Comments (0)

Files changed (2)

system/libraries/Upload.php

  *
  * @package		CodeIgniter
  * @author		ExpressionEngine Dev Team
- * @copyright	Copyright (c) 2008 - 2009, EllisLab, Inc.
+ * @copyright	Copyright (c) 2008 - 2010, EllisLab, Inc.
  * @license		http://codeigniter.com/user_guide/license.html
  * @link		http://codeigniter.com
  * @since		Version 1.0
  */
 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	= '';	
 	/**
 	 * Constructor
 	 *
 							'mimes'				=> array(),
 							'remove_spaces'		=> TRUE,
 							'xss_clean'			=> FALSE,
-							'temp_prefix'		=> "temp_file_"
+							'temp_prefix'		=> "temp_file_",
+							'client_name'		=> ''
 						);	
 	
 	
 				$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;
 	}
 	
 	// --------------------------------------------------------------------
 
 		// Set the uploaded data as class variables
 		$this->file_temp = $_FILES[$field]['tmp_name'];		
+		$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_name = $this->_prep_filename($_FILES[$field]['name']);
-		$this->file_size = $_FILES[$field]['size'];		
-		$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
-		$this->file_type = strtolower($this->file_type);
-		$this->file_ext	 = $this->get_extension($_FILES[$field]['name']);
-		
-		// Convert the file size to kilobytes
-		if ($this->file_size > 0)
-		{
-			$this->file_size = round($this->file_size/1024, 2);
-		}
+		$this->file_ext	 = $this->get_extension($this->file_name);
+		$this->client_name = $this->file_name;
 
 		// Is the file type allowed to be uploaded?
 		if ( ! $this->is_allowed_filetype())
 			$this->set_error('upload_invalid_filetype');
 			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())
 						'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(),
 	 * @access	public
 	 * @return	bool
 	 */	
-	function is_allowed_filetype()
+	function is_allowed_filetype($ignore_mime = FALSE)
 	{
 		if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
 		{
 			$this->set_error('upload_no_file_types');
 			return FALSE;
 		}
+		
+		$ext = strtolower(ltrim($this->file_ext, '.'));
+		
+		if ( ! in_array($ext, $this->allowed_types))
+		{
+			return FALSE;
+		}
 
+		// Images get some additional checks
 		$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
 
-		foreach ($this->allowed_types as $val)
+		if (in_array($ext, $image_types))
 		{
-			$mime = $this->mimes_types(strtolower($val));
+			if (getimagesize($this->file_temp) === FALSE)
+			{
+				return FALSE;
+			}			
+		}
 
-			// Images get some additional checks
-			if (in_array($val, $image_types))
+		if ($ignore_mime === TRUE)
+		{
+			return TRUE;
+		}
+		
+		$mime = $this->mimes_types($ext);
+				
+		if (is_array($mime))
+		{
+			if (in_array($this->file_type, $mime, TRUE))
 			{
-				if (getimagesize($this->file_temp) === FALSE)
-				{
-					return FALSE;
-				}
-			}
-
-			if (is_array($mime))
-			{
-				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;
 
 		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.'_';
 			}
 			}
 		}
 
-		// 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;

user_guide/libraries/file_uploading.html

 <td class="td">None</td>
 <td class="td">Desired file name</td>
 <td class="td">
-	<p>If set CodeIgniter will rename the uploaded file to this name.</p>
-	<p class="important"><strong>Note:</strong>The filename should not include a file extension.</p>
+	<p>If set CodeIgniter will rename the uploaded file to this name.  The extension provided in the file name must also be an allowed file type.</p>
 </td>
 </tr>
 
 &nbsp;&nbsp;&nbsp;&nbsp;[full_path]&nbsp;&nbsp;&nbsp;&nbsp;=> /path/to/your/upload/jpg.jpg<br />
 &nbsp;&nbsp;&nbsp;&nbsp;[raw_name]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=> mypic<br />
 &nbsp;&nbsp;&nbsp;&nbsp;[orig_name]&nbsp;&nbsp;&nbsp;&nbsp;=> mypic.jpg<br />
+&nbsp;&nbsp;&nbsp;&nbsp;[client_name]&nbsp;&nbsp;=> mypic.jpg<br />
 &nbsp;&nbsp;&nbsp;&nbsp;[file_ext]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=> .jpg<br />
 &nbsp;&nbsp;&nbsp;&nbsp;[file_size]&nbsp;&nbsp;&nbsp;&nbsp;=> 22.2<br />
 &nbsp;&nbsp;&nbsp;&nbsp;[is_image]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=> 1<br />
 <tr><td class="td"><strong>orig_name</strong></td>
 <td class="td">The original file name.  This is only useful if you use the encrypted name option.</td></tr>
 
+<tr><td class="td"><strong>client_name</strong></td>
+<td class="td">The file name as supplied by the client user agent, prior to any file name preparation or incrementing.</td></tr>
+
 <tr><td class="td"><strong>file_ext</strong></td>
 <td class="td">The file extension with period</td></tr>
 
 <a href="../index.html">User Guide Home</a>&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
 Next Topic:&nbsp;&nbsp;<a href="form_validation.html">Form Validation Class</a>
 </p>
-<p><a href="http://codeigniter.com">CodeIgniter</a> &nbsp;&middot;&nbsp; Copyright &#169; 2006-2009 &nbsp;&middot;&nbsp; <a href="http://ellislab.com/">Ellislab, Inc.</a></p>
+<p><a href="http://codeigniter.com">CodeIgniter</a> &nbsp;&middot;&nbsp; Copyright &#169; 2006-2010 &nbsp;&middot;&nbsp; <a href="http://ellislab.com/">Ellislab, Inc.</a></p>
 </div>
 
 </body>