[wp-trac] [WordPress Trac] #11154: fread() code in pclzip doesn't check the result size
WordPress Trac
wp-trac at lists.automattic.com
Mon Nov 16 19:50:33 UTC 2009
#11154: fread() code in pclzip doesn't check the result size
-----------------------------+----------------------------------------------
Reporter: dobesv | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Unassigned
Component: Upgrade/Install | Version:
Severity: normal | Keywords:
-----------------------------+----------------------------------------------
Although this code from `class-pclzip.php` obviously works for most
people, when running inside of teh quercus/PHP interpreter, it fails
because quercus returns fewer bytes than requested if more than ~8000
bytes are requested.
{{{
if ($p_entry['compression'] == 0) {
// ----- Reading the file
$p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
echo '<p>Requested '.$p_entry['compressed_size'].' bytes
of file '.$p_entry['filename'].' and got '.strlen($p_string)' bytes.</p>';
}
else {
// ----- Reading the file
$v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
// ----- Decompress the file
if (($p_string = @gzinflate($v_data)) === FALSE) {
// TBC
}
echo '<p>Requested '.$p_entry['compressed_size'].' bytes
of file '.$p_entry['filename'].' and got '.strlen($v_data)' bytes.
Expecting uncompressed size '.$p_entry['size'].' and got
'.strlen($p_string).' bytes back from gzinflate.</p>';
}
}}}
For example when installing the flutter plugin within wordpress some files
are not read in full:
{{{
Requested 12787 bytes of file fresh-
page/thirdparty/swfupload/swfupload.swf and got 8096
Requested 10020 bytes of file fresh-page/thirdparty/swfupload/swfupload.js
and got 8097
}}}
It does seem like Quercus is behaving differently than the standard PHP
distribution on this one, in that with a normal PHP executable it would be
guaranteed to return all the bytes from a local file unless there was an
EOF, so I'll also take this up with the folks at Quercus.
My suggestion would be to add these reliable versions of fread and fwrite
to file.php (or somewhere similarly suitable) and replace all calls to
fread() or fwrite() that *assume* a full write or full read with calls to
these functions:
{{{
function fullwrite ($sd, $buf) {
$total = 0;
$len = strlen($buf);
while ($total < $len && ($written = fwrite($sd, $buf))) {
$total += $written;
$buf = substr($buf, $written);
}
return $total;
}
function fullread ($sd, $len) {
$ret = '';
$read = 0;
while ($read < $len && ($buf = fread($sd, $len - $read))) {
$read += strlen($buf);
$ret .= $buf;
}
return $ret;
}
}}}
This would be a bit more defensive in case of unusual environments, since
as documented fread() and fwrite() are *not* guaranteed to read or write
the full amount requested/provided.
--
Ticket URL: <http://core.trac.wordpress.org/ticket/11154>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list