Syntax Syntax
Source Source
File: wp-admin/includes/class-pclzip.php
function privReadEndCentralDir(&$p_central_dir) { $v_result=1; // ----- Go to the end of the zip file $v_size = filesize($this->zipname); @fseek($this->zip_fd, $v_size); if (@ftell($this->zip_fd) != $v_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); // ----- Return return PclZip::errorCode(); } // ----- First try : look if this is an archive with no commentaries (most of the time) // in this case the end of central dir is at 22 bytes of the file end $v_found = 0; if ($v_size > 26) { @fseek($this->zip_fd, $v_size-22); if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); // ----- Return return PclZip::errorCode(); } // ----- Read for bytes $v_binary_data = @fread($this->zip_fd, 4); $v_data = @unpack('Vid', $v_binary_data); // ----- Check signature if ($v_data['id'] == 0x06054b50) { $v_found = 1; } $v_pos = ftell($this->zip_fd); } // ----- Go back to the maximum possible size of the Central Dir End Record if (!$v_found) { $v_maximum_size = 65557; // 0xFFFF + 22; if ($v_maximum_size > $v_size) $v_maximum_size = $v_size; @fseek($this->zip_fd, $v_size-$v_maximum_size); if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); // ----- Return return PclZip::errorCode(); } // ----- Read byte per byte in order to find the signature $v_pos = ftell($this->zip_fd); $v_bytes = 0x00000000; while ($v_pos < $v_size) { // ----- Read a byte $v_byte = @fread($this->zip_fd, 1); // ----- Add the byte //$v_bytes = ($v_bytes << 8) | Ord($v_byte); // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); // ----- Compare the bytes if ($v_bytes == 0x504b0506) { $v_pos++; break; } $v_pos++; } // ----- Look if not found end of central dir if ($v_pos == $v_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); // ----- Return return PclZip::errorCode(); } } // ----- Read the first 18 bytes of the header $v_binary_data = fread($this->zip_fd, 18); // ----- Look for invalid block size if (strlen($v_binary_data) != 18) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); // ----- Return return PclZip::errorCode(); } // ----- Extract the values $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); // ----- Check the global size if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { // ----- Removed in release 2.2 see readme file // The check of the file size is a little too strict. // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. // While decrypted, zip has training 0 bytes if (0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'The central dir is not at the end of the archive.' .' Some trailing bytes exists after the archive.'); // ----- Return return PclZip::errorCode(); } } // ----- Get comment if ($v_data['comment_size'] != 0) { $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); } else $p_central_dir['comment'] = ''; $p_central_dir['entries'] = $v_data['entries']; $p_central_dir['disk_entries'] = $v_data['disk_entries']; $p_central_dir['offset'] = $v_data['offset']; $p_central_dir['size'] = $v_data['size']; $p_central_dir['disk'] = $v_data['disk']; $p_central_dir['disk_start'] = $v_data['disk_start']; // TBC //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { //} // ----- Return return $v_result; }