• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Uploader.php function _file_mime_type fails in CI 2.1

#1
[eluser]ksorbo[/eluser]
There has been quite a bit of discussion in the code forum about problems uploading files (invalid file type). I have read all of them and nothing they did solved my problems.

I think I have found a problem (on my system, at least). I believe the problem lies with the use of the deprecated mime_content_type php function.

From upload.php CI version 2.1 lines 1019 - 1068

Code:
protected function _file_mime_type($file)
{
  // Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag)
  if ( (float) substr(phpversion(), 0, 3) >= 5.3 && function_exists('finfo_file'))
  {
   $finfo = new finfo(FILEINFO_MIME_TYPE);
   if ($finfo !== FALSE) // This is possible, if there is no magic MIME database file found on the system
   {
    $file_type = $finfo->file($file['tmp_name']);

    /* According to the comments section of the PHP manual page,
     * it is possible that this function returns an empty string
     * for some files (e.g. if they don't exist in the magic MIME database)
     */
    if (strlen($file_type) > 1)
    {
     $this->file_type = $file_type;
     return;
    }
   }
  }

  // Fall back to the deprecated mime_content_type(), if available
  if (function_exists('mime_content_type'))
  {
   $this->file_type = @mime_content_type($file['tmp_name']);
   return;
  }

  /* This is an ugly hack, but UNIX-type systems provide a native way to detect the file type,
   * which is still more secure than depending on the value of $_FILES[$field]['type'].
   *
   * Notes:
   * - a 'W' in the substr() expression bellow, would mean that we're using Windows
   * - many system admins would disable the exec() function due to security concerns, hence the function_exists() check
   */
  if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec'))
  {
   $output = array();
   @exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code);
   if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution
   {
    $this->file_type = rtrim($output[0]);
    return;
   }
  }

  $this->file_type = $file['type'];
}

I am running php 5.2.17 so the first IF (line 1022) fails. mime_content_type exists in 5.2.17 so the second if (line 1042) executes. $this->file_type is set using the mime_content_type function.

My server passes a random file name for the 'tmp_name' with no file extension. I am uploading docx files and my browser passes the correct mime type. However, the mime_content_type function returns plain text mime type. This causes the entire upload function to fail.

<b>My solution: revert to upload.php from 2.0.1.</b>

I don't know what the best way would be to detect mime type. The danger of using the browser's data is that it could be hacked allowing the user to upload potentially dangerous files.

Obviously this problem goes away if you are using 5.3+. Unfortunately, I had a hard enough time getting my host to move from 4.+ to 5.+ so I am not holding my breath.


#2
[eluser]CroNiX[/eluser]
I know there has been a lot of updates on this in the Github repo, so that version is probably working better.

#3
[eluser]ksorbo[/eluser]
I just took a look at the git source and the function _file_mime_type seems to use the same logic which is tripping me up.

Perhaps the authors are using a version of PHP which never encounters the second if statement and thus have never seen this problem.

#4
[eluser]Djaka PM[/eluser]
Hi my name is Djaka,
Currently I am facing an issue on the Upload library, I am using
- CI 2.1.0
- PHP Version 5.3.6-13ubuntu3.6

The issue actually not in the CI framework, but in a PHP function called "Fileinfo"
The Fileinfo function is called in CI`s _file_mime_type function inside Upload.php file ,
so my case is:

I am try to upload csv file, I already make sure that the file extension is correct and the allowed mime types are "csv|txt".

CI is already guess the file extension correctly("text/csv"), but by the time the CI called the "Fileinfo" function it return "text/plain", which is in my opinion is not correct.

Is there any workaround?
Some says that the "Fileinfo" is not quite reliable.
http://stackoverflow.com/questions/46071...e-from-php
For now I set the allowed mime types to wildcard, which will cause security issue.

Thanks.

#5
[eluser]Narf[/eluser]
The Upload library has been updated, try it: https://raw.github.com/EllisLab/CodeIgni...Upload.php

#6
[eluser]Djaka PM[/eluser]
Thanks Narf. I will try the new Upload.php

#7
[eluser]bluepicaso[/eluser]
[quote author="Djaka PM" date="1331116408"]Thanks Narf. I will try the new Upload.php[/quote]
Did you get this to work?
New library did not help me though

#8
[eluser]Djaka PM[/eluser]
Yup the new library still got it wrong. I think this issue only happens on *nix system.
Because when I did try my application on Windows it working correctly.

#9
[eluser]bluepicaso[/eluser]
[quote author="Djaka PM" date="1332313710"]Yup the new library still got it wrong. I think this issue only happens on *nix system.
Because when I did try my application on Windows it working correctly.
[/quote]

hmmm ok
i used valum's upload instead

#10
[eluser]Djaka PM[/eluser]
who is valum? can you share the code? because i do still dont know the workaround Big Grin


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.