php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77069 stream filter loses final block of data
Submitted: 2018-10-26 18:45 UTC Modified: 2020-08-18 11:31 UTC
Votes:4
Avg. Score:4.2 ± 0.8
Reproduced:4 of 4 (100.0%)
Same Version:2 (50.0%)
Same OS:2 (50.0%)
From: fisharebest at gmail dot com Assigned: cmb (profile)
Status: Closed Package: Streams related
PHP Version: 7.2.11 OS: *
Private report: No CVE-ID: None
 [2018-10-26 18:45 UTC] fisharebest at gmail dot com
Description:
------------
I'm using a stream filter to process data.

The test case below (also available at https://3v4l.org/kaeRJ) shows a stream filter that reverses the text on each line.

Since PHP 7.2, the final block of data is not included in the output.

My initial debugging suggests an issue with the $closing parameter.  It should be set to true when processing the final block of data.  Since PHP 7.2, it is always false.

It worked for PHP 5.5.21 -> 7.1.
It fails for PHP 7.2 and 7.3.
It fails for PHP <= 5.5.20

Test script:
---------------
<?php
class MyFilter extends php_user_filter {
    private $data = '';

    public function filter($in, $out, &$consumed, $closing) {
        $return = PSFS_FEED_ME;

        // While input data is available, continue to read it.
        while ($bucket_in = stream_bucket_make_writeable($in)) {
            $this->data .= $bucket_in->data;
            $consumed   += $bucket_in->datalen;

            // Process whole lines.
            while (preg_match('/(.*?)[\r\n]+(.*)/s', $this->data, $match) === 1) {
                list(, $data, $this->data) = $match;
                // Send this record output.
                $data       = strrev($data) . PHP_EOL;
                $bucket_out = stream_bucket_new($this->stream, $data);
                $return     = PSFS_PASS_ON;
                stream_bucket_append($out, $bucket_out);
            }
        }

        // Process the final line.
        if ($closing && $this->data !== '') {
            $data       = strrev($this->data) . PHP_EOL;
            $bucket_out = stream_bucket_new($this->stream, $data);
            $return     = PSFS_PASS_ON;
            stream_bucket_append($out, $bucket_out);
        }

        return $return;
    }
}

stream_filter_register('my-filter', 'MyFilter');

$input = "Line one\nLine two\nLine three";

$stream = fopen('data://text/plain,' . $input, 'r');
stream_filter_append($stream, 'my-filter');

$output = '';
while (!feof($stream)) {
    $output .= fread($stream, 16);
}
fclose($stream);

echo $output;


Expected result:
----------------
eno eniL
owt eniL
eerht eniL

Actual result:
--------------
eno eniL
owt eniL


Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-10-27 13:43 UTC] cmb@php.net
FWIW: this behavioral change has been introduced with commit
0a45e8f[1] which fixed bug #75515.

[1] <http://git.php.net/?p=php-src.git;a=commit;h=0a45e8f096a04464bda6277c6f3d0b5461737a27>
 [2020-08-17 15:04 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #77069: stream filter loses final block of data
On GitHub:  https://github.com/php/php-src/pull/6001
Patch:      https://github.com/php/php-src/pull/6001.patch
 [2020-08-17 15:07 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 [2020-08-18 11:31 UTC] cmb@php.net
-Status: Assigned +Status: Verified -Operating System: Linux and OSX +Operating System: *
 [2020-12-08 10:50 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=65f5573bc82108bbaf2727ffa11575f3292d736f
Log: Fix #77069: stream filter loses final block of data
 [2020-12-08 10:50 UTC] cmb@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Fri Apr 16 08:01:23 2021 UTC