From 72b7b68f9eaaa5175203d1785b4f7b5e10de0cd0 Mon Sep 17 00:00:00 2001 From: Uma <uma.s@vtiger.com> Date: Fri, 6 Mar 2020 11:24:54 +0530 Subject: [PATCH] Zip file corruption is addressed, By deperacting call by reference and filesize update for proper download --- vtlib/Vtiger/Zip.php | 23 +++++------ vtlib/thirdparty/dUnzip2.inc.php | 21 +++++----- vtlib/thirdparty/dZip.inc.php | 68 ++++++++++++++++---------------- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/vtlib/Vtiger/Zip.php b/vtlib/Vtiger/Zip.php index 271af65a1..b86e67305 100644 --- a/vtlib/Vtiger/Zip.php +++ b/vtlib/Vtiger/Zip.php @@ -18,21 +18,16 @@ class Vtiger_Zip extends dZip { * Push out the file content for download. */ function forceDownload($zipfileName) { - header("Pragma: public"); - header("Expires: 0"); - header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); - header("Cache-Control: private",false); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: private",false); header("Content-Type: application/zip"); - header("Content-Disposition: attachment; filename=".basename($zipfileName).";" ); - //header("Content-Transfer-Encoding: binary"); - - // For details on this workaround check here the ticket - // http://trac.vtiger.com/cgi-bin/trac.cgi/ticket/5298 - $disk_file_size = filesize($zipfileName); - $zipfilesize = $disk_file_size + ($disk_file_size % 1024); - header("Content-Length: ".$zipfilesize); - $fileContent = fread(fopen($zipfileName, "rb"), $zipfilesize); - echo $fileContent; + header("Content-Disposition: attachment; filename=".basename($zipfileName).";" ); + $disk_file_size = filesize($zipfileName); + header("Content-Length: ".$disk_file_size); + $fileContent = fread(fopen($zipfileName, "rb"), $disk_file_size); + echo $fileContent; } /** diff --git a/vtlib/thirdparty/dUnzip2.inc.php b/vtlib/thirdparty/dUnzip2.inc.php index 8c1958a02..893947dae 100644 --- a/vtlib/thirdparty/dUnzip2.inc.php +++ b/vtlib/thirdparty/dUnzip2.inc.php @@ -87,12 +87,16 @@ class dUnzip2{ var $dirSignatureE= "\x50\x4b\x05\x06"; // end of central dir signature // Public - Function dUnzip2($fileName){ + Function __construct($fileName){ $this->fileName = $fileName; $this->compressedList = $this->centralDirList = $this->endOfCentral = Array(); } + function ensureFh(){ + if(!$this->fh) + $this->fh = fopen($this->fileName, "r"); + } Function getList($stopOnFile=false){ if(sizeof($this->compressedList)){ @@ -101,17 +105,16 @@ class dUnzip2{ } // Open file, and set file handler - $fh = fopen($this->fileName, "r"); - $this->fh = $fh; - if(!$fh){ + $this->ensureFh(); + if(!$this->fh){ $this->debugMsg(2, "Failed to load file."); return false; } $this->debugMsg(1, "Loading list from 'End of Central Dir' index list..."); - if(!$this->_loadFileListByEOF($fh, $stopOnFile)){ + if(!$this->_loadFileListByEOF($this->fh, $stopOnFile)){ $this->debugMsg(1, "Failed! Trying to load list looking for signatures..."); - if(!$this->_loadFileListBySignatures($fh, $stopOnFile)){ + if(!$this->_loadFileListBySignatures($this->fh, $stopOnFile)){ $this->debugMsg(1, "Failed! Could not find any valid header."); $this->debugMsg(2, "ZIP File is corrupted or empty"); return false; @@ -323,7 +326,7 @@ class dUnzip2{ echo "<b style='color: #F00'>dUnzip2:</b> $string<br>"; } - Function _loadFileListByEOF(&$fh, $stopOnFile=false){ + Function _loadFileListByEOF($fh, $stopOnFile=false){ // Check if there's a valid Central Dir signature. // Let's consider a file comment smaller than 1024 characters... // Actually, it length can be 65536.. But we're not going to support it. @@ -433,7 +436,7 @@ class dUnzip2{ } return false; } - Function _loadFileListBySignatures(&$fh, $stopOnFile=false){ + Function _loadFileListBySignatures($fh, $stopOnFile=false){ fseek($fh, 0); $return = false; @@ -457,7 +460,7 @@ class dUnzip2{ return $return; } - Function _getFileHeaderInformation(&$fh, $startOffset=false){ + Function _getFileHeaderInformation($fh, $startOffset=false){ if($startOffset !== false) fseek($fh, $startOffset); diff --git a/vtlib/thirdparty/dZip.inc.php b/vtlib/thirdparty/dZip.inc.php index d4449a1ce..6e31801a4 100644 --- a/vtlib/thirdparty/dZip.inc.php +++ b/vtlib/thirdparty/dZip.inc.php @@ -15,7 +15,7 @@ class dZip{ var $files_count = 0; var $fh; - Function dZip($filename, $overwrite=true){ + Function __construct($filename, $overwrite=true){ $this->filename = $filename; $this->overwrite = $overwrite; } @@ -24,9 +24,12 @@ class dZip{ $dirname .= '/'; $this->addFile(false, $dirname, $fileComments); } - Function addFile($filename, $cfilename, $fileComments='', $data=false){ - if(!($fh = $this->fh)) - $fh = fopen($this->filename, $this->overwrite?'wb':'a+b'); + function ensureFh(){ + if(!$this->fh) + $this->fh = fopen($this->filename, $this->overwrite?'wb':'a+b'); + } + Function addFile($filename, $cfilename, $fileComments='', $data=false){ + $this->ensureFh(); // $filename can be a local file OR the data wich will be compressed if(substr($cfilename, -1)=='/'){ @@ -77,21 +80,21 @@ class dZip{ $details['modtime'] = bindec("$lastmod_timeH$lastmod_timeM$lastmod_timeS"); $details['moddate'] = bindec("$lastmod_dateY$lastmod_dateM$lastmod_dateD"); - $details['offset'] = ftell($fh); - fwrite($fh, $this->zipSignature); - fwrite($fh, pack('s', $details['vneeded'])); // version_needed - fwrite($fh, pack('s', $details['bitflag'])); // general_bit_flag - fwrite($fh, pack('s', $details['cmethod'])); // compression_method - fwrite($fh, pack('s', $details['modtime'])); // lastmod_time - fwrite($fh, pack('s', $details['moddate'])); // lastmod_date - fwrite($fh, pack('V', $details['crc_32'])); // crc-32 - fwrite($fh, pack('I', $details['comsize'])); // compressed_size - fwrite($fh, pack('I', $details['uncsize'])); // uncompressed_size - fwrite($fh, pack('s', strlen($cfilename))); // file_name_length - fwrite($fh, pack('s', 0)); // extra_field_length - fwrite($fh, $cfilename); // file_name + $details['offset'] = ftell($this->fh); + fwrite($this->fh, $this->zipSignature); + fwrite($this->fh, pack('s', $details['vneeded'])); // version_needed + fwrite($this->fh, pack('s', $details['bitflag'])); // general_bit_flag + fwrite($this->fh, pack('s', $details['cmethod'])); // compression_method + fwrite($this->fh, pack('s', $details['modtime'])); // lastmod_time + fwrite($this->fh, pack('s', $details['moddate'])); // lastmod_date + fwrite($this->fh, pack('V', $details['crc_32'])); // crc-32 + fwrite($this->fh, pack('I', $details['comsize'])); // compressed_size + fwrite($this->fh, pack('I', $details['uncsize'])); // uncompressed_size + fwrite($this->fh, pack('s', strlen($cfilename))); // file_name_length + fwrite($this->fh, pack('s', 0)); // extra_field_length + fwrite($this->fh, $cfilename); // file_name // ignoring extra_field - fwrite($fh, $zdata); + fwrite($this->fh, $zdata); // Append it to central dir $details['external_attributes'] = (substr($cfilename, -1)=='/'&&!$zdata)?16:32; // Directory or file name @@ -103,9 +106,8 @@ class dZip{ $this->centraldirs[$filename][$property] = $value; } Function save($zipComments=''){ - if(!($fh = $this->fh)) - $fh = fopen($this->filename, $this->overwrite?'w':'a+'); - + $this->ensureFh(); + $cdrec = ""; foreach($this->centraldirs as $filename=>$cd){ $cdrec .= $this->dirSignature; @@ -128,21 +130,21 @@ class dZip{ $cdrec .= $filename; $cdrec .= $cd['comments']; } - $before_cd = ftell($fh); - fwrite($fh, $cdrec); + $before_cd = ftell($this->fh); + fwrite($this->fh, $cdrec); // end of central dir - fwrite($fh, $this->dirSignatureE); - fwrite($fh, pack('v', 0)); // number of this disk - fwrite($fh, pack('v', 0)); // number of the disk with the start of the central directory - fwrite($fh, pack('v', $this->files_count)); // total # of entries "on this disk" - fwrite($fh, pack('v', $this->files_count)); // total # of entries overall - fwrite($fh, pack('V', strlen($cdrec))); // size of central dir - fwrite($fh, pack('V', $before_cd)); // offset to start of central dir - fwrite($fh, pack('v', strlen($zipComments))); // .zip file comment length - fwrite($fh, $zipComments); + fwrite($this->fh, $this->dirSignatureE); + fwrite($this->fh, pack('v', 0)); // number of this disk + fwrite($this->fh, pack('v', 0)); // number of the disk with the start of the central directory + fwrite($this->fh, pack('v', $this->files_count)); // total # of entries "on this disk" + fwrite($this->fh, pack('v', $this->files_count)); // total # of entries overall + fwrite($this->fh, pack('V', strlen($cdrec))); // size of central dir + fwrite($this->fh, pack('V', $before_cd)); // offset to start of central dir + fwrite($this->fh, pack('v', strlen($zipComments))); // .zip file comment length + fwrite($this->fh, $zipComments); - fclose($fh); + fclose($this->fh); } // Private -- GitLab