summaryrefslogtreecommitdiff
path: root/ext/standard/user_filters.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/user_filters.c')
-rw-r--r--ext/standard/user_filters.c545
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
- */