1<?php 2// this corrupt zip maker uses portions of Vincent Lascaux's File_Archive to create 3// specifically corrupted zip archives for unit-testing zip support in the phar extension 4// and was modified by Greg Beaver 5/** 6 * ZIP archive writer 7 * 8 * PHP versions 4 and 5 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA 23 * 24 * @category File Formats 25 * @package File_Archive 26 * @author Vincent Lascaux <vincentlascaux@php.net> 27 * @copyright 1997-2005 The PHP Group 28 * @license http://www.gnu.org/copyleft/lesser.html LGPL 29 * @version CVS: $Id$ 30 * @link http://pear.php.net/package/File_Archive 31 */ 32 33/** 34 * ZIP archive writer 35 */ 36class corrupt_zipmaker 37{ 38 /** 39 * @var int Current position in the writer 40 * @access private 41 */ 42 var $offset = 0; 43 44 /** 45 * @var string Optionnal comment to add to the zip 46 * @access private 47 */ 48 var $comment = ""; 49 50 /** 51 * @var string Data written at the end of the ZIP file 52 * @access private 53 */ 54 var $central = ""; 55 56 /** 57 * @var string Data written at the start of the ZIP file 58 * @access private 59 */ 60 var $start = ""; 61 62 /** 63 * Set a comment on the ZIP file 64 */ 65 function setComment($comment) { $this->comment = $comment; } 66 67 /** 68 * @param int $time Unix timestamp of the date to convert 69 * @return the date formated as a ZIP date 70 */ 71 function getMTime($time) 72 { 73 $mtime = ($time !== null ? getdate($time) : getdate()); 74 $mtime = preg_replace( 75 "/(..){1}(..){1}(..){1}(..){1}/", 76 "\\x\\4\\x\\3\\x\\2\\x\\1", 77 dechex(($mtime['year']-1980<<25)| 78 ($mtime['mon' ]<<21)| 79 ($mtime['mday' ]<<16)| 80 ($mtime['hours' ]<<11)| 81 ($mtime['minutes']<<5)| 82 ($mtime['seconds']>>1))); 83 eval('$mtime = "'.$mtime.'";'); 84 return $mtime; 85 } 86 87 private function getFileEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $data, $corrupt, $fakecomp) 88 { 89 switch ($corrupt) { 90 case null : 91 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 92 $mtime . 93 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 94 $filename . 95 $data; 96 break; 97 case 'compress' : 98 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $fakecomp) . 99 $mtime . 100 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 101 $filename . 102 $data; 103 break; 104 case 'encrypt' : 105 $file = "PK\x03\x04\x14\x00\x01\x00" . pack('v', $compmethod) . 106 $mtime . 107 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 108 $filename . 109 $data; 110 break; 111 case 'crc32' : 112 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 113 $mtime . 114 pack("VVVvv", $crc32 + 1, $complength, $uncomplength, strlen($filename), 0x00) . 115 $filename . 116 $data; 117 break; 118 case 'complength' : 119 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 120 $mtime . 121 pack("VVVvv", $crc32, $complength + 1, $uncomplength, strlen($filename), 0x00) . 122 $filename . 123 $data; 124 break; 125 case 'uncomplength' : 126 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 127 $mtime . 128 pack("VVVvv", $crc32, $complength, $uncomplength - 1, strlen($filename), 0x00) . 129 $filename . 130 $data; 131 break; 132 case 'filename_len' : 133 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 134 $mtime . 135 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename) - 1, 0x00) . 136 $filename . 137 $data; 138 break; 139 case 'extra_len' : 140 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 141 $mtime . 142 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 1) . 143 $filename . 144 $data; 145 break; 146 case 'filename' : 147 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 148 $mtime . 149 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 150 substr($filename, 1) . 151 $data; 152 break; 153 case 'data' : 154 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 155 $mtime . 156 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 157 $filename . 158 substr($data, 1); 159 break; 160 } 161 return $file; 162 } 163 164 private function getCentralEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $comment, $corrupt, &$offset, $fakecomp) 165 { 166 settype($comment, 'string'); 167 switch ($corrupt) { 168 case null : 169 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 170 $mtime . 171 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 172 0x0000, $this->offset). 173 $filename . $comment; 174 $offset = strlen($central); 175 break; 176 case 'encrypt' : 177 $central = "PK\x01\x02\x00\x00\x14\x00\x01\x00" . pack('v', $compmethod) . 178 $mtime . 179 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 180 0x0000, $this->offset). 181 $filename . $comment; 182 $offset = strlen($central); 183 break; 184 case 'compress' : 185 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $fakecomp) . 186 $mtime . 187 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 188 0x0000, $this->offset). 189 $filename . $comment; 190 $offset = strlen($central); 191 break; 192 case 'crc32' : 193 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 194 $mtime . 195 pack("VVVvvvvvVV", $crc32 + 1, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 196 0x0000, $this->offset). 197 $filename . $comment; 198 $offset = strlen($central); 199 break; 200 case 'complength' : 201 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 202 $mtime . 203 pack("VVVvvvvvVV", $crc32, $complength - 1, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 204 0x0000, $this->offset). 205 $filename . $comment; 206 $offset = strlen($central); 207 break; 208 case 'uncomplength' : 209 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 210 $mtime . 211 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength - 1, strlen($filename), 0x00,strlen($comment),0x00,0x00, 212 0x0000, $this->offset). 213 $filename . $comment; 214 $offset = strlen($central); 215 break; 216 case 'filename_len' : 217 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 218 $mtime . 219 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename) - 1, 0x00,strlen($comment),0x00,0x00, 220 0x0000, $this->offset). 221 $filename . $comment; 222 $offset = strlen($central); 223 break; 224 case 'offset' : 225 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 226 $mtime . 227 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 228 0x0000, $this->offset - 1). 229 $filename . $comment; 230 $offset = strlen($central) - 1; 231 break; 232 case 'comment' : 233 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 234 $mtime . 235 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment) + 1,0x00,0x00, 236 0x0000, $this->offset). 237 $filename . $comment; 238 $offset = strlen($central); 239 break; 240 case 'extralen1' : 241 $extra = 'nu' . 0xffff; // way huge size 242 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 243 $mtime . 244 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), strlen($extra),strlen($comment),0x00,0x00, 245 0x0000, $this->offset). 246 $filename . $extra . $comment; 247 $offset = strlen($central); 248 break; 249 } 250 return $central; 251 } 252 253 function addFile($filename, $mtime, $data, $comment = null, $compress = null, $filecorrupt = null, $centralcorrupt = null, $fakecomp = 1) 254 { 255 $mtime = $this->getMTime($mtime ? $mtime : null); 256 257 $uncomplength = strlen($data); 258 $crc32 = crc32($data) & 0xFFFFFFFF; 259 $compmethod = 0; 260 switch ($compress) { 261 case 'gz' : 262 $data = gzcompress($data); 263 $compmethod = 8; 264 break; 265 case 'bz2' : 266 $data = bzcompress($data); 267 $compmethod = 12; 268 break; 269 } 270 $complength = strlen($data); 271 272 $this->start .= ($file = $this->getFileEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $data, $filecorrupt, $fakecomp)); 273 274 $offset = 0; 275 $this->central .= $this->getCentralEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $comment, $centralcorrupt, $offset, $fakecomp); 276 277 $this->offset += $offset; 278 $this->count++; 279 } 280 281 function writeZip($zipfile, $corrupt = null) 282 { 283 $write = $this->start . $this->central; 284 switch ($corrupt) { 285 case null : 286 $write .= "PK\x05\x06\x00\x00\x00\x00" . 287 pack("vvVVv", $this->count, $this->count, 288 $this->offset, strlen($this->start), 289 strlen($this->comment)) . $this->comment; 290 break; 291 case 'disknumber' : 292 $write .= "PK\x05\x06\x01\x00\x01\x00" . 293 pack("vvVVv", $this->count, $this->count, 294 $this->offset, strlen($this->start), 295 strlen($this->comment)) . $this->comment; 296 break; 297 case 'count1' : 298 $write .= "PK\x05\x06\x00\x00\x00\x00" . 299 pack("vvVVv", $this->count + 1, $this->count, 300 $this->offset, strlen($this->start), 301 strlen($this->comment)) . $this->comment; 302 break; 303 case 'count2' : 304 $write .= "PK\x05\x06\x00\x00\x00\x00" . 305 pack("vvVVv", $this->count, $this->count + 1, 306 $this->offset, strlen($this->start), 307 strlen($this->comment)) . $this->comment; 308 break; 309 case 'cdir_offset' : 310 $write .= "PK\x05\x06\x00\x00\x00\x00" . 311 pack("vvVVv", $this->count, $this->count, 312 $this->offset, strlen($this->start) - 3, 313 strlen($this->comment)) . $this->comment; 314 break; 315 case 'cdir_len' : 316 $write .= "PK\x05\x06\x00\x00\x00\x00" . 317 pack("vvVVv", $this->count, $this->count, 318 $this->offset - 5, strlen($this->start), 319 strlen($this->comment)) . $this->comment; 320 break; 321 case 'comment' : 322 $write .= "PK\x05\x06\x00\x00\x00\x00" . 323 pack("vvVVv", $this->count, $this->count, 324 strlen($this->start), $this->offset + 1, 325 strlen($this->comment) + 1) . $this->comment; 326 break; 327 case 'none' : 328 } 329 file_put_contents($zipfile, $write); 330 } 331} 332?> 333