]> granicus.if.org Git - php/commitdiff
add utility for creating corrupted zip archives for testing purposes
authorGreg Beaver <cellog@php.net>
Sat, 19 Apr 2008 05:15:24 +0000 (05:15 +0000)
committerGreg Beaver <cellog@php.net>
Sat, 19 Apr 2008 05:15:24 +0000 (05:15 +0000)
ext/phar/tests/zip/files/corrupt_zipmaker.php.inc [new file with mode: 0644]

diff --git a/ext/phar/tests/zip/files/corrupt_zipmaker.php.inc b/ext/phar/tests/zip/files/corrupt_zipmaker.php.inc
new file mode 100644 (file)
index 0000000..315cca0
--- /dev/null
@@ -0,0 +1,286 @@
+<?php
+// this corrupt zip maker uses portions of Vincent Lascaux's File_Archive to create
+// specifically corrupted zip archives for unit-testing zip support in the phar extension
+// and was modified by Greg Beaver
+/**
+ * ZIP archive writer
+ *
+ * PHP versions 4 and 5
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA
+ *
+ * @category   File Formats
+ * @package    File_Archive
+ * @author     Vincent Lascaux <vincentlascaux@php.net>
+ * @copyright  1997-2005 The PHP Group
+ * @license    http://www.gnu.org/copyleft/lesser.html  LGPL
+ * @version    CVS: $Id$
+ * @link       http://pear.php.net/package/File_Archive
+ */
+
+/**
+ * ZIP archive writer
+ */
+class corrupt_zipmaker
+{
+       /**
+       * @var int Current position in the writer
+       * @access private
+       */
+       var $offset = 0;
+
+       /**
+       * @var string Optionnal comment to add to the zip
+       * @access private
+       */
+       var $comment = "";
+
+       /**
+       * @var string Data written at the end of the ZIP file
+       * @access private
+       */
+       var $central = "";
+
+       /**
+       * @var string Data written at the start of the ZIP file
+       * @access private
+       */
+       var $start = "";
+
+       /**
+       * Set a comment on the ZIP file
+       */
+       function setComment($comment) { $this->comment = $comment; }
+
+       /**
+       * @param int $time Unix timestamp of the date to convert
+       * @return the date formated as a ZIP date
+       */
+       function getMTime($time)
+       {
+               $mtime = ($time !== null ? getdate($time) : getdate());
+               $mtime = preg_replace(
+                               "/(..){1}(..){1}(..){1}(..){1}/",
+                               "\\x\\4\\x\\3\\x\\2\\x\\1",
+                               dechex(($mtime['year']-1980<<25)|
+                                       ($mtime['mon'    ]<<21)|
+                                       ($mtime['mday'   ]<<16)|
+                                       ($mtime['hours'  ]<<11)|
+                                       ($mtime['minutes']<<5)|
+                                       ($mtime['seconds']>>1)));
+               eval('$mtime = "'.$mtime.'";');
+               return $mtime;
+       }
+
+       private function getFileEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $data, $corrupt)
+       {
+               switch ($corrupt) {
+                       case null :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) .
+                                               $filename .
+                                               $data;
+                               break;
+                       case 'crc32' :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32 + 1, $complength, $uncomplength, strlen($filename), 0x00) .
+                                               $filename .
+                                               $data;
+                               break;
+                       case 'complength' :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32, $complength + 1, $uncomplength, strlen($filename), 0x00) .
+                                               $filename .
+                                               $data;
+                               break;
+                       case 'uncomplength' :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32, $complength, $uncomplength - 1, strlen($filename), 0x00) .
+                                               $filename .
+                                               $data;
+                               break;
+                       case 'filename_len' :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename) - 1, 0x00) .
+                                               $filename .
+                                               $data;
+                               break;
+                       case 'extra_len' :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 1) .
+                                               $filename .
+                                               $data;
+                               break;
+                       case 'filename' :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) .
+                                               substr($filename, 1) .
+                                               $data;
+                               break;
+                       case 'data' :
+                               $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) .
+                                               $filename .
+                                               substr($data, 1);
+                               break;
+               }
+               return $file;
+       }
+
+       private function getCentralEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $comment, $corrupt, &$offset)
+       {
+               settype($comment, 'string');
+               switch ($corrupt) {
+                       case null :
+                               $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00,
+                                                       0x0000, $this->offset).
+                                               $filename . $comment;
+                               $offset = strlen($central);
+                               break;
+                       case 'crc32' :
+                               $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvvvvvVV", $crc32 + 1, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00,
+                                                       0x0000, $this->offset).
+                                               $filename . $comment;
+                               $offset = strlen($central);
+                               break;
+                       case 'complength' :
+                               $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvvvvvVV", $crc32, $complength - 1, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00,
+                                                       0x0000, $this->offset).
+                                               $filename . $comment;
+                               $offset = strlen($central);
+                               break;
+                       case 'uncomplength' :
+                               $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvvvvvVV", $crc32, $complength, $uncomplength - 1, strlen($filename), 0x00,strlen($comment),0x00,0x00,
+                                                       0x0000, $this->offset).
+                                               $filename . $comment;
+                               $offset = strlen($central);
+                               break;
+                       case 'filename_len' :
+                               $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename) - 1, 0x00,strlen($comment),0x00,0x00,
+                                                       0x0000, $this->offset).
+                                               $filename . $comment;
+                               $offset = strlen($central);
+                               break;
+                       case 'offset' :
+                               $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00,
+                                                       0x0000, $this->offset - 1).
+                                               $filename . $comment;
+                               $offset = strlen($central) - 1;
+                               break;
+                       case 'comment' :
+                               $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) .
+                                               $mtime .
+                                               pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment) + 1,0x00,0x00,
+                                                       0x0000, $this->offset).
+                                               $filename . $comment;
+                               $offset = strlen($central);
+                               break;
+               }
+               return $central;
+       }
+
+       function addFile($filename, $mtime, $data, $comment = null, $compress = null, $filecorrupt = null, $centralcorrupt = null)
+       {
+               $mtime = $this->getMTime($mtime ? $mtime : null);
+
+               $uncomplength = strlen($data);
+               $crc32 = crc32($data) & 0xFFFFFFFF;
+               $compmethod = 0;
+               switch ($compress) {
+                       case 'gz' :
+                               $data = gzcompress($data);
+                               $compmethod = 8;
+                               break;
+                       case 'bz2' :
+                               $data = bzcompress($data);
+                               $compmethod = 12;
+                               break;
+               }
+               $complength = strlen($data);
+
+               $this->start .= ($file = $this->getFileEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $data, $filecorrupt));
+
+               $offset = 0;
+               $this->central .= $this->getCentralEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $comment, $centralcorrupt, $offset);
+
+               $this->offset += $offset;
+               $this->count++;
+       }
+
+       function writeZip($zipfile, $corrupt = null)
+       {
+               $write = $this->start . $this->central;
+               switch ($corrupt) {
+                       case null :
+                               $write .= "PK\x05\x06\x00\x00\x00\x00" .
+                                       pack("vvVVv", $this->count, $this->count,
+                                       $this->offset, strlen($this->start),
+                                       strlen($this->comment)) . $this->comment;
+                               break;
+                       case 'count1' :
+                               $write .= "PK\x05\x06\x00\x00\x00\x00" .
+                                       pack("vvVVv", $this->count + 1, $this->count,
+                                       $this->offset, strlen($this->start),
+                                       strlen($this->comment)) . $this->comment;
+                               break;
+                       case 'count2' :
+                               $write .= "PK\x05\x06\x00\x00\x00\x00" .
+                                       pack("vvVVv", $this->count, $this->count + 1,
+                                       $this->offset, strlen($this->start),
+                                       strlen($this->comment)) . $this->comment;
+                               break;
+                       case 'cdir_len' :
+                               $write .= "PK\x05\x06\x00\x00\x00\x00" .
+                                       pack("vvVVv", $this->count, $this->count,
+                                       $this->offset, strlen($this->start) - 3,
+                                       strlen($this->comment)) . $this->comment;
+                               break;
+                       case 'cdir_offset' :
+                               $write .= "PK\x05\x06\x00\x00\x00\x00" .
+                                       pack("vvVVv", $this->count, $this->count,
+                                       $this->offset + 1, strlen($this->start),
+                                       strlen($this->comment)) . $this->comment;
+                               break;
+                       case 'comment' :
+                               $write .= "PK\x05\x06\x00\x00\x00\x00" .
+                                       pack("vvVVv", $this->count, $this->count,
+                                       strlen($this->start), $this->offset + 1,
+                                       strlen($this->comment) + 1) . $this->comment;
+                               break;
+               }
+               file_put_contents($zipfile, $write);
+       }
+}
+?>
\ No newline at end of file