From 843423716b219d8c75bab6835a064a7d7030d937 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Feb 2014 23:05:22 +0400 Subject: [PATCH] Fixed user stream filters --- Zend/zend_API.c | 16 ++++++++-------- ext/standard/filters.c | 28 ++++++++++++++-------------- ext/standard/streamsfuncs.c | 1 + ext/standard/user_filters.c | 25 +++++++++++++------------ main/streams/filter.c | 2 +- main/streams/php_stream_filter_api.h | 2 +- 6 files changed, 38 insertions(+), 36 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index a6c9bb2437..2d7c8fdc08 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1655,7 +1655,7 @@ ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long zval z_key; ZVAL_LONG(&tmp, n); - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, 0 TSRMLS_CC); zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */ zval_ptr_dtor(&z_key); @@ -1669,7 +1669,7 @@ ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int zval z_key; ZVAL_BOOL(&tmp, b); - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, 0 TSRMLS_CC); zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */ zval_ptr_dtor(&z_key); @@ -1683,7 +1683,7 @@ ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRML zval z_key; ZVAL_NULL(&tmp); - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, 0 TSRMLS_CC); zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */ zval_ptr_dtor(&z_key); @@ -1697,7 +1697,7 @@ ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, zval z_key; ZVAL_RES(&tmp, r); - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, 0 TSRMLS_CC); zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */ zval_ptr_dtor(&z_key); @@ -1711,7 +1711,7 @@ ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, do zval z_key; ZVAL_DOUBLE(&tmp, d); - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, 0 TSRMLS_CC); zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */ zval_ptr_dtor(&z_key); @@ -1726,7 +1726,7 @@ ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, co //??? ZVAL_STRING(tmp, str, duplicate); ZVAL_STRING(&tmp, str); - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, 0 TSRMLS_CC); zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */ zval_ptr_dtor(&z_key); @@ -1741,7 +1741,7 @@ ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, c //??? ZVAL_STRINGL(tmp, str, length, duplicate); ZVAL_STRINGL(&tmp, str, length); - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, 0 TSRMLS_CC); zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */ zval_ptr_dtor(&z_key); @@ -1753,7 +1753,7 @@ ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval { zval z_key; - ZVAL_STRINGL(&z_key, key, key_len-1); + ZVAL_STRINGL(&z_key, key, key_len); Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, value, 0 TSRMLS_CC); zval_ptr_dtor(&z_key); return SUCCESS; diff --git a/ext/standard/filters.c b/ext/standard/filters.c index e99bd8d299..55737c97af 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -211,7 +211,7 @@ static php_stream_filter_status_t strfilter_strip_tags_filter( { php_stream_bucket *bucket; size_t consumed = 0; - php_strip_tags_filter *inst = (php_strip_tags_filter *) thisfilter->abstract; + php_strip_tags_filter *inst = (php_strip_tags_filter *) Z_PTR(thisfilter->abstract); while (buckets_in->head) { bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC); @@ -231,11 +231,11 @@ static php_stream_filter_status_t strfilter_strip_tags_filter( static void strfilter_strip_tags_dtor(php_stream_filter *thisfilter TSRMLS_DC) { - assert(thisfilter->abstract != NULL); + assert(Z_PTR(thisfilter->abstract) != NULL); - php_strip_tags_filter_dtor((php_strip_tags_filter *)thisfilter->abstract); + php_strip_tags_filter_dtor((php_strip_tags_filter *)Z_PTR(thisfilter->abstract)); - pefree(thisfilter->abstract, ((php_strip_tags_filter *)thisfilter->abstract)->persistent); + pefree(Z_PTR(thisfilter->abstract), ((php_strip_tags_filter *)Z_PTR(thisfilter->abstract))->persistent); } static php_stream_filter_ops strfilter_strip_tags_ops = { @@ -1742,7 +1742,7 @@ static php_stream_filter_status_t strfilter_convert_filter( { php_stream_bucket *bucket = NULL; size_t consumed = 0; - php_convert_filter *inst = (php_convert_filter *)thisfilter->abstract; + php_convert_filter *inst = (php_convert_filter *)Z_PTR(thisfilter->abstract); while (buckets_in->head != NULL) { bucket = buckets_in->head; @@ -1781,10 +1781,10 @@ out_failure: static void strfilter_convert_dtor(php_stream_filter *thisfilter TSRMLS_DC) { - assert(thisfilter->abstract != NULL); + assert(Z_PTR(thisfilter->abstract) != NULL); - php_convert_filter_dtor((php_convert_filter *)thisfilter->abstract); - pefree(thisfilter->abstract, ((php_convert_filter *)thisfilter->abstract)->persistent); + php_convert_filter_dtor((php_convert_filter *)Z_PTR(thisfilter->abstract)); + pefree(Z_PTR(thisfilter->abstract), ((php_convert_filter *)Z_PTR(thisfilter->abstract))->persistent); } static php_stream_filter_ops strfilter_convert_ops = { @@ -1859,7 +1859,7 @@ static php_stream_filter_status_t consumed_filter_filter( int flags TSRMLS_DC) { - php_consumed_filter_data *data = (php_consumed_filter_data *)(thisfilter->abstract); + php_consumed_filter_data *data = (php_consumed_filter_data *)Z_PTR(thisfilter->abstract); php_stream_bucket *bucket; size_t consumed = 0; @@ -1884,8 +1884,8 @@ static php_stream_filter_status_t consumed_filter_filter( static void consumed_filter_dtor(php_stream_filter *thisfilter TSRMLS_DC) { - if (thisfilter && thisfilter->abstract) { - php_consumed_filter_data *data = (php_consumed_filter_data*)thisfilter->abstract; + if (thisfilter && Z_PTR(thisfilter->abstract)) { + php_consumed_filter_data *data = (php_consumed_filter_data*)Z_PTR(thisfilter->abstract); pefree(data, data->persistent); } } @@ -2074,7 +2074,7 @@ static php_stream_filter_status_t php_chunked_filter( { php_stream_bucket *bucket; size_t consumed = 0; - php_chunked_filter_data *data = (php_chunked_filter_data *) thisfilter->abstract; + php_chunked_filter_data *data = (php_chunked_filter_data *) Z_PTR(thisfilter->abstract); while (buckets_in->head) { bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC); @@ -2092,8 +2092,8 @@ static php_stream_filter_status_t php_chunked_filter( static void php_chunked_dtor(php_stream_filter *thisfilter TSRMLS_DC) { - if (thisfilter && thisfilter->abstract) { - php_chunked_filter_data *data = (php_chunked_filter_data *) thisfilter->abstract; + if (thisfilter && Z_PTR(thisfilter->abstract)) { + php_chunked_filter_data *data = (php_chunked_filter_data *) Z_PTR(thisfilter->abstract); pefree(data, data->persistent); } } diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 35664d9a89..c066c60521 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1232,6 +1232,7 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) if (filter) { filter->res = ZEND_REGISTER_RESOURCE(NULL, filter, php_file_le_stream_filter()); + filter->res->gc.refcount++; RETURN_RES(filter->res); } else { RETURN_FALSE; diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index 392cc4bb51..cf3a47b938 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -137,7 +137,7 @@ PHP_RSHUTDOWN_FUNCTION(user_filters) static void userfilter_dtor(php_stream_filter *thisfilter TSRMLS_DC) { - zval *obj = (zval*)thisfilter->abstract; + zval *obj = &thisfilter->abstract; zval func_name; zval retval; @@ -146,7 +146,6 @@ static void userfilter_dtor(php_stream_filter *thisfilter TSRMLS_DC) return; } -//??? ZVAL_STRINGL(&func_name, "onclose", sizeof("onclose")-1, 0); ZVAL_STRINGL(&func_name, "onclose", sizeof("onclose")-1); call_user_function_ex(NULL, @@ -157,6 +156,7 @@ static void userfilter_dtor(php_stream_filter *thisfilter TSRMLS_DC) 0, NULL TSRMLS_CC); zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); /* kill the object */ zval_ptr_dtor(obj); @@ -172,7 +172,7 @@ php_stream_filter_status_t userfilter_filter( TSRMLS_DC) { int ret = PSFS_ERR_FATAL; - zval *obj = (zval*)thisfilter->abstract; + zval *obj = &thisfilter->abstract; zval func_name; zval retval; zval args[4]; @@ -190,7 +190,6 @@ php_stream_filter_status_t userfilter_filter( zval_ptr_dtor(&tmp); } -//??? ZVAL_STRINGL(&func_name, "filter", sizeof("filter")-1, 0); ZVAL_STRINGL(&func_name, "filter", sizeof("filter")-1); /* Setup calling arguments */ @@ -213,6 +212,8 @@ php_stream_filter_status_t userfilter_filter( 4, args, 0, NULL TSRMLS_CC); + zval_ptr_dtor(&func_name); + if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { convert_to_long(&retval); ret = Z_LVAL(retval); @@ -246,9 +247,9 @@ php_stream_filter_status_t userfilter_filter( /* filter resources are cleaned up by the stream destructor, * keeping a reference to the stream resource here would prevent it * from being destroyed properly */ -//??? ZVAL_STRINGL(&zpropname, "stream", sizeof("stream")-1, 0); ZVAL_STRINGL(&zpropname, "stream", sizeof("stream")-1); Z_OBJ_HANDLER_P(obj, unset_property)(obj, &zpropname, 0 TSRMLS_CC); + zval_ptr_dtor(&zpropname); zval_ptr_dtor(&args[3]); zval_ptr_dtor(&args[2]); @@ -347,7 +348,6 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, } /* invoke the constructor */ -//??? ZVAL_STRINGL(&func_name, "oncreate", sizeof("oncreate")-1, 0); ZVAL_STRINGL(&func_name, "oncreate", sizeof("oncreate")-1); call_user_function_ex(NULL, @@ -363,7 +363,7 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, zval_ptr_dtor(&retval); /* Kill the filter (safely) */ - filter->abstract = NULL; + ZVAL_UNDEF(&filter->abstract); php_stream_filter_free(filter TSRMLS_CC); /* Kill the object */ @@ -374,11 +374,11 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, } zval_ptr_dtor(&retval); } + zval_ptr_dtor(&func_name); /* set the filter property, this will be used during cleanup */ ZEND_REGISTER_RESOURCE(&zfilter, filter, le_userfilters); -//??? - filter->abstract = &obj; + ZVAL_COPY_VALUE(&filter->abstract, &obj); add_property_zval(&obj, "filter", &zfilter); /* add_property_zval increments the refcount which is unwanted here */ zval_ptr_dtor(&zfilter); @@ -390,8 +390,10 @@ static php_stream_filter_factory user_filter_factory = { user_filter_factory_create }; -static void filter_item_dtor(struct php_user_filter_data *fdat) +static void filter_item_dtor(zval *zv) { + struct php_user_filter_data *fdat = Z_PTR_P(zv); + efree(fdat); } /* {{{ proto object stream_bucket_make_writeable(resource brigade) @@ -544,8 +546,7 @@ PHP_FUNCTION(stream_get_filters) (key_flags = zend_hash_get_current_key_ex(filters_hash, &filter_name, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTENT; zend_hash_move_forward(filters_hash)) if (key_flags == HASH_KEY_IS_STRING) { -//??? - add_next_index_stringl(return_value, filter_name->val, filter_name->len, 1); + add_next_index_str(return_value, STR_COPY(filter_name)); } } /* It's okay to return an empty array if no filters are registered */ diff --git a/main/streams/filter.c b/main/streams/filter.c index 7a38c4fa3c..d2411c928a 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -299,7 +299,7 @@ PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, memset(filter, 0, sizeof(php_stream_filter)); filter->fops = fops; - filter->abstract = abstract; + Z_PTR(filter->abstract) = abstract; filter->is_persistent = persistent; return filter; diff --git a/main/streams/php_stream_filter_api.h b/main/streams/php_stream_filter_api.h index fe58a7d709..31e73ff6e4 100644 --- a/main/streams/php_stream_filter_api.h +++ b/main/streams/php_stream_filter_api.h @@ -107,7 +107,7 @@ typedef struct _php_stream_filter_chain { struct _php_stream_filter { php_stream_filter_ops *fops; - void *abstract; /* for use by filter implementation */ + zval abstract; /* for use by filter implementation */ php_stream_filter *next; php_stream_filter *prev; int is_persistent; -- 2.40.0