1--TEST-- 2Bug #77069 (stream filter loses final block of data) 3--FILE-- 4<?php 5class MyFilter extends php_user_filter { 6 private $data = ''; 7 8 public function filter($in, $out, &$consumed, $closing): int { 9 $return = PSFS_FEED_ME; 10 11 // While input data is available, continue to read it. 12 while ($bucket_in = stream_bucket_make_writeable($in)) { 13 $this->data .= $bucket_in->data; 14 $consumed += $bucket_in->datalen; 15 16 // Process whole lines. 17 while (preg_match('/(.*?)[\r\n]+(.*)/s', $this->data, $match) === 1) { 18 list(, $data, $this->data) = $match; 19 // Send this record output. 20 $data = strrev($data) . PHP_EOL; 21 $bucket_out = stream_bucket_new($this->stream, $data); 22 $return = PSFS_PASS_ON; 23 stream_bucket_append($out, $bucket_out); 24 } 25 } 26 27 // Process the final line. 28 if ($closing && $this->data !== '') { 29 $data = strrev($this->data) . PHP_EOL; 30 $bucket_out = stream_bucket_new($this->stream, $data); 31 $return = PSFS_PASS_ON; 32 stream_bucket_append($out, $bucket_out); 33 } 34 35 return $return; 36 } 37} 38 39stream_filter_register('my-filter', 'MyFilter'); 40 41$input = "Line one\nLine two\nLine three"; 42 43$stream = fopen('data://text/plain,' . $input, 'r'); 44stream_filter_append($stream, 'my-filter'); 45 46$output = ''; 47while (!feof($stream)) { 48 $output .= fread($stream, 16); 49} 50fclose($stream); 51 52echo $output; 53?> 54--EXPECT-- 55eno eniL 56owt eniL 57eerht eniL 58