EllisLab/CodeIgniter — Issue #750: Upload.php incorrectly detecting mime_types for PNG images
Author: zechdc
Created: 2011-12-08 11:39:12+00:00
State: open

# Problem
When Uploading a PNG image the mime_type sometimes is "text/plain" depending on which server it is run on. This prevents me from having an upload form which can accept PNG files properly.

# Summary
Below I have an example script that is used in all my tests. I also have two server configurations (Machine 1 & Machine 2).

I then ran three different tests on each machine (Situation 1, Situation 2, Situation 3 & Situation 4). The results of each situation is posted below as well.

I have been working on this for 5 + hours and not sure what to do with all this information.

## Example Upload Script:
```PHP
session->userdata('DX_user_id');
$file_name = $user_id . '_logo.png';

$config['upload_path'] = './uploads/logos/';
$config['allowed_types'] = 'png|gif|jpg';
$config['overwrite'] = TRUE;
$config['max_size']	= '50';
$config['max_width'] = '500';
$config['max_height'] = '128';
$config['file_name'] = $file_name;

$this->load->library('upload', $config);

//if they submit the form, process the upload
if($this->input->post('submit'))
{
$this->upload->do_upload('logo');
}

//Load View
}
?>
```

## Machine 1:
Local machine

**Setup:**
Mac OS: 10.7.2
MAMP: 1.9.4
PHP: 5.3.2
System:	Darwin localhost 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug 9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64

## Machine 2:
Shared hosting on liquidweb.com

**Setup:**
PHP: 5.2
System: CentOS 5.7

# Situation 1:
I ran the Example Upload Script on both Machine 1 and Machine 2

## Situation 1 Results:
**Machine 1**
Using the Example Upload Script worked fine on Machine 1.

It looks like on Machine 1 mime_types was being determined by using FILEINFO_MIME_TYPE because Machine 1 was using a version of PHP greater than 5.3. I made this assumption according the following comment found on line 1021 of Upload.php
`// Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag)`

**Machine 2**
When running the Example Upload Script on Machine 2, I ran into the issue with a PNG's mime_type being "text/plain"

It looks like in Machine 2 mime_types was being determined by using `mime_content_type()` on line 1044. Since it didn't meet the conditions to use Fileinfo extension it fell through to `mime_content_type()`.

# Situation 2:
I then ran the following script on both machines
`

`

## Situation 2 Results:
I got the following outputs:

**Machine 1**
image/png

**Machine 2**
text/plain

# Situation 3:
After Situation 2, I was questioning how mime_content_type worked.

I then found an article which suggested that mime_content_type has a bug with PNG's:
http://www.phpbuilder.com/board/showthread.php?t=10306479

I looked at PHP's documentation which says mime_content_type is deprecated. Also, the comments suggest to run the following code. So I ran the following code on both machines.
`

`

## Situation 3 Results:
I got the following outputs:

**Machine 1**
image/png; charset=binary image/png; charset=binary

**Machine 2**
image/png image/png

# Situation 4:
After Situation 3, I figured it was some server setting so I contacted liquidweb.

Below is my communication with ScottM at Liquidweb (I have edited the text for clarity):
**ScottM:** Thanks! How can I help you?
**Zech:** Is it possible for me to run a unix command on my shared hosting account?
**ScottM:** We can't give you SSH access, but I can log in and run it for you. Could you provide the full unix command you'd like to check?
**Zech:** If you could please run the following: "file --brief --mime-type ABSOLUTE_URL"
**ScottM:** Sure, give me a moment to get logged in and I'll do that.
**Zech:** thanks, the expected output will be " image/png"
**ScottM:** file: unrecognized option `--mime-type' Hmm.
**ScottM:** Man-ing file.
**Zech:** So it didn't recognize --mime-type? What do you mean Man-ing file? And what operating system is this machine running?
**ScottM:** I was looking at the integral manual using the 'man' command to check an allowable flags.
**ScottM:** Ah, it wants --mime rather than --mime-type.
**ScottM:** --mime returned expected result of image/png.
**Zech:** so the new command is "file --brief --mime"
**ScottM:** Right. For the record, this server is running CentOS 5.7.

After that brief conversation I updated line 1061 from:
`@exec('file --brief --mime-type ' . escapeshellarg($file['tmp_name']), $output, $return_code);`
To:
`@exec('file --brief --mime ' . escapeshellarg($file['tmp_name']), $output, $return_code);`

## Situation 4 Results:
I got the following outputs:

**Machine 1**
image/png; charset=binary

**Machine 2**
image/png

# Conclusion:
So as you can see, Machine 1(PHP5.3) runs fine with CI 2.1.0 but Machine 2 (PHP5.2) does not work properly unless you change line 1061 of Upload.php to:
`@exec('file --brief --mime ' . escapeshellarg($file['tmp_name']), $output, $return_code);`
Once you change line 1061, Machine 1(PHP5.3) still works properly, line 1061 does not return the desired result if the codes was to fall through.

I'm not sure what to do with the code. It seems like there are to many different outcomes based on your server configuration. I'm not very experience with these types of issues. I hope someone else knows what to do with this information. :)

If there is any more information you need please let me know.