cvs: php-src /ext/standard user_filters.c /ext/standard/tests/file bug39551.phpt /main/streams filter.c
| From: | Antony Dovgal | 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