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 * @link http://pear.php.net/package/File_Archive 30 */ 31 32/** 33 * ZIP archive writer 34 */ 35class corrupt_zipmaker 36{ 37 /** 38 * @var int Current position in the writer 39 * @access private 40 */ 41 var $offset = 0; 42 43 /** 44 * @var string Optional comment to add to the zip 45 * @access private 46 */ 47 var $comment = ""; 48 49 /** 50 * @var string Data written at the end of the ZIP file 51 * @access private 52 */ 53 var $central = ""; 54 55 /** 56 * @var string Data written at the start of the ZIP file 57 * @access private 58 */ 59 var $start = ""; 60 61 /** 62 * Set a comment on the ZIP file 63 */ 64 function setComment($comment) { $this->comment = $comment; } 65 66 /** 67 * @param int $time Unix timestamp of the date to convert 68 * @return the date formatted as a ZIP date 69 */ 70 function getMTime($time) 71 { 72 $mtime = ($time !== null ? getdate($time) : getdate()); 73 $mtime = preg_replace( 74 "/(..){1}(..){1}(..){1}(..){1}/", 75 "\\x\\4\\x\\3\\x\\2\\x\\1", 76 dechex(($mtime['year']-1980<<25)| 77 ($mtime['mon' ]<<21)| 78 ($mtime['mday' ]<<16)| 79 ($mtime['hours' ]<<11)| 80 ($mtime['minutes']<<5)| 81 ($mtime['seconds']>>1))); 82 eval('$mtime = "'.$mtime.'";'); 83 return $mtime; 84 } 85 86 private function getFileEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $data, $corrupt, $fakecomp) 87 { 88 switch ($corrupt) { 89 case null : 90 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 91 $mtime . 92 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 93 $filename . 94 $data; 95 break; 96 case 'compress' : 97 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $fakecomp) . 98 $mtime . 99 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 100 $filename . 101 $data; 102 break; 103 case 'encrypt' : 104 $file = "PK\x03\x04\x14\x00\x01\x00" . pack('v', $compmethod) . 105 $mtime . 106 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 107 $filename . 108 $data; 109 break; 110 case 'crc32' : 111 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 112 $mtime . 113 pack("VVVvv", $crc32 + 1, $complength, $uncomplength, strlen($filename), 0x00) . 114 $filename . 115 $data; 116 break; 117 case 'complength' : 118 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 119 $mtime . 120 pack("VVVvv", $crc32, $complength + 1, $uncomplength, strlen($filename), 0x00) . 121 $filename . 122 $data; 123 break; 124 case 'uncomplength' : 125 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 126 $mtime . 127 pack("VVVvv", $crc32, $complength, $uncomplength - 1, strlen($filename), 0x00) . 128 $filename . 129 $data; 130 break; 131 case 'filename_len' : 132 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 133 $mtime . 134 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename) - 1, 0x00) . 135 $filename . 136 $data; 137 break; 138 case 'extra_len' : 139 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 140 $mtime . 141 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 1) . 142 $filename . 143 $data; 144 break; 145 case 'filename' : 146 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 147 $mtime . 148 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 149 substr($filename, 1) . 150 $data; 151 break; 152 case 'data' : 153 $file = "PK\x03\x04\x14\x00\x00\x00" . pack('v', $compmethod) . 154 $mtime . 155 pack("VVVvv", $crc32, $complength, $uncomplength, strlen($filename), 0x00) . 156 $filename . 157 substr($data, 1); 158 break; 159 } 160 return $file; 161 } 162 163 private function getCentralEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $comment, $corrupt, &$offset, $fakecomp) 164 { 165 settype($comment, 'string'); 166 switch ($corrupt) { 167 case null : 168 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 169 $mtime . 170 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 171 0x0000, $this->offset). 172 $filename . $comment; 173 $offset = strlen($central); 174 break; 175 case 'encrypt' : 176 $central = "PK\x01\x02\x00\x00\x14\x00\x01\x00" . pack('v', $compmethod) . 177 $mtime . 178 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 179 0x0000, $this->offset). 180 $filename . $comment; 181 $offset = strlen($central); 182 break; 183 case 'compress' : 184 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $fakecomp) . 185 $mtime . 186 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 187 0x0000, $this->offset). 188 $filename . $comment; 189 $offset = strlen($central); 190 break; 191 case 'crc32' : 192 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 193 $mtime . 194 pack("VVVvvvvvVV", $crc32 + 1, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 195 0x0000, $this->offset). 196 $filename . $comment; 197 $offset = strlen($central); 198 break; 199 case 'complength' : 200 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 201 $mtime . 202 pack("VVVvvvvvVV", $crc32, $complength - 1, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 203 0x0000, $this->offset). 204 $filename . $comment; 205 $offset = strlen($central); 206 break; 207 case 'uncomplength' : 208 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 209 $mtime . 210 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength - 1, strlen($filename), 0x00,strlen($comment),0x00,0x00, 211 0x0000, $this->offset). 212 $filename . $comment; 213 $offset = strlen($central); 214 break; 215 case 'filename_len' : 216 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 217 $mtime . 218 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename) - 1, 0x00,strlen($comment),0x00,0x00, 219 0x0000, $this->offset). 220 $filename . $comment; 221 $offset = strlen($central); 222 break; 223 case 'offset' : 224 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 225 $mtime . 226 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment),0x00,0x00, 227 0x0000, $this->offset - 1). 228 $filename . $comment; 229 $offset = strlen($central) - 1; 230 break; 231 case 'comment' : 232 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 233 $mtime . 234 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), 0x00,strlen($comment) + 1,0x00,0x00, 235 0x0000, $this->offset). 236 $filename . $comment; 237 $offset = strlen($central); 238 break; 239 case 'extralen1' : 240 $extra = 'nu' . 0xffff; // way huge size 241 $central = "PK\x01\x02\x00\x00\x14\x00\x00\x00" . pack('v', $compmethod) . 242 $mtime . 243 pack("VVVvvvvvVV", $crc32, $complength, $uncomplength, strlen($filename), strlen($extra),strlen($comment),0x00,0x00, 244 0x0000, $this->offset). 245 $filename . $extra . $comment; 246 $offset = strlen($central); 247 break; 248 } 249 return $central; 250 } 251 252 function addFile($filename, $mtime, $data, $comment = null, $compress = null, $filecorrupt = null, $centralcorrupt = null, $fakecomp = 1) 253 { 254 $mtime = $this->getMTime($mtime ? $mtime : null); 255 256 $uncomplength = strlen($data); 257 $crc32 = crc32($data) & 0xFFFFFFFF; 258 $compmethod = 0; 259 switch ($compress) { 260 case 'gz' : 261 $data = gzcompress($data); 262 $compmethod = 8; 263 break; 264 case 'bz2' : 265 $data = bzcompress($data); 266 $compmethod = 12; 267 break; 268 } 269 $complength = strlen($data); 270 271 $this->start .= ($file = $this->getFileEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $data, $filecorrupt, $fakecomp)); 272 273 $offset = 0; 274 $this->central .= $this->getCentralEntry($compmethod, $mtime, $crc32, $complength, $uncomplength, $filename, $comment, $centralcorrupt, $offset, $fakecomp); 275 276 $this->offset += $offset; 277 $this->count++; 278 } 279 280 function writeZip($zipfile, $corrupt = null) 281 { 282 $write = $this->start . $this->central; 283 switch ($corrupt) { 284 case null : 285 $write .= "PK\x05\x06\x00\x00\x00\x00" . 286 pack("vvVVv", $this->count, $this->count, 287 $this->offset, strlen($this->start), 288 strlen($this->comment)) . $this->comment; 289 break; 290 case 'disknumber' : 291 $write .= "PK\x05\x06\x01\x00\x01\x00" . 292 pack("vvVVv", $this->count, $this->count, 293 $this->offset, strlen($this->start), 294 strlen($this->comment)) . $this->comment; 295 break; 296 case 'count1' : 297 $write .= "PK\x05\x06\x00\x00\x00\x00" . 298 pack("vvVVv", $this->count + 1, $this->count, 299 $this->offset, strlen($this->start), 300 strlen($this->comment)) . $this->comment; 301 break; 302 case 'count2' : 303 $write .= "PK\x05\x06\x00\x00\x00\x00" . 304 pack("vvVVv", $this->count, $this->count + 1, 305 $this->offset, strlen($this->start), 306 strlen($this->comment)) . $this->comment; 307 break; 308 case 'cdir_offset' : 309 $write .= "PK\x05\x06\x00\x00\x00\x00" . 310 pack("vvVVv", $this->count, $this->count, 311 $this->offset, strlen($this->start) - 3, 312 strlen($this->comment)) . $this->comment; 313 break; 314 case 'cdir_len' : 315 $write .= "PK\x05\x06\x00\x00\x00\x00" . 316 pack("vvVVv", $this->count, $this->count, 317 $this->offset - 5, strlen($this->start), 318 strlen($this->comment)) . $this->comment; 319 break; 320 case 'comment' : 321 $write .= "PK\x05\x06\x00\x00\x00\x00" . 322 pack("vvVVv", $this->count, $this->count, 323 strlen($this->start), $this->offset + 1, 324 strlen($this->comment) + 1) . $this->comment; 325 break; 326 case 'none' : 327 } 328 file_put_contents($zipfile, $write); 329 } 330} 331?> 332