[eluser]Unknown[/eluser]
I've discovered a bug in the upload class.
When I tried to upload a pdf file, with the following configuration:
Code:
$config['allowed_types'] = 'txt|jpg|pdf|doc';
I recieved the error: The filetype you are attempting to upload is not allowed.
When changing the code to:
Code:
$config['allowed_types'] = 'txt|pdf|jpg|doc';
Strangely enough it was working.
When I looked to the is_allowed_filetype() function, I discovered the reason why this error comes up.
Code:
function is_allowed_filetype()
{
if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
{
$this->set_error('upload_no_file_types');
return FALSE;
}
$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
foreach ($this->allowed_types as $val)
{
$mime = $this->mimes_types(strtolower($val));
// Images get some additional checks
if (in_array($val, $image_types))
{
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 FALSE;
}
The error is in the first part of the code:
Code:
$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
foreach ($this->allowed_types as $val)
{
$mime = $this->mimes_types(strtolower($val));
// Images get some additional checks
if (in_array($val, $image_types)) // << Error.
{
if (getimagesize($this->file_temp) === FALSE)
{
return FALSE;
}
}
When trying to upload a file which is allowed, but is no image, and there is an imagetype allowed which is in the allowed_types string before the allowed extension of the given file, this function allready threats your file like it's an image. In my case; uploading a pdf file, will be threaded like an image which wil result in an error when the getimagesize() function tries to validate it as an image.
I fixed this bug by creating my own upload class, and overruled the is_allowed function:
Code:
function is_allowed_filetype()
{
if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
{
$this->set_error('upload_no_file_types');
return FALSE;
}
$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
//Get mime-types for each image_type and put it in the image_mime_types array.
foreach($image_types AS $image_type){
$image_mimes = $this->mimes_types(strtolower($image_type));
if(is_array($image_mimes)){
foreach($image_mimes as $image_mime){
$image_mime_types[] = $image_mime;
}
}else{
$image_mime_types[] = $image_mimes;
}
}
foreach ($this->allowed_types as $val)
{
$mime = $this->mimes_types(strtolower($val));
// Images get some additional checks
if (in_array($this->file_type, $image_mime_types)) // Check if the current file_type has the mime-type of an image.
{
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 FALSE;
}
This checks the uploading file's mime-type. If this mime-type is the same as one of the specified image_types, the file will be threated like an image. If it is another type, for example a pdf file, it will not be threated like an image. With this fix, it does not matter if the jpg file extension comes before another in the allowed_types string which is no image.
I hope this post was useful!
Greets,
Eric