cvs: php-src /ext/standard user_filters.c /ext/standard/tests/file bug39551.phpt /main/streams filter.c

From: Date: Tue, 21 Nov 2006 15:47:44 +0000
Subject: cvs: php-src /ext/standard user_filters.c /ext/standard/tests/file bug39551.phpt /main/streams filter.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-41665@lists.php.net to get a copy of this message
tony2001 Tue Nov 21 15:47:44 2006 UTC Added files: /php-src/ext/standard/tests/file bug39551.phpt Modified files: /php-src/main/streams filter.c /php-src/ext/standard user_filters.c Log: fix #39551 (Segfault with stream_bucket_new in user filter) also fixes several segfaults and leaks add test http://cvs.php.net/viewvc.cgi/php-src/main/streams/filter.c?r1=1.38&r2=1.39&diff_format=u Index: php-src/main/streams/filter.c diff -u php-src/main/streams/filter.c:1.38 php-src/main/streams/filter.c:1.39 --- php-src/main/streams/filter.c:1.38 Wed Oct 11 23:07:30 2006 +++ php-src/main/streams/filter.c Tue Nov 21 15:47:44 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filter.c,v 1.38 2006/10/11 23:07:30 pollita Exp $ */ +/* $Id: filter.c,v 1.39 2006/11/21 15:47:44 tony2001 Exp $ */ #include "php.h" #include "php_globals.h" @@ -103,6 +103,7 @@ bucket->buf_type = IS_STRING; bucket->is_persistent = is_persistent; bucket->refcount = 1; + bucket->brigade = NULL; return bucket; } @@ -140,6 +141,7 @@ bucket->buf_type = IS_UNICODE; bucket->is_persistent = is_persistent; bucket->refcount = 1; + bucket->brigade = NULL; return bucket; } http://cvs.php.net/viewvc.cgi/php-src/ext/standard/user_filters.c?r1=1.39&r2=1.40&diff_format=u Index: php-src/ext/standard/user_filters.c diff -u php-src/ext/standard/user_filters.c:1.39 php-src/ext/standard/user_filters.c:1.40 --- php-src/ext/standard/user_filters.c:1.39 Wed Oct 11 14:46:31 2006 +++ php-src/ext/standard/user_filters.c Tue Nov 21 15:47:44 2006 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: user_filters.c,v 1.39 2006/10/11 14:46:31 tony2001 Exp $ */ +/* $Id: user_filters.c,v 1.40 2006/11/21 15:47:44 tony2001 Exp $ */ #include "php.h" #include "php_globals.h" @@ -79,6 +79,15 @@ static zend_class_entry user_filter_class_entry; +static ZEND_RSRC_DTOR_FUNC(php_bucket_dtor) +{ + php_stream_bucket *bucket = (php_stream_bucket *)rsrc->ptr; + if (bucket) { + php_stream_bucket_delref(bucket TSRMLS_CC); + bucket = NULL; + } +} + PHP_MINIT_FUNCTION(user_filters) { zend_class_entry *php_user_filter; @@ -101,7 +110,7 @@ /* Filters will dispose of their brigades */ le_bucket_brigade = zend_register_list_destructors_ex(NULL, NULL, PHP_STREAM_BRIGADE_RES_NAME, module_number); /* Brigades will dispose of their buckets */ - le_bucket = zend_register_list_destructors_ex(NULL, NULL, PHP_STREAM_BUCKET_RES_NAME, module_number); + le_bucket = zend_register_list_destructors_ex(php_bucket_dtor, NULL, PHP_STREAM_BUCKET_RES_NAME, module_number); if (le_bucket_brigade == FAILURE) { return FAILURE; @@ -466,6 +475,13 @@ } else { php_stream_bucket_prepend(brigade, bucket TSRMLS_CC); } + + /* This is a hack necessary to accomodate situations where bucket is appended to the stream + * * multiple times. See bug35916.phpt for reference. + * */ + if (bucket->refcount == 1) { + bucket->refcount++; + } } /* }}} */ @@ -502,14 +518,19 @@ object_init(return_value); if (Z_TYPE_P(buffer) == IS_UNICODE) { - bucket = php_stream_bucket_new_unicode(stream, Z_USTRVAL_P(buffer), Z_USTRLEN_P(buffer), 0, php_stream_is_persistent(stream) TSRMLS_CC); + UChar *pbuffer = peumalloc(Z_USTRLEN_P(buffer), php_stream_is_persistent(stream)); + memcpy(pbuffer, buffer, UBYTES(Z_USTRLEN_P(buffer))); + + bucket = php_stream_bucket_new_unicode(stream, pbuffer, Z_USTRLEN_P(buffer), 1, php_stream_is_persistent(stream) TSRMLS_CC); - ZVAL_ADDREF(buffer); add_property_zval(return_value, "data", buffer); add_property_long(return_value, "datalen", Z_USTRLEN_P(buffer)); } else { + char *pbuffer = peumalloc(Z_STRLEN_P(buffer), php_stream_is_persistent(stream)); + memcpy(pbuffer, buffer, Z_STRLEN_P(buffer)); + convert_to_string(buffer); - bucket = php_stream_bucket_new(stream, Z_STRVAL_P(buffer), Z_STRLEN_P(buffer), 0, php_stream_is_persistent(stream) TSRMLS_CC); + bucket = php_stream_bucket_new(stream, pbuffer, Z_STRLEN_P(buffer), 1, php_stream_is_persistent(stream) TSRMLS_CC); add_property_zval(return_value, "data", buffer); add_property_long(return_value, "datalen", Z_STRLEN_P(buffer)); http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/bug39551.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/file/bug39551.phpt +++ php-src/ext/standard/tests/file/bug39551.phpt --TEST-- Bug #39551 (Segfault with stream_bucket_new in user filter) --FILE-- <?php $bucket = stream_bucket_new(fopen('php://temp', 'w+'), ''); class bucketFilter { public function filter($in, $out, &$consumed, $closing ){ $bucket = stream_bucket_new(fopen('php://temp', 'w+'), ''); stream_bucket_append($out, $bucket); return PSFS_PASS_ON; } } stream_filter_register('bucketfault', 'bucketFilter'); stream_filter_append($s = fopen('php://temp', 'r+'), 'bucketfault'); stream_get_contents($s); echo "Done\n"; ?> --EXPECTF-- Done --UEXPECTF-- Done Notice: Unknown: 0 character unicode buffer downcoded for binary stream runtime_encoding in Unknown on line 0

« previous php.cvs (#41665) next »