Bug #75931 [NEW]: User stream filter is used after destruction
| From: | ivo at beerntea dot com | Date: | Wed, 07 Feb 2018 16:58:28 +0000 |
| Subject: | Bug #75931 [NEW]: User stream filter is used after destruction | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-213849@lists.php.net to get a copy of this message | ||
From: ivo at beerntea dot com
Operating system: Linux x64
PHP version: 7.2.2
Package: Streams related
Bug Type: Bug
Bug description:User stream filter is used after destruction
Description:
------------
A php_user_filter instance may be used by PHP's I/O functions after it
(and anything it references) has been destructed. This happens when the
stream the filter is bound to is closed while the process is exiting.
Allowing the stream to be garbage collected before the process exits
(uncomment
$out = NULL; in the example below) fixes the destruction
issue, but still leaves the last (closing) call to the filter method
with an invalid stream resource.
Manually closing the stream while it is still referenced results in
correct behavior: the final filter call has a valid stream resource and
destruction happens after the final call.
Also note that the constructor method is never called. It might be
unexpected that an object can be created without its constructor getting
called.
This is just a simplified test case. I was implementing a gzip stream
filter (with gzip header), using the deflate_init/deflate_add methods
when I ran into this problem. The deflate resource stored in a property
is also cleaned up before the final filter call happens, so there is no
opportunity to finalize the output.
Test script:
---------------
<?php
class test_filter extends php_user_filter {
public function __construct() {
fprintf(STDERR, "filter construct\n");
}
public function onCreate() {
fprintf(STDERR, "filter onCreate\n");
}
public function filter($in, $out, &$consumed, $closing) {
fprintf(STDERR, "filter consumed=$consumed closing=".($closing ?
'true' : 'false')." stream valid=".(is_resource($this->stream) ?
'true'
: 'false')."\n");
while ($bucket = stream_bucket_make_writeable($in)) {
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
public function onClose() {
fprintf(STDERR, "filter onClose\n");
}
public function __destruct() {
fprintf(STDERR, "filter destruct\n");
}
}
stream_filter_register('test_filter', 'test_filter');
$in = fopen('php://stdin', 'r');
$out = fopen('php://stdout', 'w');
stream_filter_append($out, 'test_filter', STREAM_FILTER_WRITE,
array());
stream_copy_to_stream($in, $out);
//fclose($out);
//$out = NULL;
Expected result:
----------------
filter construct
filter onCreate
filter consumed=0 closing=false stream valid=true
hello world
filter consumed=0 closing=true stream valid=true
filter onClose
filter destruct
Actual result:
--------------
filter onCreate
filter consumed=0 closing=false stream valid=true
hello world
filter destruct
filter consumed=0 closing=true stream valid=false
filter onClose
--
Edit bug report at https://bugs.php.net/bug.php?id=75931&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=75931&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=75931&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=75931&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=75931&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=75931&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=75931&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=75931&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=75931&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=75931&r=support
Expected behavior: https://bugs.php.net/fix.php?id=75931&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=75931&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=75931&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=75931&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=75931&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=75931&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=75931&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=75931&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=75931&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=75931&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=75931&r=mysqlcfg