function PclZip::privReadEndCentralDir in Quiz 6.6
Same name and namespace in other branches
- 6.5 includes/moodle/lib/pclzip/pclzip.lib.php \PclZip::privReadEndCentralDir()
6 calls to PclZip::privReadEndCentralDir()
- PclZip::privAdd in includes/
moodle/ lib/ pclzip/ pclzip.lib.php - PclZip::privDeleteByRule in includes/
moodle/ lib/ pclzip/ pclzip.lib.php - PclZip::privExtractByRule in includes/
moodle/ lib/ pclzip/ pclzip.lib.php - PclZip::privList in includes/
moodle/ lib/ pclzip/ pclzip.lib.php - PclZip::privMerge in includes/
moodle/ lib/ pclzip/ pclzip.lib.php
File
- includes/
moodle/ lib/ pclzip/ pclzip.lib.php, line 4392
Class
Code
function privReadEndCentralDir(&$p_central_dir) {
//--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", "");
$v_result = 1;
// ----- Go to the end of the zip file
$v_size = filesize($this->zipname);
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size");
@fseek($this->zip_fd, $v_size);
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\'');
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
//--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
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) {
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment');
@fseek($this->zip_fd, $v_size - 22);
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\'');
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
//--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
return PclZip::errorCode();
}
// ----- Read for bytes
$v_binary_data = @fread($this->zip_fd, 4);
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
$v_data = @unpack('Vid', $v_binary_data);
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
// ----- Check signature
if ($v_data['id'] == 0x6054b50) {
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position.");
$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) {
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir');
$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
//--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
return PclZip::errorCode();
}
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\'');
// ----- Read byte per byte in order to find the signature
$v_pos = ftell($this->zip_fd);
$v_bytes = 0x0;
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);
// ----- Compare the bytes
if ($v_bytes == 0x504b0506) {
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\'');
$v_pos++;
break;
}
$v_pos++;
}
// ----- Look if not found end of central dir
if ($v_pos == $v_size) {
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature");
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
// ----- Return
//--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
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) {
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : " . strlen($v_binary_data));
// ----- Return
//--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
return PclZip::errorCode();
}
// ----- Extract the values
////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'");
////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'");
$v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
// ----- Check the global size
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']);
if ($v_pos + $v_data['comment_size'] + 18 != $v_size) {
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive.");
// ----- 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
//--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
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'] = '';
}
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\'');
$p_central_dir['entries'] = $v_data['entries'];
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\'');
$p_central_dir['disk_entries'] = $v_data['disk_entries'];
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\'');
$p_central_dir['offset'] = $v_data['offset'];
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\'');
$p_central_dir['size'] = $v_data['size'];
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\'');
$p_central_dir['disk'] = $v_data['disk'];
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\'');
$p_central_dir['disk_start'] = $v_data['disk_start'];
//--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\'');
// TBC
//for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
// //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]);
//}
// ----- Return
//--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
return $v_result;
}