diff options
Diffstat (limited to 'ext/standard/user_filters.c')
-rw-r--r-- | ext/standard/user_filters.c | 545 |
1 files changed, 0 insertions, 545 deletions
diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c deleted file mode 100644 index 9dd786cdef..0000000000 --- a/ext/standard/user_filters.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2005 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: | - | Wez Furlong (wez@thebrainroom.com) | - | Sara Golemon (pollita@php.net) | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -#include "php.h" -#include "php_globals.h" -#include "ext/standard/basic_functions.h" -#include "ext/standard/file.h" - -#define PHP_STREAM_BRIGADE_RES_NAME "userfilter.bucket brigade" -#define PHP_STREAM_BUCKET_RES_NAME "userfilter.bucket" -#define PHP_STREAM_FILTER_RES_NAME "userfilter.filter" - -struct php_user_filter_data { - zend_class_entry *ce; - /* variable length; this *must* be last in the structure */ - char classname[1]; -}; - -/* to provide context for calling into the next filter from user-space */ -static int le_userfilters; -static int le_bucket_brigade; -static int le_bucket; - -#define GET_FILTER_FROM_OBJ() { \ - zval **tmp; \ - if (FAILURE == zend_hash_index_find(Z_OBJPROP_P(this_ptr), 0, (void**)&tmp)) { \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "filter property vanished"); \ - RETURN_FALSE; \ - } \ - ZEND_FETCH_RESOURCE(filter, php_stream_filter*, tmp, -1, "filter", le_userfilters); \ -} - -/* define the base filter class */ - -PHP_FUNCTION(user_filter_nop) -{ -} - -static zend_function_entry user_filter_class_funcs[] = { - PHP_NAMED_FE(filter, PHP_FN(user_filter_nop), NULL) - PHP_NAMED_FE(onCreate, PHP_FN(user_filter_nop), NULL) - PHP_NAMED_FE(onClose, PHP_FN(user_filter_nop), NULL) - { NULL, NULL, NULL } -}; - -static zend_class_entry user_filter_class_entry; - -PHP_MINIT_FUNCTION(user_filters) -{ - /* init the filter class ancestor */ - INIT_CLASS_ENTRY(user_filter_class_entry, "php_user_filter", user_filter_class_funcs); - if (NULL == zend_register_internal_class(&user_filter_class_entry TSRMLS_CC)) { - return FAILURE; - } - - /* init the filter resource; it has no dtor, as streams will always clean it up - * at the correct time */ - le_userfilters = zend_register_list_destructors_ex(NULL, NULL, PHP_STREAM_FILTER_RES_NAME, 0); - - if (le_userfilters == FAILURE) { - return FAILURE; - } - - /* 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); - - if (le_bucket_brigade == FAILURE) { - return FAILURE; - } - - REGISTER_LONG_CONSTANT("PSFS_PASS_ON", PSFS_PASS_ON, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PSFS_FEED_ME", PSFS_FEED_ME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PSFS_ERR_FATAL", PSFS_ERR_FATAL, CONST_CS | CONST_PERSISTENT); - - REGISTER_LONG_CONSTANT("PSFS_FLAG_NORMAL", PSFS_FLAG_NORMAL, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PSFS_FLAG_FLUSH_INC", PSFS_FLAG_FLUSH_INC, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PSFS_FLAG_FLUSH_CLOSE", PSFS_FLAG_FLUSH_CLOSE, CONST_CS | CONST_PERSISTENT); - - return SUCCESS; -} - -PHP_RSHUTDOWN_FUNCTION(user_filters) -{ - if (BG(user_filter_map)) { - zend_hash_destroy(BG(user_filter_map)); - efree(BG(user_filter_map)); - BG(user_filter_map) = NULL; - } - - return SUCCESS; -} - -static void userfilter_dtor(php_stream_filter *thisfilter TSRMLS_DC) -{ - zval *obj = (zval*)thisfilter->abstract; - zval func_name; - zval *retval = NULL; - - if (obj == NULL) { - /* If there's no object associated then there's nothing to dispose of */ - return; - } - - ZVAL_STRINGL(&func_name, "onclose", sizeof("onclose")-1, 0); - - call_user_function_ex(NULL, - &obj, - &func_name, - &retval, - 0, NULL, - 0, NULL TSRMLS_CC); - - if (retval) - zval_ptr_dtor(&retval); - - /* kill the object */ - zval_ptr_dtor(&obj); -} - -php_stream_filter_status_t userfilter_filter( - php_stream *stream, - php_stream_filter *thisfilter, - php_stream_bucket_brigade *buckets_in, - php_stream_bucket_brigade *buckets_out, - size_t *bytes_consumed, - int flags - TSRMLS_DC) -{ - int ret = PSFS_ERR_FATAL; - zval *obj = (zval*)thisfilter->abstract; - zval func_name; - zval *retval = NULL; - zval **args[4]; - zval *zclosing, *zconsumed, *zin, *zout, *zstream; - int call_result; - - if (FAILURE == zend_hash_find(Z_OBJPROP_P(obj), "stream", sizeof("stream"), (void**)&zstream)) { - /* Give the userfilter class a hook back to the stream */ - ALLOC_INIT_ZVAL(zstream); - php_stream_to_zval(stream, zstream); - add_property_zval(obj, "stream", zstream); - /* add_property_zval increments the refcount which is unwanted here */ - zval_ptr_dtor(&zstream); - } - - ZVAL_STRINGL(&func_name, "filter", sizeof("filter")-1, 0); - - /* Setup calling arguments */ - ALLOC_INIT_ZVAL(zin); - ZEND_REGISTER_RESOURCE(zin, buckets_in, le_bucket_brigade); - args[0] = &zin; - - ALLOC_INIT_ZVAL(zout); - ZEND_REGISTER_RESOURCE(zout, buckets_out, le_bucket_brigade); - args[1] = &zout; - - ALLOC_INIT_ZVAL(zconsumed); - if (bytes_consumed) { - ZVAL_LONG(zconsumed, *bytes_consumed); - } else { - ZVAL_NULL(zconsumed); - } - args[2] = &zconsumed; - - ALLOC_INIT_ZVAL(zclosing); - ZVAL_BOOL(zclosing, flags & PSFS_FLAG_FLUSH_CLOSE); - args[3] = &zclosing; - - call_result = call_user_function_ex(NULL, - &obj, - &func_name, - &retval, - 4, args, - 0, NULL TSRMLS_CC); - - if (call_result == SUCCESS && retval != NULL) { - convert_to_long(retval); - ret = Z_LVAL_P(retval); - } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to call filter function"); - } - - if (bytes_consumed) { - *bytes_consumed = Z_LVAL_P(zconsumed); - } - - if (retval) - zval_ptr_dtor(&retval); - zval_ptr_dtor(&zclosing); - zval_ptr_dtor(&zconsumed); - zval_ptr_dtor(&zout); - zval_ptr_dtor(&zin); - - return ret; -} - -static php_stream_filter_ops userfilter_ops = { - userfilter_filter, - userfilter_dtor, - "user-filter" -}; - -static php_stream_filter *user_filter_factory_create(const char *filtername, - zval *filterparams, int persistent TSRMLS_DC) -{ - struct php_user_filter_data *fdat = NULL; - php_stream_filter *filter; - zval *obj, *zfilter; - zval func_name; - zval *retval = NULL; - - /* some sanity checks */ - if (persistent) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "cannot use a user-space filter with a persistent stream"); - return NULL; - } - - /* determine the classname/class entry */ - if (FAILURE == zend_hash_find(BG(user_filter_map), (char*)filtername, - strlen(filtername), (void**)&fdat)) { - char *period; - - /* Userspace Filters using ambiguous wildcards could cause problems. - i.e.: myfilter.foo.bar will always call into myfilter.foo.* - never seeing myfilter.* - TODO: Allow failed userfilter creations to continue - scanning through the list */ - if ((period = strrchr(filtername, '.'))) { - char *wildcard; - - /* Search for wildcard matches instead */ - wildcard = estrdup(filtername); - period = wildcard + (period - filtername); - while (period) { - *period = '\0'; - strcat(wildcard, ".*"); - if (SUCCESS == zend_hash_find(BG(user_filter_map), wildcard, strlen(wildcard), (void**)&fdat)) { - period = NULL; - } else { - *period = '\0'; - period = strrchr(wildcard, '.'); - } - } - efree(wildcard); - } - if (fdat == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Err, filter \"%s\" is not in the user-filter map, but somehow the user-filter-factory was invoked for it!?", filtername); - return NULL; - } - } - - /* bind the classname to the actual class */ - if (fdat->ce == NULL) { - if (FAILURE == zend_lookup_class(fdat->classname, strlen(fdat->classname), - (zend_class_entry ***)&fdat->ce TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "user-filter \"%s\" requires class \"%s\", but that class is not defined", - filtername, fdat->classname); - return NULL; - } - fdat->ce = *(zend_class_entry**)fdat->ce; - - } - - filter = php_stream_filter_alloc(&userfilter_ops, NULL, 0); - if (filter == NULL) { - return NULL; - } - - /* create the object */ - ALLOC_ZVAL(obj); - object_init_ex(obj, fdat->ce); - ZVAL_REFCOUNT(obj) = 1; - PZVAL_IS_REF(obj) = 1; - - /* filtername */ - add_property_string(obj, "filtername", (char*)filtername, 1); - - /* and the parameters, if any */ - if (filterparams) { - add_property_zval(obj, "params", filterparams); - } else { - add_property_null(obj, "params"); - } - - /* invoke the constructor */ - ZVAL_STRINGL(&func_name, "oncreate", sizeof("oncreate")-1, 0); - - call_user_function_ex(NULL, - &obj, - &func_name, - &retval, - 0, NULL, - 0, NULL TSRMLS_CC); - - if (retval) { - if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) { - /* User reported filter creation error "return false;" */ - zval_ptr_dtor(&retval); - - /* Kill the filter (safely) */ - filter->abstract = NULL; - php_stream_filter_free(filter TSRMLS_CC); - - /* Kill the object */ - zval_ptr_dtor(&obj); - - /* Report failure to filter_alloc */ - return NULL; - } - zval_ptr_dtor(&retval); - } - - /* set the filter property, this will be used during cleanup */ - ALLOC_INIT_ZVAL(zfilter); - ZEND_REGISTER_RESOURCE(zfilter, filter, le_userfilters); - filter->abstract = obj; - add_property_zval(obj, "filter", zfilter); - /* add_property_zval increments the refcount which is unwanted here */ - zval_ptr_dtor(&zfilter); - - return filter; -} - -static php_stream_filter_factory user_filter_factory = { - user_filter_factory_create -}; - -static void filter_item_dtor(struct php_user_filter_data *fdat) -{ -} - -/* {{{ proto object stream_bucket_make_writeable(resource brigade) - Return a bucket object from the brigade for operating on */ -PHP_FUNCTION(stream_bucket_make_writeable) -{ - zval *zbrigade, *zbucket; - php_stream_bucket_brigade *brigade; - php_stream_bucket *bucket; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zbrigade) == FAILURE) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE(brigade, php_stream_bucket_brigade *, &zbrigade, -1, PHP_STREAM_BRIGADE_RES_NAME, le_bucket_brigade); - - ZVAL_NULL(return_value); - - if (brigade->head && (bucket = php_stream_bucket_make_writeable(brigade->head TSRMLS_CC))) { - ALLOC_INIT_ZVAL(zbucket); - ZEND_REGISTER_RESOURCE(zbucket, bucket, le_bucket); - object_init(return_value); - add_property_zval(return_value, "bucket", zbucket); - /* add_property_zval increments the refcount which is unwanted here */ - zval_ptr_dtor(&zbucket); - add_property_stringl(return_value, "data", bucket->buf, bucket->buflen, 1); - add_property_long(return_value, "datalen", bucket->buflen); - } -} -/* }}} */ - -/* {{{ php_stream_bucket_attach */ -static void php_stream_bucket_attach(int append, INTERNAL_FUNCTION_PARAMETERS) -{ - zval *zbrigade, *zobject; - zval **pzbucket, **pzdata; - php_stream_bucket_brigade *brigade; - php_stream_bucket *bucket; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zo", &zbrigade, &zobject) == FAILURE) { - RETURN_FALSE; - } - - if (FAILURE == zend_hash_find(Z_OBJPROP_P(zobject), "bucket", 7, (void**)&pzbucket)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Object has no bucket property"); - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE(brigade, php_stream_bucket_brigade *, &zbrigade, -1, PHP_STREAM_BRIGADE_RES_NAME, le_bucket_brigade); - ZEND_FETCH_RESOURCE(bucket, php_stream_bucket *, pzbucket, -1, PHP_STREAM_BUCKET_RES_NAME, le_bucket); - - if (SUCCESS == zend_hash_find(Z_OBJPROP_P(zobject), "data", 5, (void**)&pzdata) && (*pzdata)->type == IS_STRING) { - if (!bucket->own_buf) { - bucket = php_stream_bucket_make_writeable(bucket TSRMLS_CC); - } - if (bucket->buflen != Z_STRLEN_PP(pzdata)) { - bucket->buf = perealloc(bucket->buf, Z_STRLEN_PP(pzdata), bucket->is_persistent); - bucket->buflen = Z_STRLEN_PP(pzdata); - } - memcpy(bucket->buf, Z_STRVAL_PP(pzdata), bucket->buflen); - } - - if (append) { - php_stream_bucket_append(brigade, bucket TSRMLS_CC); - } else { - php_stream_bucket_prepend(brigade, bucket TSRMLS_CC); - } -} -/* }}} */ - -/* {{{ proto void stream_bucket_prepend(resource brigade, resource bucket) - Prepend bucket to brigade */ -PHP_FUNCTION(stream_bucket_prepend) -{ - php_stream_bucket_attach(0, INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ proto void stream_bucket_append(resource brigade, resource bucket) - Append bucket to brigade */ -PHP_FUNCTION(stream_bucket_append) -{ - php_stream_bucket_attach(1, INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ proto resource stream_bucket_new(resource stream, string buffer) - Create a new bucket for use on the current stream */ -PHP_FUNCTION(stream_bucket_new) -{ - zval *zstream, *zbucket; - php_stream *stream; - char *buffer; - char *pbuffer; - int buffer_len; - php_stream_bucket *bucket; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &zstream, &buffer, &buffer_len) == FAILURE) { - RETURN_FALSE; - } - - php_stream_from_zval(stream, &zstream); - - if (!(pbuffer = pemalloc(buffer_len, php_stream_is_persistent(stream)))) { - RETURN_FALSE; - } - - memcpy(pbuffer, buffer, buffer_len); - - bucket = php_stream_bucket_new(stream, pbuffer, buffer_len, 1, php_stream_is_persistent(stream) TSRMLS_CC); - - ALLOC_INIT_ZVAL(zbucket); - ZEND_REGISTER_RESOURCE(zbucket, bucket, le_bucket); - object_init(return_value); - add_property_zval(return_value, "bucket", zbucket); - /* add_property_zval increments the refcount which is unwanted here */ - zval_ptr_dtor(&zbucket); - add_property_stringl(return_value, "data", bucket->buf, bucket->buflen, 1); - add_property_long(return_value, "datalen", bucket->buflen); -} -/* }}} */ - -/* {{{ proto array stream_get_filters(void) - Returns a list of registered filters */ -PHP_FUNCTION(stream_get_filters) -{ - char *filter_name; - int key_flags, filter_name_len = 0; - HashTable *filters_hash; - ulong num_key; - - if (ZEND_NUM_ARGS() != 0) { - WRONG_PARAM_COUNT; - } - - array_init(return_value); - - filters_hash = php_get_stream_filters_hash(); - - if (filters_hash) { - for(zend_hash_internal_pointer_reset(filters_hash); - (key_flags = zend_hash_get_current_key_ex(filters_hash, &filter_name, &filter_name_len, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; - zend_hash_move_forward(filters_hash)) - if (key_flags == HASH_KEY_IS_STRING) - add_next_index_stringl(return_value, filter_name, filter_name_len, 1); - } - /* It's okay to return an empty array if no filters are registered */ -} -/* }}} */ - -/* {{{ proto bool stream_filter_register(string filtername, string classname) - Registers a custom filter handler class */ -PHP_FUNCTION(stream_filter_register) -{ - char *filtername, *classname; - int filtername_len, classname_len; - struct php_user_filter_data *fdat; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &filtername, &filtername_len, - &classname, &classname_len) == FAILURE) { - RETURN_FALSE; - } - - RETVAL_FALSE; - - if (!BG(user_filter_map)) { - BG(user_filter_map) = (HashTable*) emalloc(sizeof(HashTable)); - zend_hash_init(BG(user_filter_map), 5, NULL, (dtor_func_t) filter_item_dtor, 0); - } - - fdat = ecalloc(1, sizeof(*fdat) + classname_len); - memcpy(fdat->classname, classname, classname_len); - - if (zend_hash_add(BG(user_filter_map), filtername, filtername_len, (void*)fdat, - sizeof(*fdat) + classname_len, NULL) == SUCCESS && - php_stream_filter_register_factory_volatile(filtername, &user_filter_factory TSRMLS_CC) == SUCCESS) { - RETVAL_TRUE; - } - - efree(fdat); -} -/* }}} */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ |