Bug #81092 [Asn->Ver]: Calling fflush before stream_filter_remove results in corrupted stream
| From: | cmb@php.net | Date: | Thu, 03 Jun 2021 12:42:09 +0000 |
| Subject: | Bug #81092 [Asn->Ver]: Calling fflush before stream_filter_remove results in corrupted stream | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-234185@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=81092&edit=1
ID: 81092
Updated by: cmb@php.net
Reported by: mark at klb dot jp
Summary: Calling fflush before stream_filter_remove results
in corrupted stream
-Status: Assigned
+Status: Verified
Type: Bug
-Package: Bzip2 Related
+Package: Streams related
Operating System: Linux
-PHP Version: 8.0.6
+PHP Version: 7.4
Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
I can confirm that the script outputs int(0), but I get the same
result with PHP-7.4 either (regardless of explicitly calling
fflush()). Interestingly, using a str_repeat("*", 8192) instead
of random_bytes(8192) gives the expected result. If I use the
zlib.deflate and gzinflate(), I get an explicit:
Warning: gzinflate(): data error
So apparently a general stream (compression) filter issue.
Previous Comments:
------------------------------------------------------------------------
[2021-05-31 23:17:35] mark at klb dot jp
A couple notes:
I am not sure this is a bz2 issue, this could come from filters too. Outputting to php://output
using a filter and fflush()ing before removing the filter are conditions for this bug to happen.
The bz2 stream generated is cut partially, using bzcat will for example output:
php bug.php output | bzcat -tvv
(stdin):
[1: huff+mtf file ends unexpectedly
------------------------------------------------------------------------
[2021-05-31 18:34:32] mark at klb dot jp
Description:
------------
When using filters to output bzip2 compressed data, one may be tempted to call fflush() before
stream_filter_remove() to ensure all data has been written.
This used to work fine, however since php8, this causes the generated stream to be corrupt.
Test script:
---------------
<?php
if ($_SERVER['argv'][1]??'' == 'output') {
$stream = fopen('php://output', 'wb+');
$filter = stream_filter_append($stream, 'bzip2.compress', STREAM_FILTER_WRITE,
['blocks' => 9, 'work' => 0]);
fwrite($stream, random_bytes(8192));
fflush($stream);
stream_filter_remove($filter); // should call dtor
exit;
}
$script = $_SERVER['argv'][0];
$res = shell_exec('php '.escapeshellarg($script).' output'); // should output bz
encoded data
$data = bzdecompress($res);
var_dump(strlen($data));
Expected result:
----------------
int(8192)
Actual result:
--------------
int(0)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81092&edit=1