1<?php 2 3$disapproval_ಠ_ಠ_of_php = 'unicode var'; 4 5$test = function($a) { $lambda = 1; } 6 7/** 8 * Zip class file 9 * 10 * @package fnord.bb 11 * @subpackage archive 12 */ 13 14// Unlock? 15if(!defined('UNLOCK') || !UNLOCK) 16 die(); 17 18// Load the parent archive class 19require_once(ROOT_PATH.'/classes/archive.class.php'); 20 21class Zip\Zippಠ_ಠ_ { 22 23} 24 25/** 26 * Zip class 27 * 28 * @author Manni <manni@fnord.name> 29 * @copyright Copyright (c) 2006, Manni 30 * @version 1.0 31 * @link http://www.pkware.com/business_and_developers/developer/popups/appnote.txt 32 * @link http://mannithedark.is-a-geek.net/ 33 * @since 1.0 34 * @package fnord.bb 35 * @subpackage archive 36 */ 37class Zip extends Archive { 38 /** 39 * Outputs the zip file 40 * 41 * This function creates the zip file with the dirs and files given. 42 * If the optional parameter $file is given, the zip file is will be 43 * saved at that location. Otherwise the function returns the zip file's content. 44 * 45 * @access public 46 * 47 * @link http://www.pkware.com/business_and_developers/developer/popups/appnote.txt 48 * @param string $filename The path where the zip file will be saved 49 * 50 * @return bool|string Returns either true if the fil is sucessfully created or the content of the zip file 51 */ 52 function out($filename = false) { 53 // Empty output 54 $file_data = array(); // Data of the file part 55 $cd_data = array(); // Data of the central directory 56 57 // Sort dirs and files by path length 58 uksort($this->dirs, 'sort_by_length'); 59 uksort($this->files, 'sort_by_length'); 60 61 // Handle dirs 62 foreach($this->dirs as $dir) { 63 $dir .= '/'; 64 // File part 65 66 // Reset dir data 67 $dir_data = ''; 68 69 // Local file header 70 $dir_data .= "\x50\x4b\x03\x04"; // Local file header signature 71 $dir_data .= pack("v", 10); // Version needed to extract 72 $dir_data .= pack("v", 0); // General purpose bit flag 73 $dir_data .= pack("v", 0); // Compression method 74 $dir_data .= pack("v", 0); // Last mod file time 75 $dir_data .= pack("v", 0); // Last mod file date 76 $dir_data .= pack("V", 0); // crc-32 77 $dir_data .= pack("V", 0); // Compressed size 78 $dir_data .= pack("V", 0); // Uncompressed size 79 $dir_data .= pack("v", strlen($dir)); // File name length 80 $dir_data .= pack("v", 0); // Extra field length 81 82 $dir_data .= $dir; // File name 83 $dir_data .= ''; // Extra field (is empty) 84 85 // File data 86 $dir_data .= ''; // Dirs have no file data 87 88 // Data descriptor 89 $dir_data .= pack("V", 0); // crc-32 90 $dir_data .= pack("V", 0); // Compressed size 91 $dir_data .= pack("V", 0); // Uncompressed size 92 93 // Save current offset 94 $offset = strlen(implode('', $file_data)); 95 96 // Append dir data to the file part 97 $file_data[] = $dir_data; 98 99 // Central directory 100 101 // Reset dir data 102 $dir_data = ''; 103 104 // File header 105 $dir_data .= "\x50\x4b\x01\x02"; // Local file header signature 106 $dir_data .= pack("v", 0); // Version made by 107 $dir_data .= pack("v", 10); // Version needed to extract 108 $dir_data .= pack("v", 0); // General purpose bit flag 109 $dir_data .= pack("v", 0); // Compression method 110 $dir_data .= pack("v", 0); // Last mod file time 111 $dir_data .= pack("v", 0); // Last mod file date 112 $dir_data .= pack("V", 0); // crc-32 113 $dir_data .= pack("V", 0); // Compressed size 114 $dir_data .= pack("V", 0); // Uncompressed size 115 $dir_data .= pack("v", strlen($dir)); // File name length 116 $dir_data .= pack("v", 0); // Extra field length 117 $dir_data .= pack("v", 0); // File comment length 118 $dir_data .= pack("v", 0); // Disk number start 119 $dir_data .= pack("v", 0); // Internal file attributes 120 $dir_data .= pack("V", 16); // External file attributes 121 $dir_data .= pack("V", $offset); // Relative offset of local header 122 123 $dir_data .= $dir; // File name 124 $dir_data .= ''; // Extra field (is empty) 125 $dir_data .= ''; // File comment (is empty) 126 127 /* 128 // Data descriptor 129 $dir_data .= pack("V", 0); // crc-32 130 $dir_data .= pack("V", 0); // Compressed size 131 $dir_data .= pack("V", 0); // Uncompressed size 132 */ 133 134 // Append dir data to the central directory data 135 $cd_data[] = $dir_data; 136 } 137 138 // Handle files 139 foreach($this->files as $name => $file) { 140 // Get values 141 $content = $file[0]; 142 143 // File part 144 145 // Reset file data 146 $fd = ''; 147 148 // Detect possible compressions 149 // Use deflate 150 if(function_exists('gzdeflate')) { 151 $method = 8; 152 153 // Compress file content 154 $compressed_data = gzdeflate($content); 155 156 // Use bzip2 157 } elseif(function_exists('bzcompress')) { 158 $method = 12; 159 160 // Compress file content 161 $compressed_data = bzcompress($content); 162 163 // No compression 164 } else { 165 $method = 0; 166 167 // Do not compress the content :P 168 $compressed_data = $content; 169 } 170 171 // Local file header 172 $fd .= "\x50\x4b\x03\x04"; // Local file header signature 173 $fd .= pack("v", 20); // Version needed to extract 174 $fd .= pack("v", 0); // General purpose bit flag 175 $fd .= pack("v", $method); // Compression method 176 $fd .= pack("v", 0); // Last mod file time 177 $fd .= pack("v", 0); // Last mod file date 178 $fd .= pack("V", crc32($content)); // crc-32 179 $fd .= pack("V", strlen($compressed_data)); // Compressed size 180 $fd .= pack("V", strlen($content)); // Uncompressed size 181 $fd .= pack("v", strlen($name)); // File name length 182 $fd .= pack("v", 0); // Extra field length 183 184 $fd .= $name; // File name 185 $fd .= ''; // Extra field (is empty) 186 187 // File data 188 $fd .= $compressed_data; 189 190 // Data descriptor 191 $fd .= pack("V", crc32($content)); // crc-32 192 $fd .= pack("V", strlen($compressed_data)); // Compressed size 193 $fd .= pack("V", strlen($content)); // Uncompressed size 194 195 // Save current offset 196 $offset = strlen(implode('', $file_data)); 197 198 // Append file data to the file part 199 $file_data[] = $fd; 200 201 // Central directory 202 203 // Reset file data 204 $fd = ''; 205 206 // File header 207 $fd .= "\x50\x4b\x01\x02"; // Local file header signature 208 $fd .= pack("v", 0); // Version made by 209 $fd .= pack("v", 20); // Version needed to extract 210 $fd .= pack("v", 0); // General purpose bit flag 211 $fd .= pack("v", $method); // Compression method 212 $fd .= pack("v", 0); // Last mod file time 213 $fd .= pack("v", 0); // Last mod file date 214 $fd .= pack("V", crc32($content)); // crc-32 215 $fd .= pack("V", strlen($compressed_data)); // Compressed size 216 $fd .= pack("V", strlen($content)); // Uncompressed size 217 $fd .= pack("v", strlen($name)); // File name length 218 $fd .= pack("v", 0); // Extra field length 219 $fd .= pack("v", 0); // File comment length 220 $fd .= pack("v", 0); // Disk number start 221 $fd .= pack("v", 0); // Internal file attributes 222 $fd .= pack("V", 32); // External file attributes 223 $fd .= pack("V", $offset); // Relative offset of local header 224 225 $fd .= $name; // File name 226 $fd .= ''; // Extra field (is empty) 227 $fd .= ''; // File comment (is empty) 228 229 /* 230 // Data descriptor 231 $fd .= pack("V", crc32($content)); // crc-32 232 $fd .= pack("V", strlen($compressed_data)); // Compressed size 233 $fd .= pack("V", strlen($content)); // Uncompressed size 234 */ 235 236 // Append file data to the central directory data 237 $cd_data[] = $fd; 238 } 239 240 // Digital signature 241 $digital_signature = ''; 242 $digital_signature .= "\x50\x4b\x05\x05"; // Header signature 243 $digital_signature .= pack("v", 0); // Size of data 244 $digital_signature .= ''; // Signature data (is empty) 245 246 $tmp_file_data = implode('', $file_data); // File data 247 $tmp_cd_data = implode('', $cd_data). // Central directory 248 $digital_signature; // Digital signature 249 250 // End of central directory 251 $eof_cd = ''; 252 $eof_cd .= "\x50\x4b\x05\x06"; // End of central dir signature 253 $eof_cd .= pack("v", 0); // Number of this disk 254 $eof_cd .= pack("v", 0); // Number of the disk with the start of the central directory 255 $eof_cd .= pack("v", count($cd_data)); // Total number of entries in the central directory on this disk 256 $eof_cd .= pack("v", count($cd_data)); // Total number of entries in the central directory 257 $eof_cd .= pack("V", strlen($tmp_cd_data)); // Size of the central directory 258 $eof_cd .= pack("V", strlen($tmp_file_data)); // Offset of start of central directory with respect to the starting disk number 259 $eof_cd .= pack("v", 0); // .ZIP file comment length 260 $eof_cd .= ''; // .ZIP file comment (is empty) 261 262 // Content of the zip file 263 $data = $tmp_file_data. 264 // $extra_data_record. 265 $tmp_cd_data. 266 $eof_cd; 267 268 // Return content? 269 if(!$filename) 270 return $data; 271 272 // Write to file 273 return file_put_contents($filename, $data); 274 } 275 276 /** 277 * Load a zip file 278 * 279 * This function loads the files and dirs from a zip file from the harddrive. 280 * 281 * @access public 282 * 283 * @param string $file The path to the zip file 284 * @param bool $reset Reset the files and dirs before adding the zip file's content? 285 * 286 * @return bool Returns true if the file was loaded sucessfully 287 */ 288 function load_file($file, $reset = true) { 289 // Check whether the file exists 290 if(!file_exists($file)) 291 return false; 292 293 // Load the files content 294 $content = @file_get_contents($file); 295 296 // Return false if the file cannot be opened 297 if(!$content) 298 return false; 299 300 // Read the zip 301 return $this->load_string($content, $reset); 302 } 303 304 /** 305 * Load a zip string 306 * 307 * This function loads the files and dirs from a string 308 * 309 * @access public 310 * 311 * @param string $string The string the zip is generated from 312 * @param bool $reset Reset the files and dirs before adding the zip file's content? 313 * 314 * @return bool Returns true if the string was loaded sucessfully 315 */ 316 function load_string($string, $reset = true) { 317 // Reset the zip? 318 if($reset) { 319 $this->dirs = array(); 320 $this->files = array(); 321 } 322 323 // Get the starting position of the end of central directory record 324 $start = strpos($string, "\x50\x4b\x05\x06"); 325 326 // Error 327 if($start === false) 328 die('Could not find the end of central directory record'); 329 330 // Get the ecdr 331 $eof_cd = substr($string, $start+4, 18); 332 333 // Unpack the ecdr infos 334 $eof_cd = unpack('vdisc1/'. 335 'vdisc2/'. 336 'ventries1/'. 337 'ventries2/'. 338 'Vsize/'. 339 'Voffset/'. 340 'vcomment_lenght', $eof_cd); 341 342 // Do not allow multi disc zips 343 if($eof_cd['disc1'] != 0) 344 die('multi disk stuff is not yet implemented :/'); 345 346 // Save the interesting values 347 $cd_entries = $eof_cd['entries1']; 348 $cd_size = $eof_cd['size']; 349 $cd_offset = $eof_cd['offset']; 350 351 // Get the central directory record 352 $cdr = substr($string, $cd_offset, $cd_size); 353 354 // Reset the position and the list of the entries 355 $pos = 0; 356 $entries = array(); 357 358 // Handle cdr 359 while($pos < strlen($cdr)) { 360 // Check header signature 361 // Digital signature 362 if(substr($cdr, $pos, 4) == "\x50\x4b\x05\x05") { 363 // Get digital signature size 364 $tmp_info = unpack('vsize', substr($cdr, $pos + 4, 2)); 365 366 // Read out the digital signature 367 $digital_sig = substr($header, $pos + 6, $tmp_info['size']); 368 369 break; 370 } 371 372 // Get file header 373 $header = substr($cdr, $pos, 46); 374 375 // Unpack the header information 376 $header_info = @unpack('Vheader/'. 377 'vversion_made_by/'. 378 'vversion_needed/'. 379 'vgeneral_purpose/'. 380 'vcompression_method/'. 381 'vlast_mod_time/'. 382 'vlast_mod_date/'. 383 'Vcrc32/'. 384 'Vcompressed_size/'. 385 'Vuncompressed_size/'. 386 'vname_length/'. 387 'vextra_length/'. 388 'vcomment_length/'. 389 'vdisk_number/'. 390 'vinternal_attributes/'. 391 'Vexternal_attributes/'. 392 'Voffset', 393 $header); 394 395 // Valid header? 396 if($header_info['header'] != 33639248) 397 return false; 398 399 // New position 400 $pos += 46; 401 402 // Read out the file name 403 $header_info['name'] = substr($cdr, $pos, $header_info['name_length']); 404 405 // New position 406 $pos += $header_info['name_length']; 407 408 // Read out the extra stuff 409 $header_info['extra'] = substr($cdr, $pos, $header_info['extra_length']); 410 411 // New position 412 $pos += $header_info['extra_length']; 413 414 // Read out the comment 415 $header_info['comment'] = substr($cdr, $pos, $header_info['comment_length']); 416 417 // New position 418 $pos += $header_info['comment_length']; 419 420 // Append this file/dir to the entry list 421 $entries[] = $header_info; 422 } 423 424 // Check whether all entries where read sucessfully 425 if(count($entries) != $cd_entries) 426 return false; 427 428 // Handle files/dirs 429 foreach($entries as $entry) { 430 // Is a dir? 431 if($entry['external_attributes'] & 16) { 432 $this->add_dir($entry['name']); 433 continue; 434 } 435 436 // Get local file header 437 $header = substr($string, $entry['offset'], 30); 438 439 // Unpack the header information 440 $header_info = @unpack('Vheader/'. 441 'vversion_needed/'. 442 'vgeneral_purpose/'. 443 'vcompression_method/'. 444 'vlast_mod_time/'. 445 'vlast_mod_date/'. 446 'Vcrc32/'. 447 'Vcompressed_size/'. 448 'Vuncompressed_size/'. 449 'vname_length/'. 450 'vextra_length', 451 $header); 452 453 // Valid header? 454 if($header_info['header'] != 67324752) 455 return false; 456 457 // Get content start position 458 $start = $entry['offset'] + 30 + $header_info['name_length'] + $header_info['extra_length']; 459 460 // Get the compressed data 461 $data = substr($string, $start, $header_info['compressed_size']); 462 463 // Detect compression type 464 switch($header_info['compression_method']) { 465 // No compression 466 case 0: 467 // Ne decompression needed 468 $content = $data; 469 break; 470 471 // Gzip 472 case 8: 473 if(!function_exists('gzinflate')) 474 return false; 475 476 // Uncompress data 477 $content = gzinflate($data); 478 break; 479 480 // Bzip2 481 case 12: 482 if(!function_exists('bzdecompress')) 483 return false; 484 485 // Decompress data 486 $content = bzdecompress($data); 487 break; 488 489 // Compression not supported -> error 490 default: 491 return false; 492 } 493 494 // Try to add file 495 if(!$this->add_file($entry['name'], $content)) 496 return false; 497 } 498 499 return true; 500 } 501} 502 503function &byref() { 504 $x = array(); 505 return $x; 506} 507 508// Test highlighting of magic methods and variables 509class MagicClass { 510 public $magic_str; 511 public $ordinary_str; 512 513 public function __construct($some_var) { 514 $this->magic_str = __FILE__; 515 $this->ordinary_str = $some_var; 516 } 517 518 public function __toString() { 519 return $this->magic_str; 520 } 521 522 public function nonMagic() { 523 return $this->ordinary_str; 524 } 525} 526 527$magic = new MagicClass(__DIR__); 528__toString(); 529$magic->nonMagic(); 530$magic->__toString(); 531 532 echo <<<EOF 533 534 Test the heredocs... 535 536 EOF; 537 538echo <<<"some_delimiter" 539more heredoc testing 540continues on this line 541some_delimiter; 542 543?> 544 545