File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / filter / filter.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:48 2014 UTC (10 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:   +----------------------------------------------------------------------+
    3:   | PHP Version 5                                                        |
    4:   +----------------------------------------------------------------------+
    5:   | Copyright (c) 1997-2014 The PHP Group                                |
    6:   +----------------------------------------------------------------------+
    7:   | This source file is subject to version 3.01 of the PHP license,      |
    8:   | that is bundled with this package in the file LICENSE, and is        |
    9:   | available through the world-wide-web at the following url:           |
   10:   | http://www.php.net/license/3_01.txt                                  |
   11:   | If you did not receive a copy of the PHP license and are unable to   |
   12:   | obtain it through the world-wide-web, please send a note to          |
   13:   | license@php.net so we can mail you a copy immediately.               |
   14:   +----------------------------------------------------------------------+
   15:   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   16:   |          Derick Rethans <derick@php.net>                             |
   17:   |          Pierre-A. Joye <pierre@php.net>                             |
   18:   |          Ilia Alshanetsky <iliaa@php.net>                            |
   19:   +----------------------------------------------------------------------+
   20: */
   21: 
   22: /* $Id: filter.c,v 1.1.1.5 2014/06/15 20:03:48 misho Exp $ */
   23: 
   24: #ifdef HAVE_CONFIG_H
   25: #include "config.h"
   26: #endif
   27: 
   28: #include "php_filter.h"
   29: 
   30: ZEND_DECLARE_MODULE_GLOBALS(filter)
   31: 
   32: #include "filter_private.h"
   33: 
   34: typedef struct filter_list_entry {
   35: 	const char *name;
   36: 	int    id;
   37: 	void (*function)(PHP_INPUT_FILTER_PARAM_DECL);
   38: } filter_list_entry;
   39: 
   40: /* {{{ filter_list */
   41: static const filter_list_entry filter_list[] = {
   42: 	{ "int",             FILTER_VALIDATE_INT,           php_filter_int             },
   43: 	{ "boolean",         FILTER_VALIDATE_BOOLEAN,       php_filter_boolean         },
   44: 	{ "float",           FILTER_VALIDATE_FLOAT,         php_filter_float           },
   45: 
   46: 	{ "validate_regexp", FILTER_VALIDATE_REGEXP,        php_filter_validate_regexp },
   47: 	{ "validate_url",    FILTER_VALIDATE_URL,           php_filter_validate_url    },
   48: 	{ "validate_email",  FILTER_VALIDATE_EMAIL,         php_filter_validate_email  },
   49: 	{ "validate_ip",     FILTER_VALIDATE_IP,            php_filter_validate_ip     },
   50: 
   51: 	{ "string",          FILTER_SANITIZE_STRING,        php_filter_string          },
   52: 	{ "stripped",        FILTER_SANITIZE_STRING,        php_filter_string          },
   53: 	{ "encoded",         FILTER_SANITIZE_ENCODED,       php_filter_encoded         },
   54: 	{ "special_chars",   FILTER_SANITIZE_SPECIAL_CHARS, php_filter_special_chars   },
   55: 	{ "full_special_chars",   FILTER_SANITIZE_FULL_SPECIAL_CHARS, php_filter_full_special_chars   },
   56: 	{ "unsafe_raw",      FILTER_UNSAFE_RAW,             php_filter_unsafe_raw      },
   57: 	{ "email",           FILTER_SANITIZE_EMAIL,         php_filter_email           },
   58: 	{ "url",             FILTER_SANITIZE_URL,           php_filter_url             },
   59: 	{ "number_int",      FILTER_SANITIZE_NUMBER_INT,    php_filter_number_int      },
   60: 	{ "number_float",    FILTER_SANITIZE_NUMBER_FLOAT,  php_filter_number_float    },
   61: 	{ "magic_quotes",    FILTER_SANITIZE_MAGIC_QUOTES,  php_filter_magic_quotes    },
   62: 
   63: 	{ "callback",        FILTER_CALLBACK,               php_filter_callback        },
   64: };
   65: /* }}} */
   66: 
   67: #ifndef PARSE_ENV
   68: #define PARSE_ENV 4
   69: #endif
   70: 
   71: #ifndef PARSE_SERVER
   72: #define PARSE_SERVER 5
   73: #endif
   74: 
   75: #ifndef PARSE_SESSION
   76: #define PARSE_SESSION 6
   77: #endif
   78: 
   79: static unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
   80: static unsigned int php_sapi_filter_init(TSRMLS_D);
   81: 
   82: /* {{{ arginfo */
   83: ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_input, 0, 0, 2)
   84: 	ZEND_ARG_INFO(0, type)
   85: 	ZEND_ARG_INFO(0, variable_name)
   86: 	ZEND_ARG_INFO(0, filter)
   87: 	ZEND_ARG_INFO(0, options)
   88: ZEND_END_ARG_INFO()
   89: 
   90: ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_var, 0, 0, 1)
   91: 	ZEND_ARG_INFO(0, variable)
   92: 	ZEND_ARG_INFO(0, filter)
   93: 	ZEND_ARG_INFO(0, options)
   94: ZEND_END_ARG_INFO()
   95: 
   96: ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_input_array, 0, 0, 1)
   97: 	ZEND_ARG_INFO(0, type)
   98: 	ZEND_ARG_INFO(0, definition)
   99: 	ZEND_ARG_INFO(0, add_empty)
  100: ZEND_END_ARG_INFO()
  101: 
  102: ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_var_array, 0, 0, 1)
  103: 	ZEND_ARG_INFO(0, data)
  104: 	ZEND_ARG_INFO(0, definition)
  105: 	ZEND_ARG_INFO(0, add_empty)
  106: ZEND_END_ARG_INFO()
  107: 
  108: ZEND_BEGIN_ARG_INFO(arginfo_filter_list, 0)
  109: ZEND_END_ARG_INFO()
  110: 
  111: ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_has_var, 0, 0, 2)
  112: 	ZEND_ARG_INFO(0, type)
  113: 	ZEND_ARG_INFO(0, variable_name)
  114: ZEND_END_ARG_INFO()
  115: 
  116: ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_id, 0, 0, 1)
  117: 	ZEND_ARG_INFO(0, filtername)
  118: ZEND_END_ARG_INFO()
  119: /* }}} */
  120: 
  121: /* {{{ filter_functions[]
  122:  */
  123: static const zend_function_entry filter_functions[] = {
  124: 	PHP_FE(filter_input,		arginfo_filter_input)
  125: 	PHP_FE(filter_var,		arginfo_filter_var)
  126: 	PHP_FE(filter_input_array,	arginfo_filter_input_array)
  127: 	PHP_FE(filter_var_array,	arginfo_filter_var_array)
  128: 	PHP_FE(filter_list,		arginfo_filter_list)
  129: 	PHP_FE(filter_has_var,		arginfo_filter_has_var)
  130: 	PHP_FE(filter_id,		arginfo_filter_id)
  131: 	PHP_FE_END
  132: };
  133: /* }}} */
  134: 
  135: /* {{{ filter_module_entry
  136:  */
  137: zend_module_entry filter_module_entry = {
  138: #if ZEND_MODULE_API_NO >= 20010901
  139: 	STANDARD_MODULE_HEADER,
  140: #endif
  141: 	"filter",
  142: 	filter_functions,
  143: 	PHP_MINIT(filter),
  144: 	PHP_MSHUTDOWN(filter),
  145: 	NULL,
  146: 	PHP_RSHUTDOWN(filter),
  147: 	PHP_MINFO(filter),
  148: 	"0.11.0",
  149: 	STANDARD_MODULE_PROPERTIES
  150: };
  151: /* }}} */
  152: 
  153: #ifdef COMPILE_DL_FILTER
  154: ZEND_GET_MODULE(filter)
  155: #endif
  156: 
  157: static PHP_INI_MH(UpdateDefaultFilter) /* {{{ */
  158: {
  159: 	int i, size = sizeof(filter_list) / sizeof(filter_list_entry);
  160: 
  161: 	for (i = 0; i < size; ++i) {
  162: 		if ((strcasecmp(new_value, filter_list[i].name) == 0)) {
  163: 			IF_G(default_filter) = filter_list[i].id;
  164: 			return SUCCESS;
  165: 		}
  166: 	}
  167: 	/* Fallback to the default filter */
  168: 	IF_G(default_filter) = FILTER_DEFAULT;
  169: 	return SUCCESS;
  170: }
  171: /* }}} */
  172: 
  173: /* {{{ PHP_INI
  174:  */
  175: static PHP_INI_MH(OnUpdateFlags)
  176: {
  177: 	if (!new_value) {
  178: 		IF_G(default_filter_flags) = FILTER_FLAG_NO_ENCODE_QUOTES;
  179: 	} else {
  180: 		IF_G(default_filter_flags) = atoi(new_value);
  181: 	}
  182: 	return SUCCESS;
  183: }
  184: 
  185: PHP_INI_BEGIN()
  186: 	STD_PHP_INI_ENTRY("filter.default",   "unsafe_raw", PHP_INI_SYSTEM|PHP_INI_PERDIR, UpdateDefaultFilter, default_filter, zend_filter_globals, filter_globals)
  187: 	PHP_INI_ENTRY("filter.default_flags", NULL,     PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateFlags)
  188: PHP_INI_END()
  189: /* }}} */
  190: 
  191: static void php_filter_init_globals(zend_filter_globals *filter_globals) /* {{{ */
  192: {
  193: 	filter_globals->post_array = NULL;
  194: 	filter_globals->get_array = NULL;
  195: 	filter_globals->cookie_array = NULL;
  196: 	filter_globals->env_array = NULL;
  197: 	filter_globals->server_array = NULL;
  198: 	filter_globals->session_array = NULL;
  199: 	filter_globals->default_filter = FILTER_DEFAULT;
  200: }
  201: /* }}} */
  202: 
  203: #define PARSE_REQUEST 99
  204: 
  205: /* {{{ PHP_MINIT_FUNCTION
  206:  */
  207: PHP_MINIT_FUNCTION(filter)
  208: {
  209: 	ZEND_INIT_MODULE_GLOBALS(filter, php_filter_init_globals, NULL);
  210: 
  211: 	REGISTER_INI_ENTRIES();
  212: 
  213: 	REGISTER_LONG_CONSTANT("INPUT_POST",	PARSE_POST, 	CONST_CS | CONST_PERSISTENT);
  214: 	REGISTER_LONG_CONSTANT("INPUT_GET",		PARSE_GET,		CONST_CS | CONST_PERSISTENT);
  215: 	REGISTER_LONG_CONSTANT("INPUT_COOKIE",	PARSE_COOKIE, 	CONST_CS | CONST_PERSISTENT);
  216: 	REGISTER_LONG_CONSTANT("INPUT_ENV",		PARSE_ENV,		CONST_CS | CONST_PERSISTENT);
  217: 	REGISTER_LONG_CONSTANT("INPUT_SERVER",	PARSE_SERVER, 	CONST_CS | CONST_PERSISTENT);
  218: 	REGISTER_LONG_CONSTANT("INPUT_SESSION", PARSE_SESSION, 	CONST_CS | CONST_PERSISTENT);
  219: 	REGISTER_LONG_CONSTANT("INPUT_REQUEST", PARSE_REQUEST, 	CONST_CS | CONST_PERSISTENT);
  220: 
  221: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_NONE", FILTER_FLAG_NONE, CONST_CS | CONST_PERSISTENT);
  222: 
  223: 	REGISTER_LONG_CONSTANT("FILTER_REQUIRE_SCALAR", FILTER_REQUIRE_SCALAR, CONST_CS | CONST_PERSISTENT);
  224: 	REGISTER_LONG_CONSTANT("FILTER_REQUIRE_ARRAY", FILTER_REQUIRE_ARRAY, CONST_CS | CONST_PERSISTENT);
  225: 	REGISTER_LONG_CONSTANT("FILTER_FORCE_ARRAY", FILTER_FORCE_ARRAY, CONST_CS | CONST_PERSISTENT);
  226: 	REGISTER_LONG_CONSTANT("FILTER_NULL_ON_FAILURE", FILTER_NULL_ON_FAILURE, CONST_CS | CONST_PERSISTENT);
  227: 
  228: 	REGISTER_LONG_CONSTANT("FILTER_VALIDATE_INT", FILTER_VALIDATE_INT, CONST_CS | CONST_PERSISTENT);
  229: 	REGISTER_LONG_CONSTANT("FILTER_VALIDATE_BOOLEAN", FILTER_VALIDATE_BOOLEAN, CONST_CS | CONST_PERSISTENT);
  230: 	REGISTER_LONG_CONSTANT("FILTER_VALIDATE_FLOAT", FILTER_VALIDATE_FLOAT, CONST_CS | CONST_PERSISTENT);
  231: 
  232: 	REGISTER_LONG_CONSTANT("FILTER_VALIDATE_REGEXP", FILTER_VALIDATE_REGEXP, CONST_CS | CONST_PERSISTENT);
  233: 	REGISTER_LONG_CONSTANT("FILTER_VALIDATE_URL", FILTER_VALIDATE_URL, CONST_CS | CONST_PERSISTENT);
  234: 	REGISTER_LONG_CONSTANT("FILTER_VALIDATE_EMAIL", FILTER_VALIDATE_EMAIL, CONST_CS | CONST_PERSISTENT);
  235: 	REGISTER_LONG_CONSTANT("FILTER_VALIDATE_IP", FILTER_VALIDATE_IP, CONST_CS | CONST_PERSISTENT);
  236: 
  237: 	REGISTER_LONG_CONSTANT("FILTER_DEFAULT", FILTER_DEFAULT, CONST_CS | CONST_PERSISTENT);
  238: 	REGISTER_LONG_CONSTANT("FILTER_UNSAFE_RAW", FILTER_UNSAFE_RAW, CONST_CS | CONST_PERSISTENT);
  239: 
  240: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRING", FILTER_SANITIZE_STRING, CONST_CS | CONST_PERSISTENT);
  241: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRIPPED", FILTER_SANITIZE_STRING, CONST_CS | CONST_PERSISTENT);
  242: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_ENCODED", FILTER_SANITIZE_ENCODED, CONST_CS | CONST_PERSISTENT);
  243: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_SPECIAL_CHARS", FILTER_SANITIZE_SPECIAL_CHARS, CONST_CS | CONST_PERSISTENT);
  244: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_FULL_SPECIAL_CHARS", FILTER_SANITIZE_FULL_SPECIAL_CHARS, CONST_CS | CONST_PERSISTENT);
  245: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_EMAIL", FILTER_SANITIZE_EMAIL, CONST_CS | CONST_PERSISTENT);
  246: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_URL", FILTER_SANITIZE_URL, CONST_CS | CONST_PERSISTENT);
  247: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_NUMBER_INT", FILTER_SANITIZE_NUMBER_INT, CONST_CS | CONST_PERSISTENT);
  248: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_NUMBER_FLOAT", FILTER_SANITIZE_NUMBER_FLOAT, CONST_CS | CONST_PERSISTENT);
  249: 	REGISTER_LONG_CONSTANT("FILTER_SANITIZE_MAGIC_QUOTES", FILTER_SANITIZE_MAGIC_QUOTES, CONST_CS | CONST_PERSISTENT);
  250: 
  251: 	REGISTER_LONG_CONSTANT("FILTER_CALLBACK", FILTER_CALLBACK, CONST_CS | CONST_PERSISTENT);
  252: 
  253: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_OCTAL", FILTER_FLAG_ALLOW_OCTAL, CONST_CS | CONST_PERSISTENT);
  254: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_HEX", FILTER_FLAG_ALLOW_HEX, CONST_CS | CONST_PERSISTENT);
  255: 
  256: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_LOW", FILTER_FLAG_STRIP_LOW, CONST_CS | CONST_PERSISTENT);
  257: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_HIGH", FILTER_FLAG_STRIP_HIGH, CONST_CS | CONST_PERSISTENT);
  258: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_BACKTICK", FILTER_FLAG_STRIP_BACKTICK, CONST_CS | CONST_PERSISTENT);
  259: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ENCODE_LOW", FILTER_FLAG_ENCODE_LOW, CONST_CS | CONST_PERSISTENT);
  260: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ENCODE_HIGH", FILTER_FLAG_ENCODE_HIGH, CONST_CS | CONST_PERSISTENT);
  261: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ENCODE_AMP", FILTER_FLAG_ENCODE_AMP, CONST_CS | CONST_PERSISTENT);
  262: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_ENCODE_QUOTES", FILTER_FLAG_NO_ENCODE_QUOTES, CONST_CS | CONST_PERSISTENT);
  263: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_EMPTY_STRING_NULL", FILTER_FLAG_EMPTY_STRING_NULL, CONST_CS | CONST_PERSISTENT);
  264: 
  265: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_FRACTION", FILTER_FLAG_ALLOW_FRACTION, CONST_CS | CONST_PERSISTENT);
  266: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_THOUSAND", FILTER_FLAG_ALLOW_THOUSAND, CONST_CS | CONST_PERSISTENT);
  267: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_SCIENTIFIC", FILTER_FLAG_ALLOW_SCIENTIFIC, CONST_CS | CONST_PERSISTENT);
  268: 
  269: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_SCHEME_REQUIRED", FILTER_FLAG_SCHEME_REQUIRED, CONST_CS | CONST_PERSISTENT);
  270: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_HOST_REQUIRED", FILTER_FLAG_HOST_REQUIRED, CONST_CS | CONST_PERSISTENT);
  271: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_PATH_REQUIRED", FILTER_FLAG_PATH_REQUIRED, CONST_CS | CONST_PERSISTENT);
  272: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_QUERY_REQUIRED", FILTER_FLAG_QUERY_REQUIRED, CONST_CS | CONST_PERSISTENT);
  273: 
  274: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_IPV4", FILTER_FLAG_IPV4, CONST_CS | CONST_PERSISTENT);
  275: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_IPV6", FILTER_FLAG_IPV6, CONST_CS | CONST_PERSISTENT);
  276: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_RES_RANGE", FILTER_FLAG_NO_RES_RANGE, CONST_CS | CONST_PERSISTENT);
  277: 	REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_PRIV_RANGE", FILTER_FLAG_NO_PRIV_RANGE, CONST_CS | CONST_PERSISTENT);
  278: 
  279: 	sapi_register_input_filter(php_sapi_filter, php_sapi_filter_init TSRMLS_CC);
  280: 
  281: 	return SUCCESS;
  282: }
  283: /* }}} */
  284: 
  285: /* {{{ PHP_MSHUTDOWN_FUNCTION
  286:  */
  287: PHP_MSHUTDOWN_FUNCTION(filter)
  288: {
  289: 	UNREGISTER_INI_ENTRIES();
  290: 
  291: 	return SUCCESS;
  292: }
  293: /* }}} */
  294: 
  295: /* {{{ PHP_RSHUTDOWN_FUNCTION
  296:  */
  297: #define VAR_ARRAY_COPY_DTOR(a)   \
  298: 	if (IF_G(a)) {               \
  299: 		zval_ptr_dtor(&IF_G(a)); \
  300: 		IF_G(a) = NULL;          \
  301: 	}
  302: 
  303: PHP_RSHUTDOWN_FUNCTION(filter)
  304: {
  305: 	VAR_ARRAY_COPY_DTOR(get_array)
  306: 	VAR_ARRAY_COPY_DTOR(post_array)
  307: 	VAR_ARRAY_COPY_DTOR(cookie_array)
  308: 	VAR_ARRAY_COPY_DTOR(server_array)
  309: 	VAR_ARRAY_COPY_DTOR(env_array)
  310: 	VAR_ARRAY_COPY_DTOR(session_array)
  311: 	return SUCCESS;
  312: }
  313: /* }}} */
  314: 
  315: /* {{{ PHP_MINFO_FUNCTION
  316:  */
  317: PHP_MINFO_FUNCTION(filter)
  318: {
  319: 	php_info_print_table_start();
  320: 	php_info_print_table_row( 2, "Input Validation and Filtering", "enabled" );
  321: 	php_info_print_table_row( 2, "Revision", "$Id: filter.c,v 1.1.1.5 2014/06/15 20:03:48 misho Exp $");
  322: 	php_info_print_table_end();
  323: 
  324: 	DISPLAY_INI_ENTRIES();
  325: }
  326: /* }}} */
  327: 
  328: static filter_list_entry php_find_filter(long id) /* {{{ */
  329: {
  330: 	int i, size = sizeof(filter_list) / sizeof(filter_list_entry);
  331: 
  332: 	for (i = 0; i < size; ++i) {
  333: 		if (filter_list[i].id == id) {
  334: 			return filter_list[i];
  335: 		}
  336: 	}
  337: 	/* Fallback to "string" filter */
  338: 	for (i = 0; i < size; ++i) {
  339: 		if (filter_list[i].id == FILTER_DEFAULT) {
  340: 			return filter_list[i];
  341: 		}
  342: 	}
  343: 	/* To shut up GCC */
  344: 	return filter_list[0];
  345: }
  346: /* }}} */
  347: 
  348: static unsigned int php_sapi_filter_init(TSRMLS_D)
  349: {
  350: 	IF_G(get_array) = NULL;
  351: 	IF_G(post_array) = NULL;
  352: 	IF_G(cookie_array) = NULL;
  353: 	IF_G(server_array) = NULL;
  354: 	IF_G(env_array) = NULL;
  355: 	IF_G(session_array) = NULL;
  356: 	return SUCCESS;
  357: }
  358: 
  359: static void php_zval_filter(zval **value, long filter, long flags, zval *options, char* charset, zend_bool copy TSRMLS_DC) /* {{{ */
  360: {
  361: 	filter_list_entry  filter_func;
  362: 
  363: 	filter_func = php_find_filter(filter);
  364: 
  365: 	if (!filter_func.id) {
  366: 		/* Find default filter */
  367: 		filter_func = php_find_filter(FILTER_DEFAULT);
  368: 	}
  369: 
  370: 	if (copy) {
  371: 		SEPARATE_ZVAL(value);
  372: 	}
  373: 
  374: 	/* #49274, fatal error with object without a toString method
  375: 	  Fails nicely instead of getting a recovarable fatal error. */
  376: 	if (Z_TYPE_PP(value) == IS_OBJECT) {
  377: 		zend_class_entry *ce;
  378: 
  379: 		ce = Z_OBJCE_PP(value);
  380: 		if (!ce->__tostring) {
  381: 			ZVAL_FALSE(*value);
  382: 			return;
  383: 		}
  384: 	}
  385: 
  386: 	/* Here be strings */
  387: 	convert_to_string(*value);
  388: 
  389: 	filter_func.function(*value, flags, options, charset TSRMLS_CC);
  390: 
  391: 	if (
  392: 		options && (Z_TYPE_P(options) == IS_ARRAY || Z_TYPE_P(options) == IS_OBJECT) &&
  393: 		((flags & FILTER_NULL_ON_FAILURE && Z_TYPE_PP(value) == IS_NULL) || 
  394: 		(!(flags & FILTER_NULL_ON_FAILURE) && Z_TYPE_PP(value) == IS_BOOL && Z_LVAL_PP(value) == 0)) &&
  395: 		zend_hash_exists(HASH_OF(options), "default", sizeof("default"))
  396: 	) {
  397: 		zval **tmp; 
  398: 		if (zend_hash_find(HASH_OF(options), "default", sizeof("default"), (void **)&tmp) == SUCCESS) {
  399: 			MAKE_COPY_ZVAL(tmp, *value);
  400: 		}
  401: 	}
  402: }
  403: /* }}} */
  404: 
  405: static unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC) /* {{{ */
  406: {
  407: 	zval  new_var, raw_var;
  408: 	zval *array_ptr = NULL, *orig_array_ptr = NULL;
  409: 	int retval = 0;
  410: 
  411: 	assert(*val != NULL);
  412: 
  413: #define PARSE_CASE(s,a,t)                    \
  414: 		case s:                              \
  415: 			if (!IF_G(a)) {                  \
  416: 				ALLOC_ZVAL(array_ptr);       \
  417: 				array_init(array_ptr);       \
  418: 				INIT_PZVAL(array_ptr);       \
  419: 				IF_G(a) = array_ptr;         \
  420: 			} else {                         \
  421: 				array_ptr = IF_G(a);         \
  422: 			}                                \
  423: 			orig_array_ptr = PG(http_globals)[t]; \
  424: 			break;
  425: 
  426: 	switch (arg) {
  427: 		PARSE_CASE(PARSE_POST,    post_array,    TRACK_VARS_POST)
  428: 		PARSE_CASE(PARSE_GET,     get_array,     TRACK_VARS_GET)
  429: 		PARSE_CASE(PARSE_COOKIE,  cookie_array,  TRACK_VARS_COOKIE)
  430: 		PARSE_CASE(PARSE_SERVER,  server_array,  TRACK_VARS_SERVER)
  431: 		PARSE_CASE(PARSE_ENV,     env_array,     TRACK_VARS_ENV)
  432: 
  433: 		case PARSE_STRING: /* PARSE_STRING is used by parse_str() function */
  434: 			retval = 1;
  435: 			break;
  436: 	}
  437: 
  438: 	/* 
  439: 	 * According to rfc2965, more specific paths are listed above the less specific ones.
  440: 	 * If we encounter a duplicate cookie name, we should skip it, since it is not possible
  441: 	 * to have the same (plain text) cookie name for the same path and we should not overwrite
  442: 	 * more specific cookies with the less specific ones.
  443: 	*/
  444: 	if (arg == PARSE_COOKIE && orig_array_ptr && zend_symtable_exists(Z_ARRVAL_P(orig_array_ptr), var, strlen(var)+1)) {
  445: 		return 0;
  446: 	}
  447: 
  448: 	if (array_ptr) {
  449: 		/* Store the RAW variable internally */
  450: 		Z_STRLEN(raw_var) = val_len;
  451: 		Z_STRVAL(raw_var) = estrndup(*val, val_len);
  452: 		Z_TYPE(raw_var) = IS_STRING;
  453: 
  454: 		php_register_variable_ex(var, &raw_var, array_ptr TSRMLS_CC);
  455: 	}
  456: 
  457: 	if (val_len) {
  458: 		/* Register mangled variable */
  459: 		Z_STRLEN(new_var) = val_len;
  460: 		Z_TYPE(new_var) = IS_STRING;
  461: 
  462: 		if (IF_G(default_filter) != FILTER_UNSAFE_RAW) {
  463: 			zval *tmp_new_var = &new_var;
  464: 			Z_STRVAL(new_var) = estrndup(*val, val_len);
  465: 			INIT_PZVAL(tmp_new_var);
  466: 			php_zval_filter(&tmp_new_var, IF_G(default_filter), IF_G(default_filter_flags), NULL, NULL/*charset*/, 0 TSRMLS_CC);
  467: 		} else {
  468: 			Z_STRVAL(new_var) = estrndup(*val, val_len);
  469: 		}
  470: 	} else { /* empty string */
  471: 		ZVAL_EMPTY_STRING(&new_var);
  472: 	}
  473: 
  474: 	if (orig_array_ptr) {
  475: 		php_register_variable_ex(var, &new_var, orig_array_ptr TSRMLS_CC);
  476: 	}
  477: 
  478: 	if (retval) {
  479: 		if (new_val_len) {
  480: 			*new_val_len = Z_STRLEN(new_var);
  481: 		}
  482: 		efree(*val);
  483: 		if (Z_STRLEN(new_var)) {
  484: 			*val = estrndup(Z_STRVAL(new_var), Z_STRLEN(new_var));
  485: 		} else {
  486: 			*val = estrdup("");
  487: 		}
  488: 		zval_dtor(&new_var);
  489: 	}
  490: 
  491: 	return retval;
  492: }
  493: /* }}} */
  494: 
  495: static void php_zval_filter_recursive(zval **value, long filter, long flags, zval *options, char *charset, zend_bool copy TSRMLS_DC) /* {{{ */
  496: {
  497: 	if (Z_TYPE_PP(value) == IS_ARRAY) {
  498: 		zval **element;
  499: 		HashPosition pos;
  500: 
  501: 		if (Z_ARRVAL_PP(value)->nApplyCount > 1) {
  502: 			return;
  503: 		}
  504: 
  505: 		for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(value), &pos);
  506: 			 zend_hash_get_current_data_ex(Z_ARRVAL_PP(value), (void **) &element, &pos) == SUCCESS;
  507: 			 zend_hash_move_forward_ex(Z_ARRVAL_PP(value), &pos)
  508: 		) {
  509: 			SEPARATE_ZVAL_IF_NOT_REF(element);
  510: 			if (Z_TYPE_PP(element) == IS_ARRAY) {
  511: 				Z_ARRVAL_PP(element)->nApplyCount++;
  512: 				php_zval_filter_recursive(element, filter, flags, options, charset, copy TSRMLS_CC);
  513: 				Z_ARRVAL_PP(element)->nApplyCount--;
  514: 			} else {
  515: 				php_zval_filter(element, filter, flags, options, charset, copy TSRMLS_CC);
  516: 			}
  517: 		}
  518: 	} else {
  519: 		php_zval_filter(value, filter, flags, options, charset, copy TSRMLS_CC);
  520: 	}
  521: }
  522: /* }}} */
  523: 
  524: static zval *php_filter_get_storage(long arg TSRMLS_DC)/* {{{ */
  525: 
  526: {
  527: 	zval *array_ptr = NULL;
  528: 
  529: 	switch (arg) {
  530: 		case PARSE_GET:
  531: 			array_ptr = IF_G(get_array);
  532: 			break;
  533: 		case PARSE_POST:
  534: 			array_ptr = IF_G(post_array);
  535: 			break;
  536: 		case PARSE_COOKIE:
  537: 			array_ptr = IF_G(cookie_array);
  538: 			break;
  539: 		case PARSE_SERVER:
  540: 			if (PG(auto_globals_jit)) {
  541: 				zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
  542: 			}
  543: 			array_ptr = IF_G(server_array);
  544: 			break;
  545: 		case PARSE_ENV:
  546: 			if (PG(auto_globals_jit)) {
  547: 				zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC);
  548: 			}
  549: 			array_ptr = IF_G(env_array) ? IF_G(env_array) : PG(http_globals)[TRACK_VARS_ENV];
  550: 			break;
  551: 		case PARSE_SESSION:
  552: 			/* FIXME: Implement session source */
  553: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "INPUT_SESSION is not yet implemented");
  554: 			break;
  555: 		case PARSE_REQUEST:
  556: 			/* FIXME: Implement request source */
  557: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "INPUT_REQUEST is not yet implemented");
  558: 			break;
  559: 	}
  560: 
  561: 	return array_ptr;
  562: }
  563: /* }}} */
  564: 
  565: /* {{{ proto mixed filter_has_var(constant type, string variable_name)
  566:  * Returns true if the variable with the name 'name' exists in source.
  567:  */
  568: PHP_FUNCTION(filter_has_var)
  569: {
  570: 	long        arg;
  571: 	char       *var;
  572: 	int         var_len;
  573: 	zval       *array_ptr = NULL;
  574: 
  575: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
  576: 		RETURN_FALSE;
  577: 	}
  578: 
  579: 	array_ptr = php_filter_get_storage(arg TSRMLS_CC);
  580: 
  581: 	if (array_ptr && HASH_OF(array_ptr) && zend_hash_exists(HASH_OF(array_ptr), var, var_len + 1)) {
  582: 		RETURN_TRUE;
  583: 	}
  584: 
  585: 	RETURN_FALSE;
  586: }
  587: /* }}} */
  588: 
  589: static void php_filter_call(zval **filtered, long filter, zval **filter_args, const int copy, long filter_flags TSRMLS_DC) /* {{{ */
  590: {
  591: 	zval  *options = NULL;
  592: 	zval **option;
  593: 	char  *charset = NULL;
  594: 
  595: 	if (filter_args && Z_TYPE_PP(filter_args) != IS_ARRAY) {
  596: 		long lval;
  597: 
  598: 		PHP_FILTER_GET_LONG_OPT(filter_args, lval);
  599: 
  600: 		if (filter != -1) { /* handler for array apply */
  601: 			/* filter_args is the filter_flags */
  602: 			filter_flags = lval;
  603: 
  604: 			if (!(filter_flags & FILTER_REQUIRE_ARRAY ||  filter_flags & FILTER_FORCE_ARRAY)) {
  605: 				filter_flags |= FILTER_REQUIRE_SCALAR;
  606: 			}
  607: 		} else {
  608: 			filter = lval;
  609: 		}
  610: 	} else if (filter_args) {
  611: 		if (zend_hash_find(HASH_OF(*filter_args), "filter", sizeof("filter"), (void **)&option) == SUCCESS) {
  612: 			PHP_FILTER_GET_LONG_OPT(option, filter);
  613: 		}
  614: 
  615: 		if (zend_hash_find(HASH_OF(*filter_args), "flags", sizeof("flags"), (void **)&option) == SUCCESS) {
  616: 			PHP_FILTER_GET_LONG_OPT(option, filter_flags);
  617: 
  618: 			if (!(filter_flags & FILTER_REQUIRE_ARRAY ||  filter_flags & FILTER_FORCE_ARRAY)) {
  619: 				filter_flags |= FILTER_REQUIRE_SCALAR;
  620: 			}
  621: 		}
  622: 
  623: 		if (zend_hash_find(HASH_OF(*filter_args), "options", sizeof("options"), (void **)&option) == SUCCESS) {
  624: 			if (filter != FILTER_CALLBACK) {
  625: 				if (Z_TYPE_PP(option) == IS_ARRAY) {
  626: 					options = *option;
  627: 				}
  628: 			} else {
  629: 				options = *option;
  630: 				filter_flags = 0;
  631: 			}
  632: 		}
  633: 	}
  634: 
  635: 	if (Z_TYPE_PP(filtered) == IS_ARRAY) {
  636: 		if (filter_flags & FILTER_REQUIRE_SCALAR) {
  637: 			if (copy) {
  638: 				SEPARATE_ZVAL(filtered);
  639: 			}
  640: 			zval_dtor(*filtered);
  641: 			if (filter_flags & FILTER_NULL_ON_FAILURE) {
  642: 				ZVAL_NULL(*filtered);
  643: 			} else {
  644: 				ZVAL_FALSE(*filtered);
  645: 			}
  646: 			return;
  647: 		}
  648: 		php_zval_filter_recursive(filtered, filter, filter_flags, options, charset, copy TSRMLS_CC);
  649: 		return;
  650: 	}
  651: 	if (filter_flags & FILTER_REQUIRE_ARRAY) {
  652: 		if (copy) {
  653: 			SEPARATE_ZVAL(filtered);
  654: 		}
  655: 		zval_dtor(*filtered);
  656: 		if (filter_flags & FILTER_NULL_ON_FAILURE) {
  657: 			ZVAL_NULL(*filtered);
  658: 		} else {
  659: 			ZVAL_FALSE(*filtered);
  660: 		}
  661: 		return;
  662: 	}
  663: 
  664: 	php_zval_filter(filtered, filter, filter_flags, options, charset, copy TSRMLS_CC);
  665: 	if (filter_flags & FILTER_FORCE_ARRAY) {
  666: 		zval *tmp;
  667: 
  668: 		ALLOC_ZVAL(tmp);
  669: 		MAKE_COPY_ZVAL(filtered, tmp);
  670: 
  671: 		zval_dtor(*filtered);
  672: 
  673: 		array_init(*filtered);
  674: 		add_next_index_zval(*filtered, tmp);
  675: 	}
  676: }
  677: /* }}} */
  678: 
  679: static void php_filter_array_handler(zval *input, zval **op, zval *return_value, zend_bool add_empty TSRMLS_DC) /* {{{ */
  680: {
  681: 	char *arg_key;
  682: 	uint arg_key_len;
  683: 	ulong index;
  684: 	HashPosition pos;
  685: 	zval **tmp, **arg_elm;
  686: 
  687: 	if (!op) {
  688: 		zval_dtor(return_value);
  689: 		MAKE_COPY_ZVAL(&input, return_value);
  690: 		php_filter_call(&return_value, FILTER_DEFAULT, NULL, 0, FILTER_REQUIRE_ARRAY TSRMLS_CC);
  691: 	} else if (Z_TYPE_PP(op) == IS_LONG) {
  692: 		zval_dtor(return_value);
  693: 		MAKE_COPY_ZVAL(&input, return_value);
  694: 		php_filter_call(&return_value, Z_LVAL_PP(op), NULL, 0, FILTER_REQUIRE_ARRAY TSRMLS_CC);
  695: 	} else if (Z_TYPE_PP(op) == IS_ARRAY) {
  696: 		array_init(return_value);
  697: 
  698: 		zend_hash_internal_pointer_reset(Z_ARRVAL_PP(op));
  699: 		for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(op), &pos);
  700: 			zend_hash_get_current_data_ex(Z_ARRVAL_PP(op), (void **) &arg_elm, &pos) == SUCCESS;
  701: 			zend_hash_move_forward_ex(Z_ARRVAL_PP(op), &pos))
  702: 		{
  703: 			if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(op), &arg_key, &arg_key_len, &index, 0, &pos) != HASH_KEY_IS_STRING) {
  704: 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric keys are not allowed in the definition array");
  705: 				zval_dtor(return_value);
  706: 				RETURN_FALSE;
  707: 	 		}
  708: 			if (arg_key_len < 2) {
  709: 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty keys are not allowed in the definition array");
  710: 				zval_dtor(return_value);
  711: 				RETURN_FALSE;
  712: 			}
  713: 			if (zend_hash_find(Z_ARRVAL_P(input), arg_key, arg_key_len, (void **)&tmp) != SUCCESS) {
  714: 				if (add_empty) {
  715: 					add_assoc_null_ex(return_value, arg_key, arg_key_len);
  716: 				}
  717: 			} else {
  718: 				zval *nval;
  719: 
  720: 				ALLOC_ZVAL(nval);
  721: 				MAKE_COPY_ZVAL(tmp, nval);
  722: 
  723: 				php_filter_call(&nval, -1, arg_elm, 0, FILTER_REQUIRE_SCALAR TSRMLS_CC);
  724: 				add_assoc_zval_ex(return_value, arg_key, arg_key_len, nval);
  725: 			}
  726: 		}
  727: 	} else {
  728: 		RETURN_FALSE;
  729: 	}
  730: }
  731: /* }}} */
  732: 
  733: /* {{{ proto mixed filter_input(constant type, string variable_name [, long filter [, mixed options]])
  734:  * Returns the filtered variable 'name'* from source `type`.
  735:  */
  736: PHP_FUNCTION(filter_input)
  737: {
  738: 	long   fetch_from, filter = FILTER_DEFAULT;
  739: 	zval **filter_args = NULL, **tmp;
  740: 	zval  *input = NULL;
  741: 	char *var;
  742: 	int var_len;
  743: 
  744: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|lZ", &fetch_from, &var, &var_len, &filter, &filter_args) == FAILURE) {
  745: 		return;
  746: 	}
  747: 
  748: 	if (!PHP_FILTER_ID_EXISTS(filter)) {
  749: 		RETURN_FALSE;
  750: 	}
  751: 
  752: 	input = php_filter_get_storage(fetch_from TSRMLS_CC);
  753: 
  754: 	if (!input || !HASH_OF(input) || zend_hash_find(HASH_OF(input), var, var_len + 1, (void **)&tmp) != SUCCESS) {
  755: 		long filter_flags = 0;
  756: 		zval **option, **opt, **def;
  757: 		if (filter_args) {
  758: 			if (Z_TYPE_PP(filter_args) == IS_LONG) {
  759: 				filter_flags = Z_LVAL_PP(filter_args);
  760: 			} else if (Z_TYPE_PP(filter_args) == IS_ARRAY && zend_hash_find(HASH_OF(*filter_args), "flags", sizeof("flags"), (void **)&option) == SUCCESS) {
  761: 				PHP_FILTER_GET_LONG_OPT(option, filter_flags);
  762: 			}
  763: 			if (Z_TYPE_PP(filter_args) == IS_ARRAY && 
  764: 				zend_hash_find(HASH_OF(*filter_args), "options", sizeof("options"), (void **)&opt) == SUCCESS &&
  765: 				Z_TYPE_PP(opt) == IS_ARRAY &&
  766: 				zend_hash_find(HASH_OF(*opt), "default", sizeof("default"), (void **)&def) == SUCCESS
  767: 			) {
  768: 				MAKE_COPY_ZVAL(def, return_value);
  769: 				return;
  770: 			}
  771: 		}
  772: 
  773: 		/* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of
  774: 		 * the function: normally when validation fails false is returned, and
  775: 		 * when the input value doesn't exist NULL is returned. With the flag
  776: 		 * set, NULL and false should be returned, respectively. Ergo, although
  777: 		 * the code below looks incorrect, it's actually right. */
  778: 		if (filter_flags & FILTER_NULL_ON_FAILURE) {
  779: 			RETURN_FALSE;
  780: 		} else {
  781: 			RETURN_NULL();
  782: 		}
  783: 	}
  784: 
  785: 	MAKE_COPY_ZVAL(tmp, return_value);
  786: 
  787: 	php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC);
  788: }
  789: /* }}} */
  790: 
  791: /* {{{ proto mixed filter_var(mixed variable [, long filter [, mixed options]])
  792:  * Returns the filtered version of the vriable.
  793:  */
  794: PHP_FUNCTION(filter_var)
  795: {
  796: 	long filter = FILTER_DEFAULT;
  797: 	zval **filter_args = NULL, *data;
  798: 
  799: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/|lZ", &data, &filter, &filter_args) == FAILURE) {
  800: 		return;
  801: 	}
  802: 
  803: 	if (!PHP_FILTER_ID_EXISTS(filter)) {
  804: 		RETURN_FALSE;
  805: 	}
  806: 
  807: 	MAKE_COPY_ZVAL(&data, return_value);
  808: 
  809: 	php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC);
  810: }
  811: /* }}} */
  812: 
  813: /* {{{ proto mixed filter_input_array(constant type, [, mixed options [, bool add_empty]]])
  814:  * Returns an array with all arguments defined in 'definition'.
  815:  */
  816: PHP_FUNCTION(filter_input_array)
  817: {
  818: 	long    fetch_from;
  819: 	zval   *array_input = NULL, **op = NULL;
  820: 	zend_bool add_empty = 1;
  821: 
  822: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|Zb",  &fetch_from, &op, &add_empty) == FAILURE) {
  823: 		return;
  824: 	}
  825: 
  826: 	if (op
  827: 		&& (Z_TYPE_PP(op) != IS_ARRAY)
  828: 		&& (Z_TYPE_PP(op) == IS_LONG && !PHP_FILTER_ID_EXISTS(Z_LVAL_PP(op)))
  829: 		) {
  830: 		RETURN_FALSE;
  831: 	}
  832: 
  833: 	array_input = php_filter_get_storage(fetch_from TSRMLS_CC);
  834: 
  835: 	if (!array_input || !HASH_OF(array_input)) {
  836: 		long filter_flags = 0;
  837: 		zval **option;
  838: 		if (op) {
  839: 			if (Z_TYPE_PP(op) == IS_LONG) {
  840: 				filter_flags = Z_LVAL_PP(op);
  841: 			} else if (Z_TYPE_PP(op) == IS_ARRAY && zend_hash_find(HASH_OF(*op), "flags", sizeof("flags"), (void **)&option) == SUCCESS) {
  842: 				PHP_FILTER_GET_LONG_OPT(option, filter_flags);
  843: 			}
  844: 		}
  845: 
  846: 		/* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of
  847: 		 * the function: normally when validation fails false is returned, and
  848: 		 * when the input value doesn't exist NULL is returned. With the flag
  849: 		 * set, NULL and false should be returned, respectively. Ergo, although
  850: 		 * the code below looks incorrect, it's actually right. */
  851: 		if (filter_flags & FILTER_NULL_ON_FAILURE) {
  852: 			RETURN_FALSE;
  853: 		} else {
  854: 			RETURN_NULL();
  855: 		}
  856: 	}
  857: 
  858: 	php_filter_array_handler(array_input, op, return_value, add_empty TSRMLS_CC);
  859: }
  860: /* }}} */
  861: 
  862: /* {{{ proto mixed filter_var_array(array data, [, mixed options [, bool add_empty]]])
  863:  * Returns an array with all arguments defined in 'definition'.
  864:  */
  865: PHP_FUNCTION(filter_var_array)
  866: {
  867: 	zval *array_input = NULL, **op = NULL;
  868: 	zend_bool add_empty = 1;
  869: 
  870: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|Zb",  &array_input, &op, &add_empty) == FAILURE) {
  871: 		return;
  872: 	}
  873: 
  874: 	if (op
  875: 		&& (Z_TYPE_PP(op) != IS_ARRAY)
  876: 		&& (Z_TYPE_PP(op) == IS_LONG && !PHP_FILTER_ID_EXISTS(Z_LVAL_PP(op)))
  877: 		) {
  878: 		RETURN_FALSE;
  879: 	}
  880: 
  881: 	php_filter_array_handler(array_input, op, return_value, add_empty TSRMLS_CC);
  882: }
  883: /* }}} */
  884: 
  885: /* {{{ proto filter_list()
  886:  * Returns a list of all supported filters */
  887: PHP_FUNCTION(filter_list)
  888: {
  889: 	int i, size = sizeof(filter_list) / sizeof(filter_list_entry);
  890: 
  891: 	if (zend_parse_parameters_none() == FAILURE) {
  892: 		return;
  893: 	}
  894: 
  895: 	array_init(return_value);
  896: 	for (i = 0; i < size; ++i) {
  897: 		add_next_index_string(return_value, (char *)filter_list[i].name, 1);
  898: 	}
  899: }
  900: /* }}} */
  901: 
  902: /* {{{ proto filter_id(string filtername)
  903:  * Returns the filter ID belonging to a named filter */
  904: PHP_FUNCTION(filter_id)
  905: {
  906: 	int i, filter_len;
  907: 	int size = sizeof(filter_list) / sizeof(filter_list_entry);
  908: 	char *filter;
  909: 
  910: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filter, &filter_len) == FAILURE) {
  911: 		return;
  912: 	}
  913: 
  914: 	for (i = 0; i < size; ++i) {
  915: 		if (strcmp(filter_list[i].name, filter) == 0) {
  916: 			RETURN_LONG(filter_list[i].id);
  917: 		}
  918: 	}
  919: 
  920: 	RETURN_FALSE;
  921: }
  922: /* }}} */
  923: 
  924: /*
  925:  * Local variables:
  926:  * tab-width: 4
  927:  * c-basic-offset: 4
  928:  * End:
  929:  * vim600: noet sw=4 ts=4 fdm=marker
  930:  * vim<600: noet sw=4 ts=4
  931:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>