From: salsi at icosaedro dot it
Operating system: Slackware 14.1
PHP version: master-Git-2016-01-20 (Git)
Package: Streams related
Bug Type: Bug
Bug description:fread() does not detect decoding errors from filter zlib.inflate
Description:
------------
When the zlib.inflate filter is applied to a gzip stream, the fread()
function does not detect decoding errors on a corrupted file and keeps
instead returning the empty string or garbage. The following script
illustrates 3 distinct cases:
1. data corrupted
2. file truncated (commented away)
3. invalid CRC (commented away)
4. invalid length (commented away)
For comparison, the comments in the script also report what the 'gzip'
command tells about these corrupted files.
Also the gzdecode() function works properly and always triggers error
"data error".
In all the 4 cases above, no errors nor exceptions are generated,
although the data read are either corrupted or truncated.
Unsure if this bug is in some way related to bug #71263 (same issues
with the bzip2.decompress filter).
Test script:
---------------
<?php
// Bug report: zlib.inflate fails to detect corrupted data.
// Set a safe environment:
error_reporting(-1);
// Maps errors to ErrorException.
function my_error_handler($errno, $message)
{ throw new ErrorException($message); }
set_error_handler("my_error_handler");
/**
* Testing reading corrupted BZIP2 file using bzip2.decompress filter.
* @throws ErrorException
*/
function main()
{
$plain = "The quick brown fox jumps over the lazy dog.";
$fn = "test-zlib-inflate.gz";
$compressed = (string) gzencode($plain);
// 0. No corruption.
// $ php test-zlib-inflate.php
// --> read: string(44) "The quick brown fox jumps over the lazy dog."
// $ gzip test-zlib-inflate.gz
// (generates the file test-zlib-inflate with correct content)
// 1. Set a random byte in the middle of the compressed data.
// $ php test-zlib-inflate.php
// --> read: string(0) ""
// --> read: string(44) "The quick brown fox jumps over the lazx8dog."
// $ gzip test-zlib-inflate.gz
// gzip: test-zlib-inflate.gz: invalid compressed data--crc error
// $compressed[strlen($compressed) - 15] = 'X';
// 2. Truncate the compressed data.
// $ php test-zlib-inflate.php
// --> read: string(32) "The quick brown fox jumps over t"
// $ gzip test-zlib-inflate.gz
// gzip: test-zlib-inflate.gz: unexpected end of file
// $compressed = substr($compressed, 0, strlen($compressed) - 20);
// 3. Corrupted final CRC.
// $ php test-zlib-inflate.php
// --> read: string(0) ""
// --> read: string(44) "The quick brown fox jumps over the lazy dog."
// $ gzip test-zlib-inflate.gz
// gzip: test-zlib-inflate.gz: invalid compressed data--crc error
// $compressed[strlen($compressed)-5] = 'X';
// 4. Corrupted final length.
// $ php test-zlib-inflate.phpread: string(0) ""
// read: string(44) "The quick brown fox jumps over the lazy dog."
// $ gunzip test-zlib-inflate.gz
// gzip: test-zlib-inflate.gz: invalid compressed data--length error
$compressed[strlen($compressed)-2] = 'X';
// The gzdecode() function applied to the corrupted compressed data
always
// detects the error:
// --> gzdecode(): PHP Fatal error: Uncaught ErrorException:
gzdecode(): data error in ...
// echo "gzdecode(): ", rawurldecode(gzdecode($compressed)), "\n";
file_put_contents($fn, $compressed);
$r = fopen($fn, "r");
stream_filter_append($r, 'zlib.inflate', STREAM_FILTER_READ,
array('window' => 15+16));
while( ! feof($r) ){
$s = fread($r, 100);
echo "read: "; var_dump($s);
}
fclose($r);
// unlink($fn);
}
main();
?>
Expected result:
----------------
Fatal error: Uncaught ErrorException: fread() I/O error in ...
(or possibly a more descriptive error message similar to one of those
returned by the gzip command)
Actual result:
--------------
read: string(0) ""
read: string(44) "The quick brown fox jumps over the lazx8dog."
--
Edit bug report at https://bugs.php.net/bug.php?id=71417&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=71417&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=71417&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=71417&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=71417&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=71417&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=71417&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=71417&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=71417&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=71417&r=support
Expected behavior: https://bugs.php.net/fix.php?id=71417&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=71417&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=71417&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=71417&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=71417&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=71417&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=71417&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=71417&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=71417&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=71417&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=71417&r=mysqlcfg