On 28.05.2014 09:05, Thomas Bruederli wrote:

> Maybe you can do some tests with finfo_open() / finfo_file() and
> mime_content_type() do further track down the failing component.

I have added a couple of error_log statements to the file_content_type
function to narrow the problem down (see end of this message). A typical
trace for PDF attachments looks like this:

  Entering file_content_type
  Checking mime_ext array
  MIME type is application/pdf
  Start finfo_open block
  End finfo_open block
  Exiting file_content_type with mime_type application/pdf

while a typical trace for other files (i.e. PNG, XML) looks like this:

  Entering file_content_type
  Checking mime_ext array
  MIME type is null
  Start finfo_open block
  m1: finfo_open exists
  m3: mime_magic is null
  m4: process finfo
  m5: finfo is not null
  m8: calling finfo_file
  m9: done calling finfo_file
  m10: calling finfo_close
  Entering file_content_type
  Checking mime_ext array
  MIME type is null
  Start finfo_open block
  m1: finfo_open exists
  m3: mime_magic is null
  m4: process finfo
  m5: finfo is not null
  m8: calling finfo_file
  m9: done calling finfo_file
  m10: calling finfo_close

Seems to me that the Apache child processes die in the finfo_close call,
then a new child is spawned which dies there aswell (up to three times).
Here is a backtrace from the Apache log, if it helps:

*** Error in `/usr/sbin/apache2': free(): invalid next size (fast): 
0x00007f70207d0b40 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7403f)[0x7f7067dd303f]
/lib64/libc.so.6(+0x7995e)[0x7f7067dd895e]
/lib64/libc.so.6(+0x7a686)[0x7f7067dd9686]
/usr/lib64/libmagic.so.1(+0x4e83)[0x7f705f921e83]
/usr/lib64/apache2/modules/libphp5.so(finfo_resource_destructor+0x15)[0x7f705ec9bfe5]
/usr/lib64/apache2/modules/libphp5.so(list_entry_destructor+0x52)[0x7f705eefe492]
/usr/lib64/apache2/modules/libphp5.so(zend_hash_del_key_or_index+0x29d)[0x7f705eefc36d]
/usr/lib64/apache2/modules/libphp5.so(_zend_list_delete+0x7d)[0x7f705eefe6cd]
/usr/lib64/apache2/modules/libphp5.so(zif_finfo_close+0x6c)[0x7f705ec9c3bc]
/usr/lib64/apache2/modules/libphp5.so(+0x4e6141)[0x7f705efab141]
/usr/lib64/apache2/modules/libphp5.so(execute_ex+0x4b)[0x7f705ef1ad4b]
/usr/lib64/apache2/modules/libphp5.so(zend_execute_scripts+0x1c3)[0x7f705eeef483]
/usr/lib64/apache2/modules/libphp5.so(php_execute_script+0x20b)[0x7f705ee8208b]
/usr/lib64/apache2/modules/libphp5.so(+0x4e7f1f)[0x7f705efacf1f]
/usr/sbin/apache2(ap_run_handler+0x40)[0x448d20]
/usr/sbin/apache2(ap_invoke_handler+0x69)[0x449279]
/usr/sbin/apache2(ap_process_async_request+0x1fa)[0x45c3ba]
/usr/sbin/apache2[0x4593b0]
/usr/sbin/apache2(ap_run_process_connection+0x40)[0x451d60]
/usr/sbin/apache2[0x4641de]
/lib64/libpthread.so.0(+0x8073)[0x7f706830e073]
/lib64/libc.so.6(clone+0x6d)[0x7f7067e4744d]

Finally, here is the modified function I used for debugging:

public static function file_content_type($path, $name, $failover = 
'application/octet-stream',
$is_stream = false, $skip_suffix = false)
{
    error_log("Entering file_content_type");
    static $mime_ext = array();

    $mime_type = null;
    $config = rcube::get_instance()->config;
    $mime_magic = $config->get('mime_magic');

    if (!$skip_suffix && empty($mime_ext)) {
        foreach ($config->resolve_paths('mimetypes.php') as $fpath) {
            $mime_ext = array_merge($mime_ext, (array) @include($fpath));
        }
    }

    // use file name suffix with hard-coded mime-type map
    if (!$skip_suffix && is_array($mime_ext) && $name) {
        if ($suffix = substr($name, strrpos($name, '.')+1)) {
            error_log("Checking mime_ext array");
            $mime_type = $mime_ext[strtolower($suffix)];
            error_log("MIME type is " . ($mime_type ? $mime_type : "null"));
        }
    }

    error_log("Start finfo_open block");
    // try fileinfo extension if available
    if (!$mime_type && function_exists('finfo_open')) {
        error_log("m1: finfo_open exists");
        // null as a 2nd argument should be the same as no argument
        // this however is not true on all systems/versions
        if ($mime_magic) {
            error_log("m2: mime_magic is not null");
            $finfo = finfo_open(FILEINFO_MIME, $mime_magic);
        }
        else {
            error_log("m3: mime_magic is null");
            $finfo = finfo_open(FILEINFO_MIME);
        }

        error_log("m4: process finfo");
        if ($finfo) {
            error_log("m5: finfo is not null");
            if ($is_stream) {
                error_log("m6: calling finfo_buffer");
                $mime_type = finfo_buffer($finfo, $path);
                error_log("m7: done calling finfo_buffer");
            }
            else {
                error_log("m8: calling finfo_file");
                $mime_type = finfo_file($finfo, $path);
                    error_log("m9: done calling finfo_file");
            }
            error_log("m10: calling finfo_close");
            finfo_close($finfo);
            error_log("m11: done calling finfo_close");
        }
    }
    error_log("End finfo_open block");

    // try PHP's mime_content_type
    if (!$mime_type && !$is_stream && function_exists('mime_content_type')) {
        $mime_type = @mime_content_type($path);
    }

    // fall back to user-submitted string
    if (!$mime_type) {
        $mime_type = $failover;
    }
    else {
        // Sometimes (PHP-5.3?) content-type contains charset definition,
        // Remove it (#1487122) also "charset=binary" is useless
        $mime_type = array_shift(preg_split('/[; ]/', $mime_type));
    }

    error_log("Exiting file_content_type with mime_type " . $mime_type);
    return $mime_type;
}

_______________________________________________
Roundcube Users mailing list
[email protected]
http://lists.roundcube.net/mailman/listinfo/users

Reply via email to