diff options
author | Florian Pritz <bluewind@xinu.at> | 2012-06-13 09:19:13 +0200 |
---|---|---|
committer | Florian Pritz <bluewind@xinu.at> | 2012-06-13 09:19:13 +0200 |
commit | 0c8c0e3c9cd9942bd0512a940fe7790a666d00b7 (patch) | |
tree | 39fed6c67dba927ff293f16cd6df73aed7d9485a /system/libraries/Upload.php | |
parent | f4c8edeb04b7c1d72058066f36aa432604a277c7 (diff) | |
parent | d5e39ded4bbaaef528ebd0731c7c0a4968a8c438 (diff) |
Merge tag '2.1.1'
Retagging 2.1.1 for final release
Conflicts:
user_guide/changelog.html
user_guide/database/active_record.html
user_guide/database/caching.html
user_guide/database/call_function.html
user_guide/database/configuration.html
user_guide/database/connecting.html
user_guide/database/examples.html
user_guide/database/fields.html
user_guide/database/forge.html
user_guide/database/helpers.html
user_guide/database/index.html
user_guide/database/queries.html
user_guide/database/results.html
user_guide/database/table_data.html
user_guide/database/transactions.html
user_guide/database/utilities.html
user_guide/doc_style/index.html
user_guide/general/alternative_php.html
user_guide/general/ancillary_classes.html
user_guide/general/autoloader.html
user_guide/general/caching.html
user_guide/general/cli.html
user_guide/general/common_functions.html
user_guide/general/controllers.html
user_guide/general/core_classes.html
user_guide/general/creating_drivers.html
user_guide/general/creating_libraries.html
user_guide/general/credits.html
user_guide/general/drivers.html
user_guide/general/environments.html
user_guide/general/errors.html
user_guide/general/helpers.html
user_guide/general/hooks.html
user_guide/general/libraries.html
user_guide/general/managing_apps.html
user_guide/general/models.html
user_guide/general/profiling.html
user_guide/general/quick_reference.html
user_guide/general/requirements.html
user_guide/general/reserved_names.html
user_guide/general/routing.html
user_guide/general/security.html
user_guide/general/styleguide.html
user_guide/general/urls.html
user_guide/general/views.html
user_guide/helpers/array_helper.html
user_guide/helpers/captcha_helper.html
user_guide/helpers/cookie_helper.html
user_guide/helpers/date_helper.html
user_guide/helpers/directory_helper.html
user_guide/helpers/download_helper.html
user_guide/helpers/email_helper.html
user_guide/helpers/file_helper.html
user_guide/helpers/form_helper.html
user_guide/helpers/html_helper.html
user_guide/helpers/inflector_helper.html
user_guide/helpers/language_helper.html
user_guide/helpers/number_helper.html
user_guide/helpers/path_helper.html
user_guide/helpers/security_helper.html
user_guide/helpers/smiley_helper.html
user_guide/helpers/string_helper.html
user_guide/helpers/text_helper.html
user_guide/helpers/typography_helper.html
user_guide/helpers/url_helper.html
user_guide/helpers/xml_helper.html
user_guide/index.html
user_guide/installation/downloads.html
user_guide/installation/index.html
user_guide/installation/troubleshooting.html
user_guide/installation/upgrade_120.html
user_guide/installation/upgrade_130.html
user_guide/installation/upgrade_131.html
user_guide/installation/upgrade_132.html
user_guide/installation/upgrade_133.html
user_guide/installation/upgrade_140.html
user_guide/installation/upgrade_141.html
user_guide/installation/upgrade_150.html
user_guide/installation/upgrade_152.html
user_guide/installation/upgrade_153.html
user_guide/installation/upgrade_154.html
user_guide/installation/upgrade_160.html
user_guide/installation/upgrade_161.html
user_guide/installation/upgrade_162.html
user_guide/installation/upgrade_163.html
user_guide/installation/upgrade_170.html
user_guide/installation/upgrade_171.html
user_guide/installation/upgrade_172.html
user_guide/installation/upgrade_200.html
user_guide/installation/upgrade_201.html
user_guide/installation/upgrade_202.html
user_guide/installation/upgrade_203.html
user_guide/installation/upgrade_210.html
user_guide/installation/upgrade_b11.html
user_guide/installation/upgrading.html
user_guide/libraries/benchmark.html
user_guide/libraries/caching.html
user_guide/libraries/calendar.html
user_guide/libraries/cart.html
user_guide/libraries/config.html
user_guide/libraries/email.html
user_guide/libraries/encryption.html
user_guide/libraries/file_uploading.html
user_guide/libraries/form_validation.html
user_guide/libraries/ftp.html
user_guide/libraries/image_lib.html
user_guide/libraries/input.html
user_guide/libraries/javascript.html
user_guide/libraries/language.html
user_guide/libraries/loader.html
user_guide/libraries/migration.html
user_guide/libraries/output.html
user_guide/libraries/pagination.html
user_guide/libraries/parser.html
user_guide/libraries/security.html
user_guide/libraries/sessions.html
user_guide/libraries/table.html
user_guide/libraries/trackback.html
user_guide/libraries/typography.html
user_guide/libraries/unit_testing.html
user_guide/libraries/uri.html
user_guide/libraries/user_agent.html
user_guide/libraries/xmlrpc.html
user_guide/libraries/zip.html
user_guide/license.html
user_guide/overview/appflow.html
user_guide/overview/at_a_glance.html
user_guide/overview/cheatsheets.html
user_guide/overview/features.html
user_guide/overview/getting_started.html
user_guide/overview/goals.html
user_guide/overview/index.html
user_guide/overview/mvc.html
user_guide/toc.html
user_guide/tutorial/conclusion.html
user_guide/tutorial/create_news_items.html
user_guide/tutorial/hard_coded_pages.html
user_guide/tutorial/index.html
user_guide/tutorial/news_section.html
user_guide/tutorial/static_pages.html
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Diffstat (limited to 'system/libraries/Upload.php')
-rwxr-xr-x | system/libraries/Upload.php | 107 |
1 files changed, 84 insertions, 23 deletions
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 05511b5d3..0e5d73b19 100755 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -868,6 +868,10 @@ class CI_Upload { { return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good } + else + { + return FALSE; + } } if (($data = @file_get_contents($file)) === FALSE) @@ -1018,47 +1022,104 @@ class CI_Upload { */ 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')) + // We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii) + $regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/'; + + /* Fileinfo extension - most reliable method + * + * Unfortunately, prior to PHP 5.3 - it's only available as a PECL extension and the + * more convenient FILEINFO_MIME_TYPE flag doesn't exist. + */ + if (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 + $finfo = finfo_open(FILEINFO_MIME); + if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system { - $file_type = $finfo->file($file['tmp_name']); + $mime = @finfo_file($finfo, $file['tmp_name']); + finfo_close($finfo); /* 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) + if (is_string($mime) && preg_match($regexp, $mime, $matches)) { - $this->file_type = $file_type; + $this->file_type = $matches[1]; 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']. + /* 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'], and as it + * was reported in issue #750 (https://github.com/EllisLab/CodeIgniter/issues/750) - it's better + * than mime_content_type() as well, hence the attempts to try calling the command line with + * three different functions. * * 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 + * - the DIRECTORY_SEPARATOR comparison ensures that we're not on a Windows system + * - many system admins would disable the exec(), shell_exec(), popen() and similar functions + * due to security concerns, hence the function_exists() checks */ - if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec')) + if (DIRECTORY_SEPARATOR !== '\\') { - $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 + $cmd = 'file --brief --mime ' . escapeshellarg($file['tmp_name']) . ' 2>&1'; + + if (function_exists('exec')) + { + /* This might look confusing, as $mime is being populated with all of the output when set in the second parameter. + * However, we only neeed the last line, which is the actual return value of exec(), and as such - it overwrites + * anything that could already be set for $mime previously. This effectively makes the second parameter a dummy + * value, which is only put to allow us to get the return status code. + */ + $mime = @exec($cmd, $mime, $return_status); + if ($return_status === 0 && is_string($mime) && preg_match($regexp, $mime, $matches)) + { + $this->file_type = $matches[1]; + return; + } + } + + if ( (bool) @ini_get('safe_mode') === FALSE && function_exists('shell_exec')) + { + $mime = @shell_exec($cmd); + if (strlen($mime) > 0) + { + $mime = explode("\n", trim($mime)); + if (preg_match($regexp, $mime[(count($mime) - 1)], $matches)) + { + $this->file_type = $matches[1]; + return; + } + } + } + + if (function_exists('popen')) + { + $proc = @popen($cmd, 'r'); + if (is_resource($proc)) + { + $mime = @fread($proc, 512); + @pclose($proc); + if ($mime !== FALSE) + { + $mime = explode("\n", trim($mime)); + if (preg_match($regexp, $mime[(count($mime) - 1)], $matches)) + { + $this->file_type = $matches[1]; + return; + } + } + } + } + } + + // Fall back to the deprecated mime_content_type(), if available (still better than $_FILES[$field]['type']) + if (function_exists('mime_content_type')) + { + $this->file_type = @mime_content_type($file['tmp_name']); + if (strlen($this->file_type) > 0) // It's possible that mime_content_type() returns FALSE or an empty string { - $this->file_type = rtrim($output[0]); return; } } |