Welcome Guest, Not a member yet? Register   Sign In
Bug in Upload Class.
#1

[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
#2

[eluser]therendStudio[/eluser]
Seconding the issue (seems I'm not the only one but it's been widely ignored...)

However there's a simpler and shorter way to fix that method - simply move the image checking code inside the type-matched body

Code:
class MY_Upload extends CI_Upload {
    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));

            if(is_array($mime) && in_array($this->file_type, $mime, TRUE)
                || $mime == $this->file_type
            ) {
                    // Images get some additional checks
                    if (in_array($val, $image_types))
                        if (getimagesize($this->file_temp) === FALSE)
                            return FALSE;
                    return TRUE;
            }        
        }
        return FALSE;
    }
}
is the whole code for overriding the method
#3

[eluser]Phil Sturgeon[/eluser]
This has been fixed in CodeIgniter 2.0.
#4

[eluser]Rufus09[/eluser]
I also have this issue. It's cool that the issue is resolved in 2.0. I still have the older version, since I have been away for a while. I will be updating shortly. Thank you anyway for posting the work around, it's always nice to see people contributing solutions to common problems.




Theme © iAndrew 2016 - Forum software by © MyBB