Welcome Guest, Not a member yet? Register   Sign In
Zip "corrupted" file... starts of central directory not found
#1

[eluser]Unknown[/eluser]
I'm using this...

$this->zip->add_data($filevcf,$content);
$this->zip->archive('./uploads/my_backup.zip');
$this->zip->download("$filename.zip");

If works fine, but when i try to unzip with Winzip, Winzip Crashes with this error.
"Starts of central directory not found.."

I can open it with Winrar with no problems at all..

Any ideas?
#2

[eluser]Unknown[/eluser]
I knew a very nice application <a href="http://www.datanumen.com/azr/ ">Advanced Advanced Zip Repair</a>. It is a powerful tool to recover messages, folders and other objects from corrupt or damaged zip files.
#3

[eluser]dmorin[/eluser]
Are you doing anything to handle UTF8 characters like setting mbstring.func_overload? Setting this causes issues with things like archive and encryption libraries. There are solutions though so let me know if you think this might be the issue.
#4

[eluser]John Ashwin[/eluser]
EDIT: Sorry, my problem is not the same as yours, but since I posted here, I
can't remove it.


I'm having the same problem with the zips that are created by the Zip lib. WinRar extracts them fine, but when I right click on any of the extracted files, Windows explorer crashes.

Update:
Quote:The files are fine when extracted with:
7-zip
Native Windows Right-click option

The files are corrupt when unzipped using:
WinRar
StuffIt

Not tested on winZip as I don't have it installed.

These are the settings from my PHP.ini

Code:
[mbstring]
mbstring.func_overload = 0


So far, I've not been able to fix this problem.

I've attached an example zip that was created by CI on my server.
#5

[eluser]John Ashwin[/eluser]
UPDATE:

Ok. I've narrowed down the cause of the explorer crash to sourcegear diffmerge. Since the files from the
zip, do not contain a date stamp diffmerge crashes explorer. Notepad++ still crashes when trying to open
any of the extracted files. (extracted with winRar)
#6

[eluser]John Ashwin[/eluser]
FIXED::

I narrowed the problem down to a generic timestamps
in the packing of the data in the Zip library.

A modification of the way the data is stored for files,
worked! :cheese:

This is my replacement of the function _add_data() in
CI Native Zip library.

p.s: I've attached the fix to this post as well.

Code:
/**
     * Mod by : John Christos
     * Add Data to Zip With Dates To Correct no timestamp when
     * extracted by winrar and stuffIt.
     *
     * @access    private
     * @param    string    the file name/path
     * @param    string    the data to be encoded
     * @return    void
     */    
    function _add_data($filepath, $data, $time = 0)
    {
        $filepath = str_replace("\\", "/", $filepath);
        
        // Create TimeStamp
        $dtime    = dechex($this->unix2DosTime($time));

        $hexdtime = '\x' . $dtime[6] . $dtime[7]
                  . '\x' . $dtime[4] . $dtime[5]
                  . '\x' . $dtime[2] . $dtime[3]
                  . '\x' . $dtime[0] . $dtime[1];
                  
        eval('$hexdtime = "' . $hexdtime . '";');
        
        // At this point the Timestamp is in $hexdtime;
        
        

        $uncompressed_size = strlen($data);
        $crc32  = crc32($data);

        $gzdata = gzcompress($data);
        $gzdata = substr($gzdata, 2, -4);
        $compressed_size = strlen($gzdata);
        
    $this->zipdata .=
            "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00" . $hexdtime
            .pack('V', $crc32)
            .pack('V', $compressed_size)
            .pack('V', $uncompressed_size)
            .pack('v', strlen($filepath)) // length of filename
            .pack('v', 0) // extra field length
            .$filepath
            .$gzdata; // "file data" segment
            
            

        $this->directory .=
            "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"
            .pack('V', $crc32)
            .pack('V', $compressed_size)
            .pack('V', $uncompressed_size)
            .pack('v', strlen($filepath)) // length of filename
            .pack('v', 0) // extra field length
            .pack('v', 0) // file comment length
            .pack('v', 0) // disk number start
            .pack('v', 0) // internal file attributes
            .pack('V', 32) // external file attributes - 'archive' bit set
            .pack('V', $this->offset) // relative offset of local header
            .$filepath;

        $this->offset = strlen($this->zipdata);
        $this->entries++;
        $this->file_num++;
    }
    
    // --------------------------------------------------------------------
    
    
    /**
     * (This function is borrowed from http://drupal.org/node/83253)
     * Converts an Unix timestamp to a four byte DOS date and time format (date
     * in high two bytes, time in low two bytes allowing magnitude comparison).
     *
     * @param  integer  the current Unix timestamp
     *
     * @return integer  the current date in a four byte DOS format
     *
     * @access private
     */
    function unix2DosTime($unixtime = 0) {
        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);

        if ($timearray['year'] < 1980) {
            $timearray['year']    = 1980;
            $timearray['mon']     = 1;
            $timearray['mday']    = 1;
            $timearray['hours']   = 0;
            $timearray['minutes'] = 0;
            $timearray['seconds'] = 0;
        } // end if

        return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
                ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
    } // end of the 'unix2DosTime()' method



The zip files work brilliantly now with all unzipper softwares.

I hope this helps someone else as well.

All the best!!


Best Regards,

John Christos




Theme © iAndrew 2016 - Forum software by © MyBB