Annotation of embedaddon/php/ext/filter/filter.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   +----------------------------------------------------------------------+
        !             3:   | PHP Version 5                                                        |
        !             4:   +----------------------------------------------------------------------+
        !             5:   | Copyright (c) 1997-2012 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 321634 2012-01-01 13:15:04Z felipe $ */
        !            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_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);
        !           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", "$Revision: 321634 $");
        !           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:        char *orig_var = NULL;
        !           410:        int retval = 0;
        !           411: 
        !           412:        assert(*val != NULL);
        !           413: 
        !           414: #define PARSE_CASE(s,a,t)                    \
        !           415:                case s:                              \
        !           416:                        if (!IF_G(a)) {                  \
        !           417:                                ALLOC_ZVAL(array_ptr);       \
        !           418:                                array_init(array_ptr);       \
        !           419:                                INIT_PZVAL(array_ptr);       \
        !           420:                                IF_G(a) = array_ptr;         \
        !           421:                        } else {                         \
        !           422:                                array_ptr = IF_G(a);         \
        !           423:                        }                                \
        !           424:                        orig_array_ptr = PG(http_globals)[t]; \
        !           425:                        break;
        !           426: 
        !           427:        switch (arg) {
        !           428:                PARSE_CASE(PARSE_POST,    post_array,    TRACK_VARS_POST)
        !           429:                PARSE_CASE(PARSE_GET,     get_array,     TRACK_VARS_GET)
        !           430:                PARSE_CASE(PARSE_COOKIE,  cookie_array,  TRACK_VARS_COOKIE)
        !           431:                PARSE_CASE(PARSE_SERVER,  server_array,  TRACK_VARS_SERVER)
        !           432:                PARSE_CASE(PARSE_ENV,     env_array,     TRACK_VARS_ENV)
        !           433: 
        !           434:                case PARSE_STRING: /* PARSE_STRING is used by parse_str() function */
        !           435:                        retval = 1;
        !           436:                        break;
        !           437:        }
        !           438: 
        !           439:        /* 
        !           440:         * According to rfc2965, more specific paths are listed above the less specific ones.
        !           441:         * If we encounter a duplicate cookie name, we should skip it, since it is not possible
        !           442:         * to have the same (plain text) cookie name for the same path and we should not overwrite
        !           443:         * more specific cookies with the less specific ones.
        !           444:        */
        !           445:        if (arg == PARSE_COOKIE && orig_array_ptr && zend_symtable_exists(Z_ARRVAL_P(orig_array_ptr), var, strlen(var)+1)) {
        !           446:                return 0;
        !           447:        }
        !           448: 
        !           449:        if (array_ptr) {
        !           450:                /* Make a copy of the variable name, as php_register_variable_ex seems to
        !           451:                 * modify it */
        !           452:                orig_var = estrdup(var);
        !           453: 
        !           454:                /* Store the RAW variable internally */
        !           455:                /* FIXME: Should not use php_register_variable_ex as that also registers
        !           456:                 * globals when register_globals is turned on */
        !           457:                Z_STRLEN(raw_var) = val_len;
        !           458:                Z_STRVAL(raw_var) = estrndup(*val, val_len);
        !           459:                Z_TYPE(raw_var) = IS_STRING;
        !           460: 
        !           461:                php_register_variable_ex(var, &raw_var, array_ptr TSRMLS_CC);
        !           462:        }
        !           463: 
        !           464:        if (val_len) {
        !           465:                /* Register mangled variable */
        !           466:                /* FIXME: Should not use php_register_variable_ex as that also registers
        !           467:                 * globals when register_globals is turned on */
        !           468:                Z_STRLEN(new_var) = val_len;
        !           469:                Z_TYPE(new_var) = IS_STRING;
        !           470: 
        !           471:                if (IF_G(default_filter) != FILTER_UNSAFE_RAW) {
        !           472:                        zval *tmp_new_var = &new_var;
        !           473:                        Z_STRVAL(new_var) = estrndup(*val, val_len);
        !           474:                        INIT_PZVAL(tmp_new_var);
        !           475:                        php_zval_filter(&tmp_new_var, IF_G(default_filter), IF_G(default_filter_flags), NULL, NULL/*charset*/, 0 TSRMLS_CC);
        !           476:                } else if (PG(magic_quotes_gpc) && !retval) { /* for PARSE_STRING php_register_variable_safe() will do the addslashes() */
        !           477:                        Z_STRVAL(new_var) = php_addslashes(*val, Z_STRLEN(new_var), &Z_STRLEN(new_var), 0 TSRMLS_CC);
        !           478:                } else {
        !           479:                        Z_STRVAL(new_var) = estrndup(*val, val_len);
        !           480:                }
        !           481:        } else { /* empty string */
        !           482:                ZVAL_EMPTY_STRING(&new_var);
        !           483:        }
        !           484: 
        !           485:        if (orig_array_ptr) {
        !           486:                php_register_variable_ex(orig_var, &new_var, orig_array_ptr TSRMLS_CC);
        !           487:        }
        !           488:        if (array_ptr) {
        !           489:                efree(orig_var);
        !           490:        }
        !           491: 
        !           492:        if (retval) {
        !           493:                if (new_val_len) {
        !           494:                        *new_val_len = Z_STRLEN(new_var);
        !           495:                }
        !           496:                efree(*val);
        !           497:                if (Z_STRLEN(new_var)) {
        !           498:                        *val = estrndup(Z_STRVAL(new_var), Z_STRLEN(new_var));
        !           499:                } else {
        !           500:                        *val = estrdup("");
        !           501:                }
        !           502:                zval_dtor(&new_var);
        !           503:        }
        !           504: 
        !           505:        return retval;
        !           506: }
        !           507: /* }}} */
        !           508: 
        !           509: static void php_zval_filter_recursive(zval **value, long filter, long flags, zval *options, char *charset, zend_bool copy TSRMLS_DC) /* {{{ */
        !           510: {
        !           511:        if (Z_TYPE_PP(value) == IS_ARRAY) {
        !           512:                zval **element;
        !           513:                HashPosition pos;
        !           514: 
        !           515:                if (Z_ARRVAL_PP(value)->nApplyCount > 1) {
        !           516:                        return;
        !           517:                }
        !           518: 
        !           519:                for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(value), &pos);
        !           520:                         zend_hash_get_current_data_ex(Z_ARRVAL_PP(value), (void **) &element, &pos) == SUCCESS;
        !           521:                         zend_hash_move_forward_ex(Z_ARRVAL_PP(value), &pos)
        !           522:                ) {
        !           523:                        SEPARATE_ZVAL_IF_NOT_REF(element);
        !           524:                        if (Z_TYPE_PP(element) == IS_ARRAY) {
        !           525:                                Z_ARRVAL_PP(element)->nApplyCount++;
        !           526:                                php_zval_filter_recursive(element, filter, flags, options, charset, copy TSRMLS_CC);
        !           527:                                Z_ARRVAL_PP(element)->nApplyCount--;
        !           528:                        } else {
        !           529:                                php_zval_filter(element, filter, flags, options, charset, copy TSRMLS_CC);
        !           530:                        }
        !           531:                }
        !           532:        } else {
        !           533:                php_zval_filter(value, filter, flags, options, charset, copy TSRMLS_CC);
        !           534:        }
        !           535: }
        !           536: /* }}} */
        !           537: 
        !           538: static zval *php_filter_get_storage(long arg TSRMLS_DC)/* {{{ */
        !           539: 
        !           540: {
        !           541:        zval *array_ptr = NULL;
        !           542:        zend_bool jit_initialization = (PG(auto_globals_jit) && !PG(register_globals) && !PG(register_long_arrays));
        !           543: 
        !           544:        switch (arg) {
        !           545:                case PARSE_GET:
        !           546:                        array_ptr = IF_G(get_array);
        !           547:                        break;
        !           548:                case PARSE_POST:
        !           549:                        array_ptr = IF_G(post_array);
        !           550:                        break;
        !           551:                case PARSE_COOKIE:
        !           552:                        array_ptr = IF_G(cookie_array);
        !           553:                        break;
        !           554:                case PARSE_SERVER:
        !           555:                        if (jit_initialization) {
        !           556:                                zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
        !           557:                        }
        !           558:                        array_ptr = IF_G(server_array);
        !           559:                        break;
        !           560:                case PARSE_ENV:
        !           561:                        if (jit_initialization) {
        !           562:                                zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC);
        !           563:                        }
        !           564:                        array_ptr = IF_G(env_array) ? IF_G(env_array) : PG(http_globals)[TRACK_VARS_ENV];
        !           565:                        break;
        !           566:                case PARSE_SESSION:
        !           567:                        /* FIXME: Implement session source */
        !           568:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "INPUT_SESSION is not yet implemented");
        !           569:                        break;
        !           570:                case PARSE_REQUEST:
        !           571:                        /* FIXME: Implement request source */
        !           572:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "INPUT_REQUEST is not yet implemented");
        !           573:                        break;
        !           574:        }
        !           575: 
        !           576:        return array_ptr;
        !           577: }
        !           578: /* }}} */
        !           579: 
        !           580: /* {{{ proto mixed filter_has_var(constant type, string variable_name)
        !           581:  * Returns true if the variable with the name 'name' exists in source.
        !           582:  */
        !           583: PHP_FUNCTION(filter_has_var)
        !           584: {
        !           585:        long        arg;
        !           586:        char       *var;
        !           587:        int         var_len;
        !           588:        zval       *array_ptr = NULL;
        !           589: 
        !           590:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
        !           591:                RETURN_FALSE;
        !           592:        }
        !           593: 
        !           594:        array_ptr = php_filter_get_storage(arg TSRMLS_CC);
        !           595: 
        !           596:        if (array_ptr && HASH_OF(array_ptr) && zend_hash_exists(HASH_OF(array_ptr), var, var_len + 1)) {
        !           597:                RETURN_TRUE;
        !           598:        }
        !           599: 
        !           600:        RETURN_FALSE;
        !           601: }
        !           602: /* }}} */
        !           603: 
        !           604: static void php_filter_call(zval **filtered, long filter, zval **filter_args, const int copy, long filter_flags TSRMLS_DC) /* {{{ */
        !           605: {
        !           606:        zval  *options = NULL;
        !           607:        zval **option;
        !           608:        char  *charset = NULL;
        !           609: 
        !           610:        if (filter_args && Z_TYPE_PP(filter_args) != IS_ARRAY) {
        !           611:                long lval;
        !           612: 
        !           613:                PHP_FILTER_GET_LONG_OPT(filter_args, lval);
        !           614: 
        !           615:                if (filter != -1) { /* handler for array apply */
        !           616:                        /* filter_args is the filter_flags */
        !           617:                        filter_flags = lval;
        !           618: 
        !           619:                        if (!(filter_flags & FILTER_REQUIRE_ARRAY ||  filter_flags & FILTER_FORCE_ARRAY)) {
        !           620:                                filter_flags |= FILTER_REQUIRE_SCALAR;
        !           621:                        }
        !           622:                } else {
        !           623:                        filter = lval;
        !           624:                }
        !           625:        } else if (filter_args) {
        !           626:                if (zend_hash_find(HASH_OF(*filter_args), "filter", sizeof("filter"), (void **)&option) == SUCCESS) {
        !           627:                        PHP_FILTER_GET_LONG_OPT(option, filter);
        !           628:                }
        !           629: 
        !           630:                if (zend_hash_find(HASH_OF(*filter_args), "flags", sizeof("flags"), (void **)&option) == SUCCESS) {
        !           631:                        PHP_FILTER_GET_LONG_OPT(option, filter_flags);
        !           632: 
        !           633:                        if (!(filter_flags & FILTER_REQUIRE_ARRAY ||  filter_flags & FILTER_FORCE_ARRAY)) {
        !           634:                                filter_flags |= FILTER_REQUIRE_SCALAR;
        !           635:                        }
        !           636:                }
        !           637: 
        !           638:                if (zend_hash_find(HASH_OF(*filter_args), "options", sizeof("options"), (void **)&option) == SUCCESS) {
        !           639:                        if (filter != FILTER_CALLBACK) {
        !           640:                                if (Z_TYPE_PP(option) == IS_ARRAY) {
        !           641:                                        options = *option;
        !           642:                                }
        !           643:                        } else {
        !           644:                                options = *option;
        !           645:                                filter_flags = 0;
        !           646:                        }
        !           647:                }
        !           648:        }
        !           649: 
        !           650:        if (Z_TYPE_PP(filtered) == IS_ARRAY) {
        !           651:                if (filter_flags & FILTER_REQUIRE_SCALAR) {
        !           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:                php_zval_filter_recursive(filtered, filter, filter_flags, options, charset, copy TSRMLS_CC);
        !           664:                return;
        !           665:        }
        !           666:        if (filter_flags & FILTER_REQUIRE_ARRAY) {
        !           667:                if (copy) {
        !           668:                        SEPARATE_ZVAL(filtered);
        !           669:                }
        !           670:                zval_dtor(*filtered);
        !           671:                if (filter_flags & FILTER_NULL_ON_FAILURE) {
        !           672:                        ZVAL_NULL(*filtered);
        !           673:                } else {
        !           674:                        ZVAL_FALSE(*filtered);
        !           675:                }
        !           676:                return;
        !           677:        }
        !           678: 
        !           679:        php_zval_filter(filtered, filter, filter_flags, options, charset, copy TSRMLS_CC);
        !           680:        if (filter_flags & FILTER_FORCE_ARRAY) {
        !           681:                zval *tmp;
        !           682: 
        !           683:                ALLOC_ZVAL(tmp);
        !           684:                MAKE_COPY_ZVAL(filtered, tmp);
        !           685: 
        !           686:                zval_dtor(*filtered);
        !           687: 
        !           688:                array_init(*filtered);
        !           689:                add_next_index_zval(*filtered, tmp);
        !           690:        }
        !           691: }
        !           692: /* }}} */
        !           693: 
        !           694: static void php_filter_array_handler(zval *input, zval **op, zval *return_value, zend_bool add_empty TSRMLS_DC) /* {{{ */
        !           695: {
        !           696:        char *arg_key;
        !           697:        uint arg_key_len;
        !           698:        ulong index;
        !           699:        HashPosition pos;
        !           700:        zval **tmp, **arg_elm;
        !           701: 
        !           702:        if (!op) {
        !           703:                zval_dtor(return_value);
        !           704:                MAKE_COPY_ZVAL(&input, return_value);
        !           705:                php_filter_call(&return_value, FILTER_DEFAULT, NULL, 0, FILTER_REQUIRE_ARRAY TSRMLS_CC);
        !           706:        } else if (Z_TYPE_PP(op) == IS_LONG) {
        !           707:                zval_dtor(return_value);
        !           708:                MAKE_COPY_ZVAL(&input, return_value);
        !           709:                php_filter_call(&return_value, Z_LVAL_PP(op), NULL, 0, FILTER_REQUIRE_ARRAY TSRMLS_CC);
        !           710:        } else if (Z_TYPE_PP(op) == IS_ARRAY) {
        !           711:                array_init(return_value);
        !           712: 
        !           713:                zend_hash_internal_pointer_reset(Z_ARRVAL_PP(op));
        !           714:                for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(op), &pos);
        !           715:                        zend_hash_get_current_data_ex(Z_ARRVAL_PP(op), (void **) &arg_elm, &pos) == SUCCESS;
        !           716:                        zend_hash_move_forward_ex(Z_ARRVAL_PP(op), &pos))
        !           717:                {
        !           718:                        if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(op), &arg_key, &arg_key_len, &index, 0, &pos) != HASH_KEY_IS_STRING) {
        !           719:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric keys are not allowed in the definition array");
        !           720:                                zval_dtor(return_value);
        !           721:                                RETURN_FALSE;
        !           722:                        }
        !           723:                        if (arg_key_len < 2) {
        !           724:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty keys are not allowed in the definition array");
        !           725:                                zval_dtor(return_value);
        !           726:                                RETURN_FALSE;
        !           727:                        }
        !           728:                        if (zend_hash_find(Z_ARRVAL_P(input), arg_key, arg_key_len, (void **)&tmp) != SUCCESS) {
        !           729:                                if (add_empty) {
        !           730:                                        add_assoc_null_ex(return_value, arg_key, arg_key_len);
        !           731:                                }
        !           732:                        } else {
        !           733:                                zval *nval;
        !           734: 
        !           735:                                ALLOC_ZVAL(nval);
        !           736:                                MAKE_COPY_ZVAL(tmp, nval);
        !           737: 
        !           738:                                php_filter_call(&nval, -1, arg_elm, 0, FILTER_REQUIRE_SCALAR TSRMLS_CC);
        !           739:                                add_assoc_zval_ex(return_value, arg_key, arg_key_len, nval);
        !           740:                        }
        !           741:                }
        !           742:        } else {
        !           743:                RETURN_FALSE;
        !           744:        }
        !           745: }
        !           746: /* }}} */
        !           747: 
        !           748: /* {{{ proto mixed filter_input(constant type, string variable_name [, long filter [, mixed options]])
        !           749:  * Returns the filtered variable 'name'* from source `type`.
        !           750:  */
        !           751: PHP_FUNCTION(filter_input)
        !           752: {
        !           753:        long   fetch_from, filter = FILTER_DEFAULT;
        !           754:        zval **filter_args = NULL, **tmp;
        !           755:        zval  *input = NULL;
        !           756:        char *var;
        !           757:        int var_len;
        !           758: 
        !           759:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|lZ", &fetch_from, &var, &var_len, &filter, &filter_args) == FAILURE) {
        !           760:                return;
        !           761:        }
        !           762: 
        !           763:        if (!PHP_FILTER_ID_EXISTS(filter)) {
        !           764:                RETURN_FALSE;
        !           765:        }
        !           766: 
        !           767:        input = php_filter_get_storage(fetch_from TSRMLS_CC);
        !           768: 
        !           769:        if (!input || !HASH_OF(input) || zend_hash_find(HASH_OF(input), var, var_len + 1, (void **)&tmp) != SUCCESS) {
        !           770:                long filter_flags = 0;
        !           771:                zval **option, **opt, **def;
        !           772:                if (filter_args) {
        !           773:                        if (Z_TYPE_PP(filter_args) == IS_LONG) {
        !           774:                                filter_flags = Z_LVAL_PP(filter_args);
        !           775:                        } else if (Z_TYPE_PP(filter_args) == IS_ARRAY && zend_hash_find(HASH_OF(*filter_args), "flags", sizeof("flags"), (void **)&option) == SUCCESS) {
        !           776:                                PHP_FILTER_GET_LONG_OPT(option, filter_flags);
        !           777:                        }
        !           778:                        if (Z_TYPE_PP(filter_args) == IS_ARRAY && 
        !           779:                                zend_hash_find(HASH_OF(*filter_args), "options", sizeof("options"), (void **)&opt) == SUCCESS &&
        !           780:                                Z_TYPE_PP(opt) == IS_ARRAY &&
        !           781:                                zend_hash_find(HASH_OF(*opt), "default", sizeof("default"), (void **)&def) == SUCCESS
        !           782:                        ) {
        !           783:                                MAKE_COPY_ZVAL(def, return_value);
        !           784:                                return;
        !           785:                        }
        !           786:                }
        !           787: 
        !           788:                /* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of
        !           789:                 * the function: normally when validation fails false is returned, and
        !           790:                 * when the input value doesn't exist NULL is returned. With the flag
        !           791:                 * set, NULL and false should be returned, respectively. Ergo, although
        !           792:                 * the code below looks incorrect, it's actually right. */
        !           793:                if (filter_flags & FILTER_NULL_ON_FAILURE) {
        !           794:                        RETURN_FALSE;
        !           795:                } else {
        !           796:                        RETURN_NULL();
        !           797:                }
        !           798:        }
        !           799: 
        !           800:        MAKE_COPY_ZVAL(tmp, return_value);
        !           801: 
        !           802:        php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC);
        !           803: }
        !           804: /* }}} */
        !           805: 
        !           806: /* {{{ proto mixed filter_var(mixed variable [, long filter [, mixed options]])
        !           807:  * Returns the filtered version of the vriable.
        !           808:  */
        !           809: PHP_FUNCTION(filter_var)
        !           810: {
        !           811:        long filter = FILTER_DEFAULT;
        !           812:        zval **filter_args = NULL, *data;
        !           813: 
        !           814:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/|lZ", &data, &filter, &filter_args) == FAILURE) {
        !           815:                return;
        !           816:        }
        !           817: 
        !           818:        if (!PHP_FILTER_ID_EXISTS(filter)) {
        !           819:                RETURN_FALSE;
        !           820:        }
        !           821: 
        !           822:        MAKE_COPY_ZVAL(&data, return_value);
        !           823: 
        !           824:        php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC);
        !           825: }
        !           826: /* }}} */
        !           827: 
        !           828: /* {{{ proto mixed filter_input_array(constant type, [, mixed options [, bool add_empty]]])
        !           829:  * Returns an array with all arguments defined in 'definition'.
        !           830:  */
        !           831: PHP_FUNCTION(filter_input_array)
        !           832: {
        !           833:        long    fetch_from;
        !           834:        zval   *array_input = NULL, **op = NULL;
        !           835:        zend_bool add_empty = 1;
        !           836: 
        !           837:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|Zb",  &fetch_from, &op, &add_empty) == FAILURE) {
        !           838:                return;
        !           839:        }
        !           840: 
        !           841:        if (op
        !           842:                && (Z_TYPE_PP(op) != IS_ARRAY)
        !           843:                && (Z_TYPE_PP(op) == IS_LONG && !PHP_FILTER_ID_EXISTS(Z_LVAL_PP(op)))
        !           844:                ) {
        !           845:                RETURN_FALSE;
        !           846:        }
        !           847: 
        !           848:        array_input = php_filter_get_storage(fetch_from TSRMLS_CC);
        !           849: 
        !           850:        if (!array_input || !HASH_OF(array_input)) {
        !           851:                long filter_flags = 0;
        !           852:                zval **option;
        !           853:                if (op) {
        !           854:                        if (Z_TYPE_PP(op) == IS_LONG) {
        !           855:                                filter_flags = Z_LVAL_PP(op);
        !           856:                        } else if (Z_TYPE_PP(op) == IS_ARRAY && zend_hash_find(HASH_OF(*op), "flags", sizeof("flags"), (void **)&option) == SUCCESS) {
        !           857:                                PHP_FILTER_GET_LONG_OPT(option, filter_flags);
        !           858:                        }
        !           859:                }
        !           860: 
        !           861:                /* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of
        !           862:                 * the function: normally when validation fails false is returned, and
        !           863:                 * when the input value doesn't exist NULL is returned. With the flag
        !           864:                 * set, NULL and false should be returned, respectively. Ergo, although
        !           865:                 * the code below looks incorrect, it's actually right. */
        !           866:                if (filter_flags & FILTER_NULL_ON_FAILURE) {
        !           867:                        RETURN_FALSE;
        !           868:                } else {
        !           869:                        RETURN_NULL();
        !           870:                }
        !           871:        }
        !           872: 
        !           873:        php_filter_array_handler(array_input, op, return_value, add_empty TSRMLS_CC);
        !           874: }
        !           875: /* }}} */
        !           876: 
        !           877: /* {{{ proto mixed filter_var_array(array data, [, mixed options [, bool add_empty]]])
        !           878:  * Returns an array with all arguments defined in 'definition'.
        !           879:  */
        !           880: PHP_FUNCTION(filter_var_array)
        !           881: {
        !           882:        zval *array_input = NULL, **op = NULL;
        !           883:        zend_bool add_empty = 1;
        !           884: 
        !           885:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|Zb",  &array_input, &op, &add_empty) == FAILURE) {
        !           886:                return;
        !           887:        }
        !           888: 
        !           889:        if (op
        !           890:                && (Z_TYPE_PP(op) != IS_ARRAY)
        !           891:                && (Z_TYPE_PP(op) == IS_LONG && !PHP_FILTER_ID_EXISTS(Z_LVAL_PP(op)))
        !           892:                ) {
        !           893:                RETURN_FALSE;
        !           894:        }
        !           895: 
        !           896:        php_filter_array_handler(array_input, op, return_value, add_empty TSRMLS_CC);
        !           897: }
        !           898: /* }}} */
        !           899: 
        !           900: /* {{{ proto filter_list()
        !           901:  * Returns a list of all supported filters */
        !           902: PHP_FUNCTION(filter_list)
        !           903: {
        !           904:        int i, size = sizeof(filter_list) / sizeof(filter_list_entry);
        !           905: 
        !           906:        if (zend_parse_parameters_none() == FAILURE) {
        !           907:                return;
        !           908:        }
        !           909: 
        !           910:        array_init(return_value);
        !           911:        for (i = 0; i < size; ++i) {
        !           912:                add_next_index_string(return_value, (char *)filter_list[i].name, 1);
        !           913:        }
        !           914: }
        !           915: /* }}} */
        !           916: 
        !           917: /* {{{ proto filter_id(string filtername)
        !           918:  * Returns the filter ID belonging to a named filter */
        !           919: PHP_FUNCTION(filter_id)
        !           920: {
        !           921:        int i, filter_len;
        !           922:        int size = sizeof(filter_list) / sizeof(filter_list_entry);
        !           923:        char *filter;
        !           924: 
        !           925:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filter, &filter_len) == FAILURE) {
        !           926:                return;
        !           927:        }
        !           928: 
        !           929:        for (i = 0; i < size; ++i) {
        !           930:                if (strcmp(filter_list[i].name, filter) == 0) {
        !           931:                        RETURN_LONG(filter_list[i].id);
        !           932:                }
        !           933:        }
        !           934: 
        !           935:        RETURN_FALSE;
        !           936: }
        !           937: /* }}} */
        !           938: 
        !           939: /*
        !           940:  * Local variables:
        !           941:  * tab-width: 4
        !           942:  * c-basic-offset: 4
        !           943:  * End:
        !           944:  * vim600: noet sw=4 ts=4 fdm=marker
        !           945:  * vim<600: noet sw=4 ts=4
        !           946:  */

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