-
-
Notifications
You must be signed in to change notification settings - Fork 35
Description
A WordPress plugin that uses your library consistently gived an error when the tar file being created tried to add a directory to a tar archive. This because a call to fopen() a folder on Windows will fail (actually the docs say it may succeed on a folder: refsect1-function.fopen-notes, apparently on Linux it succeeds but that is not guaranteed, on Windows it doesn't)
However as a directory does not contain data and we only want to write the header block with a.o. the access rights, there’s no need to make that call to fopen(), nor write any contents block as a tar archive expects 0 or more file contents blocks after the header block, so it is correct to not write anything to the archive when the file size is 0 (empty file or directory).
I changed that part of code to only call fopen() when it is a file that is not empty. This prevents the fopen on Windows on a folder and it saves a few system calls (fopen(), feof(), fclose() for each folder and empty file) on all OS's.
php-archive/src/Tar.php, method addFile(),line 249 and further:
`
if ($this->closed) {
throw new ArchiveIOException('Archive has been closed, files can no longer be added');
}
// create file header
$this->writeFileHeader($fileinfo);
// write data, but only if we have data to write.
// note: on Windows fopen() on a directory will fail, so we prevent
// errors on Windows by testing if we have data to write.
if (!$fileinfo->getIsdir() && $fileinfo->getSize() > 0) {
$read = 0;
$fp = @fopen($file, 'rb');
if (!$fp) {
throw new ArchiveIOException('Could not open file for reading: ' . $file);
}
while (!feof($fp)) {
$data = fread($fp, 512);
$read += strlen($data);
if ($data === false) {
break;
}
if ($data === '') {
break;
}
$packed = pack("a512", $data);
$this->writebytes($packed);
}
fclose($fp);
if ($read != $fileinfo->getSize()) {
$this->close();
throw new ArchiveCorruptedException("The size of $file changed while reading, archive corrupted. read $read expected ".$fileinfo->getSize());
}
}
...`