From dd6c671b9d206cd89b823d9b6bcfd9c38aa6fc36 Mon Sep 17 00:00:00 2001
From: Aurelien Bompard <aurelien@bompard.org>
Date: Thu, 28 Feb 2008 00:14:47 +0100
Subject: [PATCH] multiple fixes for the zip library

 1. A recursive zip function. "$basedir" will be stripped from the path in the
    archive.

 2. and 3. : Documentation

 4. : Avoid a PHP "Notice"

 5., 6. and 7. : handle ODT files where some headers are equal to 0.

 8.: Avoid a PHP "Notice"

darcs-hash:20080227231447-5a6cd-45ff763079ad0a7d8f4029639cf53fe10faa4389.gz
---
 inc/ZipLib.class.php | 50 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 7 deletions(-)

diff --git a/inc/ZipLib.class.php b/inc/ZipLib.class.php
index cb1a26e75..a1d266673 100644
--- a/inc/ZipLib.class.php
+++ b/inc/ZipLib.class.php
@@ -53,6 +53,34 @@ class ZipLib
   return $ret;
  }
 
+ /**
+  * Zips recursively the $folder directory, from the $basedir directory
+  */
+ function Compress($folder, $basedir=null, $parent=null)
+ {
+  $full_path = $basedir."/".$parent.$folder;
+  $zip_path = $parent.$folder;
+  if ($zip_path) {
+   $zip_path .= "/";
+   $this->add_dir($zip_path);
+  }
+  $dir = new DirectoryIterator($full_path);
+  foreach($dir as $file) {
+   if(!$file->isDot()) {
+    $filename = $file->getFilename();
+    if($file->isDir()) {
+     $this->Compress($filename, $basedir, $zip_path);
+    } else {
+     $content = join('', file($full_path.'/'.$filename));
+     $this->add_File($content, $zip_path.$filename);
+    }
+   }
+  }
+ }
+
+ /**
+  * Returns the Zip file
+  */
  function get_file()
  {
    $data = implode('', $this -> datasec);
@@ -85,6 +113,9 @@ class ZipLib
    $this -> dirs[] = $name;
  }
 
+ /**
+  * Add a file named $name from a string $data
+  */
  function add_File($data, $name, $compact = 1)
  {
    $name     = str_replace('\\', '/', $name);
@@ -138,6 +169,9 @@ class ZipLib
     ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
  }
 
+ /**
+  * Extract a zip file $zn to the $to directory
+  */
  function Extract ( $zn, $to, $index = Array(-1) )
  {
    if(!@is_dir($to)) $this->_mkdir($to);
@@ -147,7 +181,7 @@ class ZipLib
    $pos_entry = $cdir['offset'];
 
    if(!is_array($index)){ $index = array($index);  }
-   for($i=0; $index[$i];$i++){
+   for($i=0; isset($index[$i]);$i++){
      if(intval($index[$i])!=$index[$i]||$index[$i]>$cdir['entries'])
       return(-1);
    }
@@ -166,7 +200,7 @@ class ZipLib
    return $stat;
  }
 
-  function ReadFileHeader($zip)
+  function ReadFileHeader($zip, $header)
   {
     $binary_data = fread($zip, 30);
     $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);
@@ -176,9 +210,11 @@ class ZipLib
       $header['extra'] = fread($zip, $data['extra_len']);
     } else { $header['extra'] = ''; }
 
-    $header['compression'] = $data['compression'];$header['size'] = $data['size'];
-    $header['compressed_size'] = $data['compressed_size'];
-    $header['crc'] = $data['crc']; $header['flag'] = $data['flag'];
+    $header['compression'] = $data['compression'];
+    foreach (array('size','compressed_size','crc') as $hd) { // On ODT files, these headers are 0. Keep the previous value.
+        if ($data[$hd] != 0) $header[$hd] = $data[$hd];
+    }
+    $header['flag'] = $data['flag'];
     $header['mdate'] = $data['mdate'];$header['mtime'] = $data['mtime'];
 
     if ($header['mdate'] && $header['mtime']){
@@ -258,7 +294,7 @@ class ZipLib
 
  function ExtractFile($header,$to,$zip)
  {
-   $header = $this->readfileheader($zip);
+   $header = $this->readfileheader($zip, $header);
 
    if(substr($to,-1)!="/") $to.="/";
    if(substr($header['filename'],-1)=="/")
@@ -276,7 +312,7 @@ class ZipLib
 //   }
   if (!$this->_mkdir($to.dirname($header['filename']))) return (-1);   //--CS
 
-  if (!($header['external']==0x41FF0010)&&!($header['external']==16))
+  if (!array_key_exists("external", $header) || (!($header['external']==0x41FF0010)&&!($header['external']==16)))
   {
    if ($header['compression']==0)
    {
-- 
GitLab