Home arrow Blog arrow Another Joomla installer problem

Another Joomla installer problem

There is a problem with the PHP function gunzip() which in early versions of PHP 5 is known to have made large and unnecessary memory demands in some circumstances. This error is liable to be triggered by Joomla for some PHP versions in the 5.1.x range. Also, there is a problem with some of the Joomla code.

Also, for sites running PHP 5.2.0 or later Joomla would use PHP functions to unpack zip files, but with earlier versions Joomla code is used. A problem was eventually traced to the JFile class and its read method. It can be found at ../libraries/joomla/filesystem/file.php. The old read method is:

    function read($filename, $incpath = false, $amount = 0, 
    $chunksize = 8192, $offset = 0)
    {
            // Initialize variables
            $data = null;
            if($amount && $chunksize > $amount) { $chunksize = $amount; }
            if (false === $fh = fopen($filename, 'rb', $incpath)) {
                    JError::raiseWarning(21, 'JFile::read: '.
                    JText::_('Unable to open file') . ": '$filename'");
                    return false;
            }
            clearstatcache();
            if($offset) fseek($fh, $offset);
            if ($fsize = @ filesize($filename)) {
                    if($amount && $fsize > $amount) {
                            $data = fread($fh, $amount);
                    } else {
                            $data = fread($fh, $fsize);
                    }
            } else {
                    $data = '';
                    $x = 0;
                    // While its:
                    // 1: Not the end of the file AND
                    // 2a: No Max Amount set OR
                    // 2b: The length of the data is less than the max amount 
                    // we want
                    while (!feof($fh) && (!$amount || strlen($data) < $amount)) {
                            $data .= fread($fh, $chunksize);
                    }
            }
            fclose($fh);

            return $data;
    }

This is not especially well written, and so far as I can see, does not work correctly for a file larger than 8192 bytes. It can be replaced by:

function read($filename, $incpath = false, $amount = 0, 
$chunksize = 8192, $offset = 0)
{
    // Initialize variables
    if (false === $fh = fopen($filename, 'rb', $incpath)) {
        JError::raiseWarning(21, 'JFile::read: '.
        JText::_('Unable to open file') . ": '$filename'");
        return false;
    }
    if($offset) fseek($fh, $offset);
    $data = '';
    // While its:
    // 1: Not the end of the file AND
    // 2a: No Max Amount set OR
    // 2b: The length of the data is less than the max amount we want
    while (!feof($fh) AND $trysize = $amount ? 
    min($chunksize, ($amount - strlen($data))) : $chunksize) {
        $data .= fread($fh, $trysize);
    }
    fclose($fh);

    return $data;
}

which appears to provide the desired functionality. With this code in place, it was possible to install either zip or tar.gz files.

#128006 • 10/20/2009 5:26pm by Martin Brampton • Vote: Up votes (309) Down votes (196)