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