diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/filter | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/filter')
93 files changed, 5890 insertions, 0 deletions
diff --git a/ext/filter/CREDITS b/ext/filter/CREDITS new file mode 100644 index 0000000..8d75401 --- /dev/null +++ b/ext/filter/CREDITS @@ -0,0 +1,2 @@ +Input Filter +Rasmus Lerdorf, Derick Rethans, Pierre-Alain Joye, Ilia Alshanetsky diff --git a/ext/filter/callback_filter.c b/ext/filter/callback_filter.c new file mode 100644 index 0000000..3beacb6 --- /dev/null +++ b/ext/filter/callback_filter.c @@ -0,0 +1,63 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans <derick@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include "php_filter.h" + +void php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL) +{ + zval *retval_ptr; + zval ***args; + int status; + + if (!option_array || !zend_is_callable(option_array, IS_CALLABLE_CHECK_NO_ACCESS, NULL TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument is expected to be a valid callback"); + zval_dtor(value); + Z_TYPE_P(value) = IS_NULL; + return; + } + + args = safe_emalloc(sizeof(zval **), 1, 0); + args[0] = &value; + + status = call_user_function_ex(EG(function_table), NULL, option_array, &retval_ptr, 1, args, 0, NULL TSRMLS_CC); + + if (status == SUCCESS && retval_ptr != NULL) { + if (retval_ptr != value) { + zval_dtor(value); + COPY_PZVAL_TO_ZVAL(*value, retval_ptr); + } else { + zval_ptr_dtor(&retval_ptr); + } + } else { + zval_dtor(value); + Z_TYPE_P(value) = IS_NULL; + } + + efree(args); +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/filter/config.m4 b/ext/filter/config.m4 new file mode 100644 index 0000000..b4e32a2 --- /dev/null +++ b/ext/filter/config.m4 @@ -0,0 +1,47 @@ +dnl $Id$ +dnl config.m4 for input filtering extension + +PHP_ARG_ENABLE(filter, whether to enable input filter support, +[ --disable-filter Disable input filter support], yes) + +PHP_ARG_WITH(pcre-dir, pcre install prefix, +[ --with-pcre-dir FILTER: pcre install prefix], no, no) + +if test "$PHP_FILTER" != "no"; then + + dnl Check if configure is the PHP core configure + if test -n "$PHP_VERSION"; then + dnl This extension can not be build as shared when in PHP core + ext_shared=no + else + dnl This is PECL build, check if bundled PCRE library is used + old_CPPFLAGS=$CPPFLAGS + CPPFLAGS=$INCLUDES + AC_EGREP_CPP(yes,[ +#include <main/php_config.h> +#if defined(HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE) +yes +#endif + ],[ + PHP_PCRE_REGEX=yes + ],[ + AC_EGREP_CPP(yes,[ +#include <main/php_config.h> +#if defined(HAVE_PCRE) && !defined(COMPILE_DL_PCRE) +yes +#endif + ],[ + PHP_PCRE_REGEX=pecl + ],[ + PHP_PCRE_REGEX=no + ]) + ]) + CPPFLAGS=$old_CPPFLAGS + fi + + PHP_NEW_EXTENSION(filter, filter.c sanitizing_filters.c logical_filters.c callback_filter.c, $ext_shared) + PHP_SUBST(FILTER_SHARED_LIBADD) + + PHP_INSTALL_HEADERS([ext/filter/php_filter.h]) + PHP_ADD_EXTENSION_DEP(filter, pcre) +fi diff --git a/ext/filter/config.w32 b/ext/filter/config.w32 new file mode 100644 index 0000000..b74f3a2 --- /dev/null +++ b/ext/filter/config.w32 @@ -0,0 +1,9 @@ +// $Id$ +// vim:ft=javascript + +ARG_ENABLE("filter", "Filter Support", "yes"); + +if (PHP_FILTER == "yes") { + EXTENSION("filter", "filter.c sanitizing_filters.c logical_filters.c callback_filter.c"); + PHP_INSTALL_HEADERS("ext/filter", "php_filter.h"); +} diff --git a/ext/filter/docs/filter.txt b/ext/filter/docs/filter.txt new file mode 100644 index 0000000..48aae0c --- /dev/null +++ b/ext/filter/docs/filter.txt @@ -0,0 +1,331 @@ +Input Filter Extension +~~~~~~~~~~~~~~~~~~~~~~ + +Introduction +============ +We all know that you should always check input variables, but PHP does not +offer really good functionality for doing this in a safe way. The Input Filter +extension is meant to address this issue by implementing a set of filters and +mechanisms that users can use to safely access their input data. + + +Change Log +========== +2005-10-27 + * Updated filter_data prototype + * Added filter constants + * Fixed minor problems + * Changes by David Tulloh + +2005-10-05 + * Changed "input_filter.paranoid_admin_default_filter" to + "filter.default". + * Updated API prototypes to reflect implementation. + * Added 'on' and 'off' to the boolean filter. + * Removed min_range and max_range flags from the float filter. + * Added validate_url, validate_email and validate_ip filters. + * Updated allows flags for all filters. + +2005-08-15 + * Unmade *source* a bitmask, it doesn't make sense to do. + * Changed return value of filters which got invalid data from 'false' to + 'null. + * Failed filters do not throw an E_NOTICE any longer. + * Added a magic_quotes sanitizing filter. + + +General Considerations +====================== +* If the filter's expected input data mask does not match the provided data + for logical filters the filter function returns "false". If the data was + not found, "null" is returned. +* Character filters always return a string. +* With the input filter extension enabled, and the + input_filter.paranoid_admin_default_filter is set to something != 'raw', + then all entries in the affected super globals will be passed through the + configured filter. The 'callback' filter can not be used here, as that + requieres a PHP script to be running already. +* As the input filter acts on input data before the magic quotes function + mangles data, all access through the filter() function will not have any + quotes or slashes added - it will be the pure data as send by the browser. +* All flags mentioned here should be prepended with `FILTER_FLAG_` when used + with PHP. + + +API +=== +mixed *input_get* (int *source*, string *name*, [, int *filter* [, mixed *filter_options*, [ string *characterset* ] ]); + Returns the filtered variable *$name* from source *$source*. It uses the + filter as specified in *$filter* with a constant, and additional options + to the filter through *$filter_options*. + +mixed *input_get_args* (array *definitions*, int *source*, [, array *data*]); + Returns an array with all filtered variables defined in 'definition'. + The keys are used as the name of the argument. The value can be either + an integer (flags) or an array of options. This array can contain + the 'filter' type, the 'flags', the 'otptions' or the 'charset' + +bool *input_has_variable (int *source*, string *name*); + Returns *true* if the variable with the name *name* exists in *source*, or + *false* otherwise. + +array *input_filters_list* (); + Returns a list with all supported filter names. + +mixed *filter_data* (mixed *variable*, int *filter* [, mixed *filter_options*, [ string *characterset* ] ]); + Filters the user supplied variable *$variable* in the same manner as + *input_get*. + +*$source*: + +* INPUT_POST 0 +* INPUT_GET 1 +* INPUT_COOKIE 2 +* INPUT_ENV 4 +* INPUT_SERVER 5 (not implemented yet) +* INPUT_SESSION 6 (not implemented yet) + + +General flags +============= + +* FILTER_FLAG_SCALAR +* FILTER_FLAG_ARRAY + +These two constants define whether to allow arrays in the source values. The +default value is SCALAR for input_get_args and ARRAY for the other functions +(< 0.9.5). These constants also insure that the function returns the correct +type, if you ask for an array, you will get an array even if the source is +only one value. However, if you ask for a scalar and the source is an array, +the result will be FALSE (invalid). + + +Logical Filters +=============== + +These filters check whether passed data was valid, and do never mangle input +variables, but ofcourse they can deny the whole input variable getting to the +application by returning false. + +The constants should be prepended by `FILTER_VALIDATE_` when used with php. + +================ ========== =========== ================================================== +Name Constant Return Type Description +================ ========== =========== ================================================== +int INT integer Returns the input variable as an integer + + $filter_options - an array with the optional + elements: + + * min_range: Minimal number that is allowed + (inclusive) + * max_range: Maximum number that is allowed + (inclusive) + * flags: A bitmask supporting the following flags: + + - ALLOW_OCTAL: allow octal numbers with the format + 0nn as input too. + - ALLOW_HEX: allow hexadecimal numbers with the + format 0xnn or 0Xnn too. + +boolean BOOLEAN boolean Returns *true* for '1', 'on' and 'true' and *false* + for '0', 'off' and 'false' + +float FLOAT float Returns the input variable as a floating point value + +validate_regexp REGEXP string Matches the input value as a string against the + regular expression. If there is a match then the + string is returned, otherwise the filter returns + *null*. + Remarks: Only available if pcre has been compiled + into PHP. + +validate_url URL string Validates an URL's format. + + $filter_options - an bitmask that supports the + following flags: + + * SCHEME_REQUIRED: The 'schema' part of the URL + needs to in the passed URL. + * HOST_REQUIRED: The 'host' part of the URL + needs to in the passed URL. + * PATH_REQUIRED: The 'path' part of the URL + needs to in the passed URL. + * QUERY_REQUIRED: The 'query' part of the URL + needs to in the passed URL. + +validate_email EMAIL string Validates the passed string against a reasonably + good regular expression for validating an email + address. + +validate_ip IP string Validates a string representing an IP address. + + $filter_options - an bitmask that supports the + following flags: + + * IPV4: Allows IPv4 addresses. + * IPV6: Allows IPv6 addresses. + * NO_RES_RANGE: Disallows addresses in reversed + ranges (IPv4 only) + * NO_PRIV_RANGE: Disallows addresses in private + ranges (IPv4 only) +================ ========== =========== ================================================== + + +Sanitizing Filters +================== + +These filters remove data, or change data depending on the filter, and the +set rules for this specific filter. Instead of taking an *options* array, they +use this parameter for flags for the specific filter. + +The constants should be prepended by `FILTER_SANITIZE_` when used with php. + +============= ================ =========== ===================================================== +Name Constant Return Type Description +============= ================ =========== ===================================================== +string STRING string Returns the input variable as a string after it has + been stripped of XML/HTML tags and other evil things + that can cause XSS problems. + + $filter_options - an bitmask that supports the + following flags: + + * NO_ENCODE_QUOTES: Prevents single and double + quotes from being encoded as numerical HTML + entities. + * STRIP_LOW: excludes all characters < 0x20 from the + allowed character list + * STRIP_HIGH: excludes all characters >= 0x80 from + the allowed character list + * ENCODE_LOW: allows characters < 0x20 but encodes + them as numerical HTML entities + * ENCODE_HIGH: allows characters >= 0x80 but encodes + them as numerical HTML entities + * ENCODE_AMP: encodes & as & + + The flags STRIP_LOW and ENCODE_LOW are mutual + exclusive, and so are STRIP_HIGH and ENCODE_HIGH. In + the case they clash, the characters will be + stripped. + +stripped STRIPPED string Alias for 'string'. + +encoded ENCODED string Encodes all characters outside the range + "a-zA-Z0-9-._" as URL encoded values. + + $filter_options - an bitmask that supports the + following flags: + + * STRIP_LOW: excludes all characters < 0x20 from the + allowed character list + * STRIP_HIGH: excludes all characters >= 0x80 from + the allowed character list + * ENCODE_LOW: allows characters < 0x20 but encodes + them as numerical HTML entities + * ENCODE_HIGH: allows characters >= 0x80 but encodes + them as numerical HTML entities + +special_chars SPECIAL_CHARS string Encodes the 'special' characters ' " < > &, \0 and + everything below 0x20 as numerical HTML entities. + + $filter_options - an bitmask that supports the + following flags: + + * STRIP_LOW: excludes all characters < 0x20 from the + allowed character list. If this is not set, then + those characters are encoded as numerical HTML + entities + * STRIP_HIGH: excludes all characters >= 0x80 from + the allowed character list + * ENCODE_HIGH: allows characters >= 0x80 but encodes + them as numerical HTML entities + +unsafe_raw UNSAFE_RAW string Returns the input variable as a string without + XML/HTML being stripped from the input value. + + $filter_options - an bitmask that supports the + following flags: + + * STRIP_LOW: excludes all characters < 0x20 from the + allowed character list + * STRIP_HIGH: excludes all characters >= 0x80 from + the allowed character list + * ENCODE_LOW: allows characters < 0x20 but encodes + them as numerical HTML entities + * ENCODE_HIGH: allows characters >= 0x80 but encodes + them as numerical HTML entities + * ENCODE_AMP: encodes & as & + + The flags STRIP_LOW and ENCODE_LOW are mutual + exclusive, and so are STRIP_HIGH and ENCODE_HIGH. In + the case they clash, the characters will be + stripped. + +email EMAIL string Removes all characters that can not be part of a + correctly formed e-mail address (exception are + comments in the email address) (a-z A-Z 0-9 " ! # $ + % & ' * + - / = ? ^ _ ` { | } ~ @ . [ ]). This + filter does `not` validate if the e-mail address has + the correct format, use the validate_email filter + for that. + +url URL string Removes all characters that can not be part of a + correctly formed URI. (a-z A-Z 0-9 $ - _ . + ! * ' ( + ) , { } | \ ^ ~ [ ] ` < > # % " ; / ? : @ & =) This + filter does `not` validate if a URI has the correct + format, use the validate_url filter for that. + +number_int NUMBER_INT int Removes all characters that are [^0-9+-]. + +number_float NUMBER_FLOAT float Removes all characters that are [^0-9+-]. + + $filter_options - an bitmask that supports the + following flags: + + * ALLOW_FRACTION: adds "." to the characters that + are not stripped. + * ALLOW_THOUSAND: adds "," to the characters that + are not stripped. + * ALLOW_SCIENTIFIC: adds "eE" to the characters that + are not stripped. + +magic_quotes MAGIC_QUOTES string BC filter for people who like magic quotes. +============= ================ =========== ===================================================== + + +Callback Filter +=============== + +This filter will callback to the specified callback function as specified with +the *filter_options* parameter. All variants of callback functions are +supported: + +* function with *'functionname'* +* static method with *array('classname', 'methodname')* +* dynamic method with *array(&$this, 'methodname')* + +The constants should be prepended by `FILTER_` when used with php. + +============= =========== =========== ===================================================== +Name Constant Return Type Description +============= =========== =========== ===================================================== +callback CALLBACK mixed Calls the callback function/method with the input + variable's value by reference which can do filtering + and modifying of the input value. If the callback + function returns "false" then the input value is + supposed to be incorrect and the returned value will + be 'false' (and an E_NOTICE will be raised). +============= =========== =========== ===================================================== + +The callback function's prototype is: + +boolean callback(&$value, $characterset); + With *$value* being a reference to the input variable and *$characterset* + containing the same value as this parameter's value in the call to + *input_get()* or *input_get_array()*. If the *$characterset* parameter was + not passed, it defaults to *'null'*. + +Version: $Id$ +.. vim: et syn=rst tw=78 + diff --git a/ext/filter/docs/input_get_args.php b/ext/filter/docs/input_get_args.php new file mode 100644 index 0000000..b580524 --- /dev/null +++ b/ext/filter/docs/input_get_args.php @@ -0,0 +1,41 @@ +<?php +error_reporting(E_ALL|E_STRICT); +$data = array( + 'product_id' => 'product id<script>', + 'component' => '10', + 'versions' => '1.2.33', + 'testscalar' => array('2','23','10','12'), + 'testarray' => '2', +); + +$args = array( + 'product_id' => FILTER_SANITIZE_ENCODED, + 'component' => array('filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FLAG_ARRAY, + 'options' => array("min_range"=>1, "max_range"=>10) + ), + + /* equivalent of => FILTER_SANITIZE_ENCODED as SCALAR is + * the default mode + */ + 'versions' => array( + 'filter' => FILTER_SANITIZE_ENCODED, + 'flags' => FILTER_FLAG_SCALAR, + ), + 'doesnotexist' => FILTER_VALIDATE_INT, + 'testscalar' => FILTER_VALIDATE_INT, + 'testarray' => array( + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FLAG_ARRAY, + ) + +); + +/* +The other INPUT_* can be used as well. +$myinputs = input_get_args($args, INPUT_POST); +*/ +$myinputs = input_get_args($args, INPUT_DATA, $data); + +var_dump($myinputs); + diff --git a/ext/filter/filter.c b/ext/filter/filter.c new file mode 100644 index 0000000..d4053d0 --- /dev/null +++ b/ext/filter/filter.c @@ -0,0 +1,931 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@php.net> | + | Derick Rethans <derick@php.net> | + | Pierre-A. Joye <pierre@php.net> | + | Ilia Alshanetsky <iliaa@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id: 2aa8dd57d9c0c655cd45e6e5872bb95fa5ad76cf $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php_filter.h" + +ZEND_DECLARE_MODULE_GLOBALS(filter) + +#include "filter_private.h" + +typedef struct filter_list_entry { + const char *name; + int id; + void (*function)(PHP_INPUT_FILTER_PARAM_DECL); +} filter_list_entry; + +/* {{{ filter_list */ +static const filter_list_entry filter_list[] = { + { "int", FILTER_VALIDATE_INT, php_filter_int }, + { "boolean", FILTER_VALIDATE_BOOLEAN, php_filter_boolean }, + { "float", FILTER_VALIDATE_FLOAT, php_filter_float }, + + { "validate_regexp", FILTER_VALIDATE_REGEXP, php_filter_validate_regexp }, + { "validate_url", FILTER_VALIDATE_URL, php_filter_validate_url }, + { "validate_email", FILTER_VALIDATE_EMAIL, php_filter_validate_email }, + { "validate_ip", FILTER_VALIDATE_IP, php_filter_validate_ip }, + + { "string", FILTER_SANITIZE_STRING, php_filter_string }, + { "stripped", FILTER_SANITIZE_STRING, php_filter_string }, + { "encoded", FILTER_SANITIZE_ENCODED, php_filter_encoded }, + { "special_chars", FILTER_SANITIZE_SPECIAL_CHARS, php_filter_special_chars }, + { "full_special_chars", FILTER_SANITIZE_FULL_SPECIAL_CHARS, php_filter_full_special_chars }, + { "unsafe_raw", FILTER_UNSAFE_RAW, php_filter_unsafe_raw }, + { "email", FILTER_SANITIZE_EMAIL, php_filter_email }, + { "url", FILTER_SANITIZE_URL, php_filter_url }, + { "number_int", FILTER_SANITIZE_NUMBER_INT, php_filter_number_int }, + { "number_float", FILTER_SANITIZE_NUMBER_FLOAT, php_filter_number_float }, + { "magic_quotes", FILTER_SANITIZE_MAGIC_QUOTES, php_filter_magic_quotes }, + + { "callback", FILTER_CALLBACK, php_filter_callback }, +}; +/* }}} */ + +#ifndef PARSE_ENV +#define PARSE_ENV 4 +#endif + +#ifndef PARSE_SERVER +#define PARSE_SERVER 5 +#endif + +#ifndef PARSE_SESSION +#define PARSE_SESSION 6 +#endif + +static unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); +static unsigned int php_sapi_filter_init(TSRMLS_D); + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_input, 0, 0, 2) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, variable_name) + ZEND_ARG_INFO(0, filter) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_var, 0, 0, 1) + ZEND_ARG_INFO(0, variable) + ZEND_ARG_INFO(0, filter) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_input_array, 0, 0, 1) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, definition) + ZEND_ARG_INFO(0, add_empty) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_var_array, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, definition) + ZEND_ARG_INFO(0, add_empty) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_filter_list, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_has_var, 0, 0, 2) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, variable_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_filter_id, 0, 0, 1) + ZEND_ARG_INFO(0, filtername) +ZEND_END_ARG_INFO() +/* }}} */ + +/* {{{ filter_functions[] + */ +static const zend_function_entry filter_functions[] = { + PHP_FE(filter_input, arginfo_filter_input) + PHP_FE(filter_var, arginfo_filter_var) + PHP_FE(filter_input_array, arginfo_filter_input_array) + PHP_FE(filter_var_array, arginfo_filter_var_array) + PHP_FE(filter_list, arginfo_filter_list) + PHP_FE(filter_has_var, arginfo_filter_has_var) + PHP_FE(filter_id, arginfo_filter_id) + PHP_FE_END +}; +/* }}} */ + +/* {{{ filter_module_entry + */ +zend_module_entry filter_module_entry = { +#if ZEND_MODULE_API_NO >= 20010901 + STANDARD_MODULE_HEADER, +#endif + "filter", + filter_functions, + PHP_MINIT(filter), + PHP_MSHUTDOWN(filter), + NULL, + PHP_RSHUTDOWN(filter), + PHP_MINFO(filter), + "0.11.0", + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +#ifdef COMPILE_DL_FILTER +ZEND_GET_MODULE(filter) +#endif + +static PHP_INI_MH(UpdateDefaultFilter) /* {{{ */ +{ + int i, size = sizeof(filter_list) / sizeof(filter_list_entry); + + for (i = 0; i < size; ++i) { + if ((strcasecmp(new_value, filter_list[i].name) == 0)) { + IF_G(default_filter) = filter_list[i].id; + return SUCCESS; + } + } + /* Fallback to the default filter */ + IF_G(default_filter) = FILTER_DEFAULT; + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_INI + */ +static PHP_INI_MH(OnUpdateFlags) +{ + if (!new_value) { + IF_G(default_filter_flags) = FILTER_FLAG_NO_ENCODE_QUOTES; + } else { + IF_G(default_filter_flags) = atoi(new_value); + } + return SUCCESS; +} + +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("filter.default", "unsafe_raw", PHP_INI_SYSTEM|PHP_INI_PERDIR, UpdateDefaultFilter, default_filter, zend_filter_globals, filter_globals) + PHP_INI_ENTRY("filter.default_flags", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateFlags) +PHP_INI_END() +/* }}} */ + +static void php_filter_init_globals(zend_filter_globals *filter_globals) /* {{{ */ +{ + filter_globals->post_array = NULL; + filter_globals->get_array = NULL; + filter_globals->cookie_array = NULL; + filter_globals->env_array = NULL; + filter_globals->server_array = NULL; + filter_globals->session_array = NULL; + filter_globals->default_filter = FILTER_DEFAULT; +} +/* }}} */ + +#define PARSE_REQUEST 99 + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(filter) +{ + ZEND_INIT_MODULE_GLOBALS(filter, php_filter_init_globals, NULL); + + REGISTER_INI_ENTRIES(); + + REGISTER_LONG_CONSTANT("INPUT_POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INPUT_GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INPUT_COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INPUT_ENV", PARSE_ENV, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INPUT_SERVER", PARSE_SERVER, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INPUT_SESSION", PARSE_SESSION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INPUT_REQUEST", PARSE_REQUEST, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_FLAG_NONE", FILTER_FLAG_NONE, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_REQUIRE_SCALAR", FILTER_REQUIRE_SCALAR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_REQUIRE_ARRAY", FILTER_REQUIRE_ARRAY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FORCE_ARRAY", FILTER_FORCE_ARRAY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_NULL_ON_FAILURE", FILTER_NULL_ON_FAILURE, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_INT", FILTER_VALIDATE_INT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_BOOLEAN", FILTER_VALIDATE_BOOLEAN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_FLOAT", FILTER_VALIDATE_FLOAT, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_REGEXP", FILTER_VALIDATE_REGEXP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_URL", FILTER_VALIDATE_URL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_EMAIL", FILTER_VALIDATE_EMAIL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_IP", FILTER_VALIDATE_IP, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_DEFAULT", FILTER_DEFAULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_UNSAFE_RAW", FILTER_UNSAFE_RAW, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRING", FILTER_SANITIZE_STRING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRIPPED", FILTER_SANITIZE_STRING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_ENCODED", FILTER_SANITIZE_ENCODED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_SPECIAL_CHARS", FILTER_SANITIZE_SPECIAL_CHARS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_FULL_SPECIAL_CHARS", FILTER_SANITIZE_SPECIAL_CHARS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_EMAIL", FILTER_SANITIZE_EMAIL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_URL", FILTER_SANITIZE_URL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_NUMBER_INT", FILTER_SANITIZE_NUMBER_INT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_NUMBER_FLOAT", FILTER_SANITIZE_NUMBER_FLOAT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_SANITIZE_MAGIC_QUOTES", FILTER_SANITIZE_MAGIC_QUOTES, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_CALLBACK", FILTER_CALLBACK, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_OCTAL", FILTER_FLAG_ALLOW_OCTAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_HEX", FILTER_FLAG_ALLOW_HEX, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_LOW", FILTER_FLAG_STRIP_LOW, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_HIGH", FILTER_FLAG_STRIP_HIGH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_BACKTICK", FILTER_FLAG_STRIP_BACKTICK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_ENCODE_LOW", FILTER_FLAG_ENCODE_LOW, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_ENCODE_HIGH", FILTER_FLAG_ENCODE_HIGH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_ENCODE_AMP", FILTER_FLAG_ENCODE_AMP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_ENCODE_QUOTES", FILTER_FLAG_NO_ENCODE_QUOTES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_EMPTY_STRING_NULL", FILTER_FLAG_EMPTY_STRING_NULL, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_FRACTION", FILTER_FLAG_ALLOW_FRACTION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_THOUSAND", FILTER_FLAG_ALLOW_THOUSAND, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_SCIENTIFIC", FILTER_FLAG_ALLOW_SCIENTIFIC, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_FLAG_SCHEME_REQUIRED", FILTER_FLAG_SCHEME_REQUIRED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_HOST_REQUIRED", FILTER_FLAG_HOST_REQUIRED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_PATH_REQUIRED", FILTER_FLAG_PATH_REQUIRED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_QUERY_REQUIRED", FILTER_FLAG_QUERY_REQUIRED, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("FILTER_FLAG_IPV4", FILTER_FLAG_IPV4, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_IPV6", FILTER_FLAG_IPV6, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_RES_RANGE", FILTER_FLAG_NO_RES_RANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_PRIV_RANGE", FILTER_FLAG_NO_PRIV_RANGE, CONST_CS | CONST_PERSISTENT); + + sapi_register_input_filter(php_sapi_filter, php_sapi_filter_init TSRMLS_CC); + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(filter) +{ + UNREGISTER_INI_ENTRIES(); + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_RSHUTDOWN_FUNCTION + */ +#define VAR_ARRAY_COPY_DTOR(a) \ + if (IF_G(a)) { \ + zval_ptr_dtor(&IF_G(a)); \ + IF_G(a) = NULL; \ + } + +PHP_RSHUTDOWN_FUNCTION(filter) +{ + VAR_ARRAY_COPY_DTOR(get_array) + VAR_ARRAY_COPY_DTOR(post_array) + VAR_ARRAY_COPY_DTOR(cookie_array) + VAR_ARRAY_COPY_DTOR(server_array) + VAR_ARRAY_COPY_DTOR(env_array) + VAR_ARRAY_COPY_DTOR(session_array) + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(filter) +{ + php_info_print_table_start(); + php_info_print_table_row( 2, "Input Validation and Filtering", "enabled" ); + php_info_print_table_row( 2, "Revision", "$Id: 2aa8dd57d9c0c655cd45e6e5872bb95fa5ad76cf $"); + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} +/* }}} */ + +static filter_list_entry php_find_filter(long id) /* {{{ */ +{ + int i, size = sizeof(filter_list) / sizeof(filter_list_entry); + + for (i = 0; i < size; ++i) { + if (filter_list[i].id == id) { + return filter_list[i]; + } + } + /* Fallback to "string" filter */ + for (i = 0; i < size; ++i) { + if (filter_list[i].id == FILTER_DEFAULT) { + return filter_list[i]; + } + } + /* To shut up GCC */ + return filter_list[0]; +} +/* }}} */ + +static unsigned int php_sapi_filter_init(TSRMLS_D) +{ + IF_G(get_array) = NULL; + IF_G(post_array) = NULL; + IF_G(cookie_array) = NULL; + IF_G(server_array) = NULL; + IF_G(env_array) = NULL; + IF_G(session_array) = NULL; + return SUCCESS; +} + +static void php_zval_filter(zval **value, long filter, long flags, zval *options, char* charset, zend_bool copy TSRMLS_DC) /* {{{ */ +{ + filter_list_entry filter_func; + + filter_func = php_find_filter(filter); + + if (!filter_func.id) { + /* Find default filter */ + filter_func = php_find_filter(FILTER_DEFAULT); + } + + if (copy) { + SEPARATE_ZVAL(value); + } + + /* #49274, fatal error with object without a toString method + Fails nicely instead of getting a recovarable fatal error. */ + if (Z_TYPE_PP(value) == IS_OBJECT) { + zend_class_entry *ce; + + ce = Z_OBJCE_PP(value); + if (!ce->__tostring) { + ZVAL_FALSE(*value); + return; + } + } + + /* Here be strings */ + convert_to_string(*value); + + filter_func.function(*value, flags, options, charset TSRMLS_CC); + + if ( + options && (Z_TYPE_P(options) == IS_ARRAY || Z_TYPE_P(options) == IS_OBJECT) && + ((flags & FILTER_NULL_ON_FAILURE && Z_TYPE_PP(value) == IS_NULL) || + (!(flags & FILTER_NULL_ON_FAILURE) && Z_TYPE_PP(value) == IS_BOOL && Z_LVAL_PP(value) == 0)) && + zend_hash_exists(HASH_OF(options), "default", sizeof("default")) + ) { + zval **tmp; + if (zend_hash_find(HASH_OF(options), "default", sizeof("default"), (void **)&tmp) == SUCCESS) { + MAKE_COPY_ZVAL(tmp, *value); + } + } +} +/* }}} */ + +static unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC) /* {{{ */ +{ + zval new_var, raw_var; + zval *array_ptr = NULL, *orig_array_ptr = NULL; + int retval = 0; + + assert(*val != NULL); + +#define PARSE_CASE(s,a,t) \ + case s: \ + if (!IF_G(a)) { \ + ALLOC_ZVAL(array_ptr); \ + array_init(array_ptr); \ + INIT_PZVAL(array_ptr); \ + IF_G(a) = array_ptr; \ + } else { \ + array_ptr = IF_G(a); \ + } \ + orig_array_ptr = PG(http_globals)[t]; \ + break; + + switch (arg) { + PARSE_CASE(PARSE_POST, post_array, TRACK_VARS_POST) + PARSE_CASE(PARSE_GET, get_array, TRACK_VARS_GET) + PARSE_CASE(PARSE_COOKIE, cookie_array, TRACK_VARS_COOKIE) + PARSE_CASE(PARSE_SERVER, server_array, TRACK_VARS_SERVER) + PARSE_CASE(PARSE_ENV, env_array, TRACK_VARS_ENV) + + case PARSE_STRING: /* PARSE_STRING is used by parse_str() function */ + retval = 1; + break; + } + + /* + * According to rfc2965, more specific paths are listed above the less specific ones. + * If we encounter a duplicate cookie name, we should skip it, since it is not possible + * to have the same (plain text) cookie name for the same path and we should not overwrite + * more specific cookies with the less specific ones. + */ + if (arg == PARSE_COOKIE && orig_array_ptr && zend_symtable_exists(Z_ARRVAL_P(orig_array_ptr), var, strlen(var)+1)) { + return 0; + } + + if (array_ptr) { + /* Store the RAW variable internally */ + Z_STRLEN(raw_var) = val_len; + Z_STRVAL(raw_var) = estrndup(*val, val_len); + Z_TYPE(raw_var) = IS_STRING; + + php_register_variable_ex(var, &raw_var, array_ptr TSRMLS_CC); + } + + if (val_len) { + /* Register mangled variable */ + Z_STRLEN(new_var) = val_len; + Z_TYPE(new_var) = IS_STRING; + + if (IF_G(default_filter) != FILTER_UNSAFE_RAW) { + zval *tmp_new_var = &new_var; + Z_STRVAL(new_var) = estrndup(*val, val_len); + INIT_PZVAL(tmp_new_var); + php_zval_filter(&tmp_new_var, IF_G(default_filter), IF_G(default_filter_flags), NULL, NULL/*charset*/, 0 TSRMLS_CC); + } else { + Z_STRVAL(new_var) = estrndup(*val, val_len); + } + } else { /* empty string */ + ZVAL_EMPTY_STRING(&new_var); + } + + if (orig_array_ptr) { + php_register_variable_ex(var, &new_var, orig_array_ptr TSRMLS_CC); + } + + if (retval) { + if (new_val_len) { + *new_val_len = Z_STRLEN(new_var); + } + efree(*val); + if (Z_STRLEN(new_var)) { + *val = estrndup(Z_STRVAL(new_var), Z_STRLEN(new_var)); + } else { + *val = estrdup(""); + } + zval_dtor(&new_var); + } + + return retval; +} +/* }}} */ + +static void php_zval_filter_recursive(zval **value, long filter, long flags, zval *options, char *charset, zend_bool copy TSRMLS_DC) /* {{{ */ +{ + if (Z_TYPE_PP(value) == IS_ARRAY) { + zval **element; + HashPosition pos; + + if (Z_ARRVAL_PP(value)->nApplyCount > 1) { + return; + } + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(value), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(value), (void **) &element, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(value), &pos) + ) { + SEPARATE_ZVAL_IF_NOT_REF(element); + if (Z_TYPE_PP(element) == IS_ARRAY) { + Z_ARRVAL_PP(element)->nApplyCount++; + php_zval_filter_recursive(element, filter, flags, options, charset, copy TSRMLS_CC); + Z_ARRVAL_PP(element)->nApplyCount--; + } else { + php_zval_filter(element, filter, flags, options, charset, copy TSRMLS_CC); + } + } + } else { + php_zval_filter(value, filter, flags, options, charset, copy TSRMLS_CC); + } +} +/* }}} */ + +static zval *php_filter_get_storage(long arg TSRMLS_DC)/* {{{ */ + +{ + zval *array_ptr = NULL; + + switch (arg) { + case PARSE_GET: + array_ptr = IF_G(get_array); + break; + case PARSE_POST: + array_ptr = IF_G(post_array); + break; + case PARSE_COOKIE: + array_ptr = IF_G(cookie_array); + break; + case PARSE_SERVER: + if (PG(auto_globals_jit)) { + zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); + } + array_ptr = IF_G(server_array); + break; + case PARSE_ENV: + if (PG(auto_globals_jit)) { + zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC); + } + array_ptr = IF_G(env_array) ? IF_G(env_array) : PG(http_globals)[TRACK_VARS_ENV]; + break; + case PARSE_SESSION: + /* FIXME: Implement session source */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "INPUT_SESSION is not yet implemented"); + break; + case PARSE_REQUEST: + /* FIXME: Implement request source */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "INPUT_REQUEST is not yet implemented"); + break; + } + + return array_ptr; +} +/* }}} */ + +/* {{{ proto mixed filter_has_var(constant type, string variable_name) + * Returns true if the variable with the name 'name' exists in source. + */ +PHP_FUNCTION(filter_has_var) +{ + long arg; + char *var; + int var_len; + zval *array_ptr = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) { + RETURN_FALSE; + } + + array_ptr = php_filter_get_storage(arg TSRMLS_CC); + + if (array_ptr && HASH_OF(array_ptr) && zend_hash_exists(HASH_OF(array_ptr), var, var_len + 1)) { + RETURN_TRUE; + } + + RETURN_FALSE; +} +/* }}} */ + +static void php_filter_call(zval **filtered, long filter, zval **filter_args, const int copy, long filter_flags TSRMLS_DC) /* {{{ */ +{ + zval *options = NULL; + zval **option; + char *charset = NULL; + + if (filter_args && Z_TYPE_PP(filter_args) != IS_ARRAY) { + long lval; + + PHP_FILTER_GET_LONG_OPT(filter_args, lval); + + if (filter != -1) { /* handler for array apply */ + /* filter_args is the filter_flags */ + filter_flags = lval; + + if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) { + filter_flags |= FILTER_REQUIRE_SCALAR; + } + } else { + filter = lval; + } + } else if (filter_args) { + if (zend_hash_find(HASH_OF(*filter_args), "filter", sizeof("filter"), (void **)&option) == SUCCESS) { + PHP_FILTER_GET_LONG_OPT(option, filter); + } + + if (zend_hash_find(HASH_OF(*filter_args), "flags", sizeof("flags"), (void **)&option) == SUCCESS) { + PHP_FILTER_GET_LONG_OPT(option, filter_flags); + + if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) { + filter_flags |= FILTER_REQUIRE_SCALAR; + } + } + + if (zend_hash_find(HASH_OF(*filter_args), "options", sizeof("options"), (void **)&option) == SUCCESS) { + if (filter != FILTER_CALLBACK) { + if (Z_TYPE_PP(option) == IS_ARRAY) { + options = *option; + } + } else { + options = *option; + filter_flags = 0; + } + } + } + + if (Z_TYPE_PP(filtered) == IS_ARRAY) { + if (filter_flags & FILTER_REQUIRE_SCALAR) { + if (copy) { + SEPARATE_ZVAL(filtered); + } + zval_dtor(*filtered); + if (filter_flags & FILTER_NULL_ON_FAILURE) { + ZVAL_NULL(*filtered); + } else { + ZVAL_FALSE(*filtered); + } + return; + } + php_zval_filter_recursive(filtered, filter, filter_flags, options, charset, copy TSRMLS_CC); + return; + } + if (filter_flags & FILTER_REQUIRE_ARRAY) { + if (copy) { + SEPARATE_ZVAL(filtered); + } + zval_dtor(*filtered); + if (filter_flags & FILTER_NULL_ON_FAILURE) { + ZVAL_NULL(*filtered); + } else { + ZVAL_FALSE(*filtered); + } + return; + } + + php_zval_filter(filtered, filter, filter_flags, options, charset, copy TSRMLS_CC); + if (filter_flags & FILTER_FORCE_ARRAY) { + zval *tmp; + + ALLOC_ZVAL(tmp); + MAKE_COPY_ZVAL(filtered, tmp); + + zval_dtor(*filtered); + + array_init(*filtered); + add_next_index_zval(*filtered, tmp); + } +} +/* }}} */ + +static void php_filter_array_handler(zval *input, zval **op, zval *return_value, zend_bool add_empty TSRMLS_DC) /* {{{ */ +{ + char *arg_key; + uint arg_key_len; + ulong index; + HashPosition pos; + zval **tmp, **arg_elm; + + if (!op) { + zval_dtor(return_value); + MAKE_COPY_ZVAL(&input, return_value); + php_filter_call(&return_value, FILTER_DEFAULT, NULL, 0, FILTER_REQUIRE_ARRAY TSRMLS_CC); + } else if (Z_TYPE_PP(op) == IS_LONG) { + zval_dtor(return_value); + MAKE_COPY_ZVAL(&input, return_value); + php_filter_call(&return_value, Z_LVAL_PP(op), NULL, 0, FILTER_REQUIRE_ARRAY TSRMLS_CC); + } else if (Z_TYPE_PP(op) == IS_ARRAY) { + array_init(return_value); + + zend_hash_internal_pointer_reset(Z_ARRVAL_PP(op)); + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(op), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(op), (void **) &arg_elm, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(op), &pos)) + { + if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(op), &arg_key, &arg_key_len, &index, 0, &pos) != HASH_KEY_IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric keys are not allowed in the definition array"); + zval_dtor(return_value); + RETURN_FALSE; + } + if (arg_key_len < 2) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty keys are not allowed in the definition array"); + zval_dtor(return_value); + RETURN_FALSE; + } + if (zend_hash_find(Z_ARRVAL_P(input), arg_key, arg_key_len, (void **)&tmp) != SUCCESS) { + if (add_empty) { + add_assoc_null_ex(return_value, arg_key, arg_key_len); + } + } else { + zval *nval; + + ALLOC_ZVAL(nval); + MAKE_COPY_ZVAL(tmp, nval); + + php_filter_call(&nval, -1, arg_elm, 0, FILTER_REQUIRE_SCALAR TSRMLS_CC); + add_assoc_zval_ex(return_value, arg_key, arg_key_len, nval); + } + } + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto mixed filter_input(constant type, string variable_name [, long filter [, mixed options]]) + * Returns the filtered variable 'name'* from source `type`. + */ +PHP_FUNCTION(filter_input) +{ + long fetch_from, filter = FILTER_DEFAULT; + zval **filter_args = NULL, **tmp; + zval *input = NULL; + char *var; + int var_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|lZ", &fetch_from, &var, &var_len, &filter, &filter_args) == FAILURE) { + return; + } + + if (!PHP_FILTER_ID_EXISTS(filter)) { + RETURN_FALSE; + } + + input = php_filter_get_storage(fetch_from TSRMLS_CC); + + if (!input || !HASH_OF(input) || zend_hash_find(HASH_OF(input), var, var_len + 1, (void **)&tmp) != SUCCESS) { + long filter_flags = 0; + zval **option, **opt, **def; + if (filter_args) { + if (Z_TYPE_PP(filter_args) == IS_LONG) { + filter_flags = Z_LVAL_PP(filter_args); + } else if (Z_TYPE_PP(filter_args) == IS_ARRAY && zend_hash_find(HASH_OF(*filter_args), "flags", sizeof("flags"), (void **)&option) == SUCCESS) { + PHP_FILTER_GET_LONG_OPT(option, filter_flags); + } + if (Z_TYPE_PP(filter_args) == IS_ARRAY && + zend_hash_find(HASH_OF(*filter_args), "options", sizeof("options"), (void **)&opt) == SUCCESS && + Z_TYPE_PP(opt) == IS_ARRAY && + zend_hash_find(HASH_OF(*opt), "default", sizeof("default"), (void **)&def) == SUCCESS + ) { + MAKE_COPY_ZVAL(def, return_value); + return; + } + } + + /* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of + * the function: normally when validation fails false is returned, and + * when the input value doesn't exist NULL is returned. With the flag + * set, NULL and false should be returned, respectively. Ergo, although + * the code below looks incorrect, it's actually right. */ + if (filter_flags & FILTER_NULL_ON_FAILURE) { + RETURN_FALSE; + } else { + RETURN_NULL(); + } + } + + MAKE_COPY_ZVAL(tmp, return_value); + + php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto mixed filter_var(mixed variable [, long filter [, mixed options]]) + * Returns the filtered version of the vriable. + */ +PHP_FUNCTION(filter_var) +{ + long filter = FILTER_DEFAULT; + zval **filter_args = NULL, *data; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/|lZ", &data, &filter, &filter_args) == FAILURE) { + return; + } + + if (!PHP_FILTER_ID_EXISTS(filter)) { + RETURN_FALSE; + } + + MAKE_COPY_ZVAL(&data, return_value); + + php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto mixed filter_input_array(constant type, [, mixed options [, bool add_empty]]]) + * Returns an array with all arguments defined in 'definition'. + */ +PHP_FUNCTION(filter_input_array) +{ + long fetch_from; + zval *array_input = NULL, **op = NULL; + zend_bool add_empty = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|Zb", &fetch_from, &op, &add_empty) == FAILURE) { + return; + } + + if (op + && (Z_TYPE_PP(op) != IS_ARRAY) + && (Z_TYPE_PP(op) == IS_LONG && !PHP_FILTER_ID_EXISTS(Z_LVAL_PP(op))) + ) { + RETURN_FALSE; + } + + array_input = php_filter_get_storage(fetch_from TSRMLS_CC); + + if (!array_input || !HASH_OF(array_input)) { + long filter_flags = 0; + zval **option; + if (op) { + if (Z_TYPE_PP(op) == IS_LONG) { + filter_flags = Z_LVAL_PP(op); + } else if (Z_TYPE_PP(op) == IS_ARRAY && zend_hash_find(HASH_OF(*op), "flags", sizeof("flags"), (void **)&option) == SUCCESS) { + PHP_FILTER_GET_LONG_OPT(option, filter_flags); + } + } + + /* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of + * the function: normally when validation fails false is returned, and + * when the input value doesn't exist NULL is returned. With the flag + * set, NULL and false should be returned, respectively. Ergo, although + * the code below looks incorrect, it's actually right. */ + if (filter_flags & FILTER_NULL_ON_FAILURE) { + RETURN_FALSE; + } else { + RETURN_NULL(); + } + } + + php_filter_array_handler(array_input, op, return_value, add_empty TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto mixed filter_var_array(array data, [, mixed options [, bool add_empty]]]) + * Returns an array with all arguments defined in 'definition'. + */ +PHP_FUNCTION(filter_var_array) +{ + zval *array_input = NULL, **op = NULL; + zend_bool add_empty = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|Zb", &array_input, &op, &add_empty) == FAILURE) { + return; + } + + if (op + && (Z_TYPE_PP(op) != IS_ARRAY) + && (Z_TYPE_PP(op) == IS_LONG && !PHP_FILTER_ID_EXISTS(Z_LVAL_PP(op))) + ) { + RETURN_FALSE; + } + + php_filter_array_handler(array_input, op, return_value, add_empty TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto filter_list() + * Returns a list of all supported filters */ +PHP_FUNCTION(filter_list) +{ + int i, size = sizeof(filter_list) / sizeof(filter_list_entry); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + array_init(return_value); + for (i = 0; i < size; ++i) { + add_next_index_string(return_value, (char *)filter_list[i].name, 1); + } +} +/* }}} */ + +/* {{{ proto filter_id(string filtername) + * Returns the filter ID belonging to a named filter */ +PHP_FUNCTION(filter_id) +{ + int i, filter_len; + int size = sizeof(filter_list) / sizeof(filter_list_entry); + char *filter; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filter, &filter_len) == FAILURE) { + return; + } + + for (i = 0; i < size; ++i) { + if (strcmp(filter_list[i].name, filter) == 0) { + RETURN_LONG(filter_list[i].id); + } + } + + RETURN_FALSE; +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/filter/filter_private.h b/ext/filter/filter_private.h new file mode 100644 index 0000000..9bc53a0 --- /dev/null +++ b/ext/filter/filter_private.h @@ -0,0 +1,139 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans <derick@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef FILTER_PRIVATE_H +#define FILTER_PRIVATE_H + +#define FILTER_FLAG_NONE 0x0000 + +#define FILTER_REQUIRE_ARRAY 0x1000000 +#define FILTER_REQUIRE_SCALAR 0x2000000 + +#define FILTER_FORCE_ARRAY 0x4000000 +#define FILTER_NULL_ON_FAILURE 0x8000000 + +#define FILTER_FLAG_ALLOW_OCTAL 0x0001 +#define FILTER_FLAG_ALLOW_HEX 0x0002 + +#define FILTER_FLAG_STRIP_LOW 0x0004 +#define FILTER_FLAG_STRIP_HIGH 0x0008 +#define FILTER_FLAG_ENCODE_LOW 0x0010 +#define FILTER_FLAG_ENCODE_HIGH 0x0020 +#define FILTER_FLAG_ENCODE_AMP 0x0040 +#define FILTER_FLAG_NO_ENCODE_QUOTES 0x0080 +#define FILTER_FLAG_EMPTY_STRING_NULL 0x0100 +#define FILTER_FLAG_STRIP_BACKTICK 0x0200 + +#define FILTER_FLAG_ALLOW_FRACTION 0x1000 +#define FILTER_FLAG_ALLOW_THOUSAND 0x2000 +#define FILTER_FLAG_ALLOW_SCIENTIFIC 0x4000 + +#define FILTER_FLAG_SCHEME_REQUIRED 0x010000 +#define FILTER_FLAG_HOST_REQUIRED 0x020000 +#define FILTER_FLAG_PATH_REQUIRED 0x040000 +#define FILTER_FLAG_QUERY_REQUIRED 0x080000 + +#define FILTER_FLAG_IPV4 0x100000 +#define FILTER_FLAG_IPV6 0x200000 +#define FILTER_FLAG_NO_RES_RANGE 0x400000 +#define FILTER_FLAG_NO_PRIV_RANGE 0x800000 + +#define FILTER_VALIDATE_INT 0x0101 +#define FILTER_VALIDATE_BOOLEAN 0x0102 +#define FILTER_VALIDATE_FLOAT 0x0103 + +#define FILTER_VALIDATE_REGEXP 0x0110 +#define FILTER_VALIDATE_URL 0x0111 +#define FILTER_VALIDATE_EMAIL 0x0112 +#define FILTER_VALIDATE_IP 0x0113 +#define FILTER_VALIDATE_LAST 0x0113 + +#define FILTER_VALIDATE_ALL 0x0100 + +#define FILTER_DEFAULT 0x0204 +#define FILTER_UNSAFE_RAW 0x0204 + +#define FILTER_SANITIZE_STRING 0x0201 +#define FILTER_SANITIZE_ENCODED 0x0202 +#define FILTER_SANITIZE_SPECIAL_CHARS 0x0203 +#define FILTER_SANITIZE_EMAIL 0x0205 +#define FILTER_SANITIZE_URL 0x0206 +#define FILTER_SANITIZE_NUMBER_INT 0x0207 +#define FILTER_SANITIZE_NUMBER_FLOAT 0x0208 +#define FILTER_SANITIZE_MAGIC_QUOTES 0x0209 +#define FILTER_SANITIZE_FULL_SPECIAL_CHARS 0x020a +#define FILTER_SANITIZE_LAST 0x020a + +#define FILTER_SANITIZE_ALL 0x0200 + +#define FILTER_CALLBACK 0x0400 + +#define PHP_FILTER_ID_EXISTS(id) \ +((id >= FILTER_SANITIZE_ALL && id <= FILTER_SANITIZE_LAST) \ +|| (id >= FILTER_VALIDATE_ALL && id <= FILTER_VALIDATE_LAST) \ +|| id == FILTER_CALLBACK) + +#define RETURN_VALIDATION_FAILED \ + zval_dtor(value); \ + if (flags & FILTER_NULL_ON_FAILURE) { \ + ZVAL_NULL(value); \ + } else { \ + ZVAL_FALSE(value); \ + } \ + return; \ + +#define PHP_FILTER_TRIM_DEFAULT(p, len) PHP_FILTER_TRIM_DEFAULT_EX(p, len, 1); + +#define PHP_FILTER_TRIM_DEFAULT_EX(p, len, return_if_empty) { \ + while ((len > 0) && (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\v' || *p == '\n')) { \ + p++; \ + len--; \ + } \ + if (len < 1 && return_if_empty) { \ + RETURN_VALIDATION_FAILED \ + } \ + if (len > 0) { \ + while (p[len-1] == ' ' || p[len-1] == '\t' || p[len-1] == '\r' || p[len-1] == '\v' || p[len-1] == '\n') { \ + len--; \ + } \ + } \ +} + +#define PHP_FILTER_GET_LONG_OPT(zv, opt) { \ + if (Z_TYPE_PP(zv) != IS_LONG) { \ + zval ___tmp = **zv; \ + zval_copy_ctor(&___tmp); \ + convert_to_long(&___tmp); \ + opt = Z_LVAL(___tmp); \ + } else { \ + opt = Z_LVAL_PP(zv); \ + } \ +} + +#endif /* FILTER_PRIVATE_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c new file mode 100644 index 0000000..58d5870 --- /dev/null +++ b/ext/filter/logical_filters.c @@ -0,0 +1,794 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans <derick@php.net> | + | Pierre-A. Joye <pierre@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include "php_filter.h" +#include "filter_private.h" +#include "ext/standard/url.h" +#include "ext/pcre/php_pcre.h" + +#include "zend_multiply.h" + +#if HAVE_ARPA_INET_H +# include <arpa/inet.h> +#endif + +#ifndef INADDR_NONE +# define INADDR_NONE ((unsigned long int) -1) +#endif + + +/* {{{ FETCH_LONG_OPTION(var_name, option_name) */ +#define FETCH_LONG_OPTION(var_name, option_name) \ + var_name = 0; \ + var_name##_set = 0; \ + if (option_array) { \ + if (zend_hash_find(HASH_OF(option_array), option_name, sizeof(option_name), (void **) &option_val) == SUCCESS) { \ + PHP_FILTER_GET_LONG_OPT(option_val, var_name); \ + var_name##_set = 1; \ + } \ + } +/* }}} */ + +/* {{{ FETCH_STRING_OPTION(var_name, option_name) */ +#define FETCH_STRING_OPTION(var_name, option_name) \ + var_name = NULL; \ + var_name##_set = 0; \ + var_name##_len = 0; \ + if (option_array) { \ + if (zend_hash_find(HASH_OF(option_array), option_name, sizeof(option_name), (void **) &option_val) == SUCCESS) { \ + if (Z_TYPE_PP(option_val) == IS_STRING) { \ + var_name = Z_STRVAL_PP(option_val); \ + var_name##_len = Z_STRLEN_PP(option_val); \ + var_name##_set = 1; \ + } \ + } \ + } +/* }}} */ + +#define FORMAT_IPV4 4 +#define FORMAT_IPV6 6 + +static int php_filter_parse_int(const char *str, unsigned int str_len, long *ret TSRMLS_DC) { /* {{{ */ + long ctx_value; + int sign = 0, digit = 0; + const char *end = str + str_len; + + switch (*str) { + case '-': + sign = 1; + case '+': + str++; + default: + break; + } + + if (*str == '0' && str + 1 == end) { + /* Special cases: +0 and -0 */ + return 1; + } + + /* must start with 1..9*/ + if (str < end && *str >= '1' && *str <= '9') { + ctx_value = ((sign)?-1:1) * ((*(str++)) - '0'); + } else { + return -1; + } + + if ((end - str > MAX_LENGTH_OF_LONG - 1) /* number too long */ + || (SIZEOF_LONG == 4 && (end - str == MAX_LENGTH_OF_LONG - 1) && *str > '2')) { + /* overflow */ + return -1; + } + + while (str < end) { + if (*str >= '0' && *str <= '9') { + digit = (*(str++) - '0'); + if ( (!sign) && ctx_value <= (LONG_MAX-digit)/10 ) { + ctx_value = (ctx_value * 10) + digit; + } else if ( sign && ctx_value >= (LONG_MIN+digit)/10) { + ctx_value = (ctx_value * 10) - digit; + } else { + return -1; + } + } else { + return -1; + } + } + + *ret = ctx_value; + return 1; +} +/* }}} */ + +static int php_filter_parse_octal(const char *str, unsigned int str_len, long *ret TSRMLS_DC) { /* {{{ */ + unsigned long ctx_value = 0; + const char *end = str + str_len; + + while (str < end) { + if (*str >= '0' && *str <= '7') { + unsigned long n = ((*(str++)) - '0'); + + if ((ctx_value > ((unsigned long)(~(long)0)) / 8) || + ((ctx_value = ctx_value * 8) > ((unsigned long)(~(long)0)) - n)) { + return -1; + } + ctx_value += n; + } else { + return -1; + } + } + + *ret = (long)ctx_value; + return 1; +} +/* }}} */ + +static int php_filter_parse_hex(const char *str, unsigned int str_len, long *ret TSRMLS_DC) { /* {{{ */ + unsigned long ctx_value = 0; + const char *end = str + str_len; + unsigned long n; + + while (str < end) { + if (*str >= '0' && *str <= '9') { + n = ((*(str++)) - '0'); + } else if (*str >= 'a' && *str <= 'f') { + n = ((*(str++)) - ('a' - 10)); + } else if (*str >= 'A' && *str <= 'F') { + n = ((*(str++)) - ('A' - 10)); + } else { + return -1; + } + if ((ctx_value > ((unsigned long)(~(long)0)) / 16) || + ((ctx_value = ctx_value * 16) > ((unsigned long)(~(long)0)) - n)) { + return -1; + } + ctx_value += n; + } + + *ret = (long)ctx_value; + return 1; +} +/* }}} */ + +void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + zval **option_val; + long min_range, max_range, option_flags; + int min_range_set, max_range_set; + int allow_octal = 0, allow_hex = 0; + int len, error = 0; + long ctx_value; + char *p; + + /* Parse options */ + FETCH_LONG_OPTION(min_range, "min_range"); + FETCH_LONG_OPTION(max_range, "max_range"); + option_flags = flags; + + len = Z_STRLEN_P(value); + + if (len == 0) { + RETURN_VALIDATION_FAILED + } + + if (option_flags & FILTER_FLAG_ALLOW_OCTAL) { + allow_octal = 1; + } + + if (option_flags & FILTER_FLAG_ALLOW_HEX) { + allow_hex = 1; + } + + /* Start the validating loop */ + p = Z_STRVAL_P(value); + ctx_value = 0; + + PHP_FILTER_TRIM_DEFAULT(p, len); + + if (*p == '0') { + p++; len--; + if (allow_hex && (*p == 'x' || *p == 'X')) { + p++; len--; + if (php_filter_parse_hex(p, len, &ctx_value TSRMLS_CC) < 0) { + error = 1; + } + } else if (allow_octal) { + if (php_filter_parse_octal(p, len, &ctx_value TSRMLS_CC) < 0) { + error = 1; + } + } else if (len != 0) { + error = 1; + } + } else { + if (php_filter_parse_int(p, len, &ctx_value TSRMLS_CC) < 0) { + error = 1; + } + } + + if (error > 0 || (min_range_set && (ctx_value < min_range)) || (max_range_set && (ctx_value > max_range))) { + RETURN_VALIDATION_FAILED + } else { + zval_dtor(value); + Z_TYPE_P(value) = IS_LONG; + Z_LVAL_P(value) = ctx_value; + return; + } +} +/* }}} */ + +void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + char *str = Z_STRVAL_P(value); + int len = Z_STRLEN_P(value); + int ret; + + PHP_FILTER_TRIM_DEFAULT_EX(str, len, 0); + + /* returns true for "1", "true", "on" and "yes" + * returns false for "0", "false", "off", "no", and "" + * null otherwise. */ + switch (len) { + case 0: + ret = 0; + break; + case 1: + if (*str == '1') { + ret = 1; + } else if (*str == '0') { + ret = 0; + } else { + ret = -1; + } + break; + case 2: + if (strncasecmp(str, "on", 2) == 0) { + ret = 1; + } else if (strncasecmp(str, "no", 2) == 0) { + ret = 0; + } else { + ret = -1; + } + break; + case 3: + if (strncasecmp(str, "yes", 3) == 0) { + ret = 1; + } else if (strncasecmp(str, "off", 3) == 0) { + ret = 0; + } else { + ret = -1; + } + break; + case 4: + if (strncasecmp(str, "true", 4) == 0) { + ret = 1; + } else { + ret = -1; + } + break; + case 5: + if (strncasecmp(str, "false", 5) == 0) { + ret = 0; + } else { + ret = -1; + } + break; + default: + ret = -1; + } + + if (ret == -1) { + RETURN_VALIDATION_FAILED + } else { + zval_dtor(value); + ZVAL_BOOL(value, ret); + } +} +/* }}} */ + +void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + int len; + char *str, *end; + char *num, *p; + + zval **option_val; + char *decimal; + int decimal_set, decimal_len; + char dec_sep = '.'; + char tsd_sep[3] = "',."; + + long lval; + double dval; + + int first, n; + + len = Z_STRLEN_P(value); + str = Z_STRVAL_P(value); + + PHP_FILTER_TRIM_DEFAULT(str, len); + end = str + len; + + FETCH_STRING_OPTION(decimal, "decimal"); + + if (decimal_set) { + if (decimal_len != 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "decimal separator must be one char"); + RETURN_VALIDATION_FAILED + } else { + dec_sep = *decimal; + } + } + + num = p = emalloc(len+1); + if (str < end && (*str == '+' || *str == '-')) { + *p++ = *str++; + } + first = 1; + while (1) { + n = 0; + while (str < end && *str >= '0' && *str <= '9') { + ++n; + *p++ = *str++; + } + if (str == end || *str == dec_sep || *str == 'e' || *str == 'E') { + if (!first && n != 3) { + goto error; + } + if (*str == dec_sep) { + *p++ = '.'; + str++; + while (str < end && *str >= '0' && *str <= '9') { + *p++ = *str++; + } + } + if (*str == 'e' || *str == 'E') { + *p++ = *str++; + if (str < end && (*str == '+' || *str == '-')) { + *p++ = *str++; + } + while (str < end && *str >= '0' && *str <= '9') { + *p++ = *str++; + } + } + break; + } + if ((flags & FILTER_FLAG_ALLOW_THOUSAND) && (*str == tsd_sep[0] || *str == tsd_sep[1] || *str == tsd_sep[2])) { + if (first?(n < 1 || n > 3):(n != 3)) { + goto error; + } + first = 0; + str++; + } else { + goto error; + } + } + if (str != end) { + goto error; + } + *p = 0; + + switch (is_numeric_string(num, p - num, &lval, &dval, 0)) { + case IS_LONG: + zval_dtor(value); + Z_TYPE_P(value) = IS_DOUBLE; + Z_DVAL_P(value) = lval; + break; + case IS_DOUBLE: + if ((!dval && p - num > 1 && strpbrk(num, "123456789")) || !zend_finite(dval)) { + goto error; + } + zval_dtor(value); + Z_TYPE_P(value) = IS_DOUBLE; + Z_DVAL_P(value) = dval; + break; + default: +error: + efree(num); + RETURN_VALIDATION_FAILED + } + efree(num); +} +/* }}} */ + +void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + zval **option_val; + char *regexp; + int regexp_len; + long option_flags; + int regexp_set, option_flags_set; + + pcre *re = NULL; + pcre_extra *pcre_extra = NULL; + int preg_options = 0; + + int ovector[3]; + int matches; + + /* Parse options */ + FETCH_STRING_OPTION(regexp, "regexp"); + FETCH_LONG_OPTION(option_flags, "flags"); + + if (!regexp_set) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'regexp' option missing"); + RETURN_VALIDATION_FAILED + } + + re = pcre_get_compiled_regex(regexp, &pcre_extra, &preg_options TSRMLS_CC); + if (!re) { + RETURN_VALIDATION_FAILED + } + matches = pcre_exec(re, NULL, Z_STRVAL_P(value), Z_STRLEN_P(value), 0, 0, ovector, 3); + + /* 0 means that the vector is too small to hold all the captured substring offsets */ + if (matches < 0) { + RETURN_VALIDATION_FAILED + } +} +/* }}} */ + +void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + php_url *url; + int old_len = Z_STRLEN_P(value); + + php_filter_url(value, flags, option_array, charset TSRMLS_CC); + + if (Z_TYPE_P(value) != IS_STRING || old_len != Z_STRLEN_P(value)) { + RETURN_VALIDATION_FAILED + } + + /* Use parse_url - if it returns false, we return NULL */ + url = php_url_parse_ex(Z_STRVAL_P(value), Z_STRLEN_P(value)); + + if (url == NULL) { + RETURN_VALIDATION_FAILED + } + + if (url->scheme != NULL && (!strcasecmp(url->scheme, "http") || !strcasecmp(url->scheme, "https"))) { + char *e, *s; + + if (url->host == NULL) { + goto bad_url; + } + + e = url->host + strlen(url->host); + s = url->host; + + /* First char of hostname must be alphanumeric */ + if(!isalnum((int)*(unsigned char *)s)) { + goto bad_url; + } + + while (s < e) { + if (!isalnum((int)*(unsigned char *)s) && *s != '-' && *s != '.') { + goto bad_url; + } + s++; + } + + if (*(e - 1) == '.') { + goto bad_url; + } + } + + if ( + url->scheme == NULL || + /* some schemas allow the host to be empty */ + (url->host == NULL && (strcmp(url->scheme, "mailto") && strcmp(url->scheme, "news") && strcmp(url->scheme, "file"))) || + ((flags & FILTER_FLAG_PATH_REQUIRED) && url->path == NULL) || ((flags & FILTER_FLAG_QUERY_REQUIRED) && url->query == NULL) + ) { +bad_url: + php_url_free(url); + RETURN_VALIDATION_FAILED + } + php_url_free(url); +} +/* }}} */ + +void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + /* + * The regex below is based on a regex by Michael Rushton. + * However, it is not identical. I changed it to only consider routeable + * addresses as valid. Michael's regex considers a@b a valid address + * which conflicts with section 2.3.5 of RFC 5321 which states that: + * + * Only resolvable, fully-qualified domain names (FQDNs) are permitted + * when domain names are used in SMTP. In other words, names that can + * be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed + * in Section 5) are permitted, as are CNAME RRs whose targets can be + * resolved, in turn, to MX or address RRs. Local nicknames or + * unqualified names MUST NOT be used. + * + * This regex does not handle comments and folding whitespace. While + * this is technically valid in an email address, these parts aren't + * actually part of the address itself. + * + * Michael's regex carries this copyright: + * + * Copyright ยฉ Michael Rushton 2009-10 + * http://squiloople.com/ + * Feel free to use and redistribute this code. But please keep this copyright notice. + * + */ + const char regexp[] = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD"; + + pcre *re = NULL; + pcre_extra *pcre_extra = NULL; + int preg_options = 0; + int ovector[150]; /* Needs to be a multiple of 3 */ + int matches; + + + /* The maximum length of an e-mail address is 320 octets, per RFC 2821. */ + if (Z_STRLEN_P(value) > 320) { + RETURN_VALIDATION_FAILED + } + + re = pcre_get_compiled_regex((char *)regexp, &pcre_extra, &preg_options TSRMLS_CC); + if (!re) { + RETURN_VALIDATION_FAILED + } + matches = pcre_exec(re, NULL, Z_STRVAL_P(value), Z_STRLEN_P(value), 0, 0, ovector, 3); + + /* 0 means that the vector is too small to hold all the captured substring offsets */ + if (matches < 0) { + RETURN_VALIDATION_FAILED + } + +} +/* }}} */ + +static int _php_filter_validate_ipv4(char *str, int str_len, int *ip) /* {{{ */ +{ + const char *end = str + str_len; + int num, m; + int n = 0; + + while (str < end) { + int leading_zero; + if (*str < '0' || *str > '9') { + return 0; + } + leading_zero = (*str == '0'); + m = 1; + num = ((*(str++)) - '0'); + while (str < end && (*str >= '0' && *str <= '9')) { + num = num * 10 + ((*(str++)) - '0'); + if (num > 255 || ++m > 3) { + return 0; + } + } + /* don't allow a leading 0; that introduces octal numbers, + * which we don't support */ + if (leading_zero && (num != 0 || m > 1)) + return 0; + ip[n++] = num; + if (n == 4) { + return str == end; + } else if (str >= end || *(str++) != '.') { + return 0; + } + } + return 0; +} +/* }}} */ + +static int _php_filter_validate_ipv6(char *str, int str_len TSRMLS_DC) /* {{{ */ +{ + int compressed = 0; + int blocks = 0; + int n; + char *ipv4; + char *end; + int ip4elm[4]; + char *s = str; + + if (!memchr(str, ':', str_len)) { + return 0; + } + + /* check for bundled IPv4 */ + ipv4 = memchr(str, '.', str_len); + if (ipv4) { + while (ipv4 > str && *(ipv4-1) != ':') { + ipv4--; + } + + if (!_php_filter_validate_ipv4(ipv4, (str_len - (ipv4 - str)), ip4elm)) { + return 0; + } + + str_len = ipv4 - str; /* length excluding ipv4 */ + if (str_len < 2) { + return 0; + } + + if (ipv4[-2] != ':') { + /* don't include : before ipv4 unless it's a :: */ + str_len--; + } + + blocks = 2; + } + + end = str + str_len; + + while (str < end) { + if (*str == ':') { + if (++str >= end) { + /* cannot end in : without previous : */ + return 0; + } + if (*str == ':') { + if (compressed) { + return 0; + } + blocks++; /* :: means 1 or more 16-bit 0 blocks */ + compressed = 1; + + if (++str == end) { + return (blocks <= 8); + } + } else if ((str - 1) == s) { + /* dont allow leading : without another : following */ + return 0; + } + } + n = 0; + while ((str < end) && + ((*str >= '0' && *str <= '9') || + (*str >= 'a' && *str <= 'f') || + (*str >= 'A' && *str <= 'F'))) { + n++; + str++; + } + if (n < 1 || n > 4) { + return 0; + } + if (++blocks > 8) + return 0; + } + return ((compressed && blocks <= 8) || blocks == 8); +} +/* }}} */ + +void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + /* validates an ipv4 or ipv6 IP, based on the flag (4, 6, or both) add a + * flag to throw out reserved ranges; multicast ranges... etc. If both + * allow_ipv4 and allow_ipv6 flags flag are used, then the first dot or + * colon determine the format */ + + int ip[4]; + int mode; + + if (memchr(Z_STRVAL_P(value), ':', Z_STRLEN_P(value))) { + mode = FORMAT_IPV6; + } else if (memchr(Z_STRVAL_P(value), '.', Z_STRLEN_P(value))) { + mode = FORMAT_IPV4; + } else { + RETURN_VALIDATION_FAILED + } + + if ((flags & FILTER_FLAG_IPV4) && (flags & FILTER_FLAG_IPV6)) { + /* Both formats are cool */ + } else if ((flags & FILTER_FLAG_IPV4) && mode == FORMAT_IPV6) { + RETURN_VALIDATION_FAILED + } else if ((flags & FILTER_FLAG_IPV6) && mode == FORMAT_IPV4) { + RETURN_VALIDATION_FAILED + } + + switch (mode) { + case FORMAT_IPV4: + if (!_php_filter_validate_ipv4(Z_STRVAL_P(value), Z_STRLEN_P(value), ip)) { + RETURN_VALIDATION_FAILED + } + + /* Check flags */ + if (flags & FILTER_FLAG_NO_PRIV_RANGE) { + if ( + (ip[0] == 10) || + (ip[0] == 172 && (ip[1] >= 16 && ip[1] <= 31)) || + (ip[0] == 192 && ip[1] == 168) + ) { + RETURN_VALIDATION_FAILED + } + } + + if (flags & FILTER_FLAG_NO_RES_RANGE) { + if ( + (ip[0] == 0) || + (ip[0] == 128 && ip[1] == 0) || + (ip[0] == 191 && ip[1] == 255) || + (ip[0] == 169 && ip[1] == 254) || + (ip[0] == 192 && ip[1] == 0 && ip[2] == 2) || + (ip[0] == 127 && ip[1] == 0 && ip[2] == 0 && ip[3] == 1) || + (ip[0] >= 224 && ip[0] <= 255) + ) { + RETURN_VALIDATION_FAILED + } + } + break; + + case FORMAT_IPV6: + { + int res = 0; + res = _php_filter_validate_ipv6(Z_STRVAL_P(value), Z_STRLEN_P(value) TSRMLS_CC); + if (res < 1) { + RETURN_VALIDATION_FAILED + } + /* Check flags */ + if (flags & FILTER_FLAG_NO_PRIV_RANGE) { + if (Z_STRLEN_P(value) >=2 && (!strncasecmp("FC", Z_STRVAL_P(value), 2) || !strncasecmp("FD", Z_STRVAL_P(value), 2))) { + RETURN_VALIDATION_FAILED + } + } + if (flags & FILTER_FLAG_NO_RES_RANGE) { + switch (Z_STRLEN_P(value)) { + case 1: case 0: + break; + case 2: + if (!strcmp("::", Z_STRVAL_P(value))) { + RETURN_VALIDATION_FAILED + } + break; + case 3: + if (!strcmp("::1", Z_STRVAL_P(value)) || !strcmp("5f:", Z_STRVAL_P(value))) { + RETURN_VALIDATION_FAILED + } + break; + default: + if (Z_STRLEN_P(value) >= 5) { + if ( + !strncasecmp("fe8", Z_STRVAL_P(value), 3) || + !strncasecmp("fe9", Z_STRVAL_P(value), 3) || + !strncasecmp("fea", Z_STRVAL_P(value), 3) || + !strncasecmp("feb", Z_STRVAL_P(value), 3) + ) { + RETURN_VALIDATION_FAILED + } + } + if ( + (Z_STRLEN_P(value) >= 9 && !strncasecmp("2001:0db8", Z_STRVAL_P(value), 9)) || + (Z_STRLEN_P(value) >= 2 && !strncasecmp("5f", Z_STRVAL_P(value), 2)) || + (Z_STRLEN_P(value) >= 4 && !strncasecmp("3ff3", Z_STRVAL_P(value), 4)) || + (Z_STRLEN_P(value) >= 8 && !strncasecmp("2001:001", Z_STRVAL_P(value), 8)) + ) { + RETURN_VALIDATION_FAILED + } + } + } + } + break; + } +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/filter/php_filter.h b/ext/filter/php_filter.h new file mode 100644 index 0000000..cbe1c47 --- /dev/null +++ b/ext/filter/php_filter.h @@ -0,0 +1,103 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@php.net> | + | Derick Rethans <derick@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_FILTER_H +#define PHP_FILTER_H + +#include "SAPI.h" +#include "zend_API.h" +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" +#include "ext/standard/html.h" +#include "php_variables.h" + +extern zend_module_entry filter_module_entry; +#define phpext_filter_ptr &filter_module_entry + +#ifdef ZTS +#include "TSRM.h" +#endif + +PHP_MINIT_FUNCTION(filter); +PHP_MSHUTDOWN_FUNCTION(filter); +PHP_RINIT_FUNCTION(filter); +PHP_RSHUTDOWN_FUNCTION(filter); +PHP_MINFO_FUNCTION(filter); + +PHP_FUNCTION(filter_input); +PHP_FUNCTION(filter_var); +PHP_FUNCTION(filter_input_array); +PHP_FUNCTION(filter_var_array); +PHP_FUNCTION(filter_list); +PHP_FUNCTION(filter_has_var); +PHP_FUNCTION(filter_id); + +ZEND_BEGIN_MODULE_GLOBALS(filter) + zval *post_array; + zval *get_array; + zval *cookie_array; + zval *env_array; + zval *server_array; + zval *session_array; + long default_filter; + long default_filter_flags; +ZEND_END_MODULE_GLOBALS(filter) + +#ifdef ZTS +#define IF_G(v) TSRMG(filter_globals_id, zend_filter_globals *, v) +#else +#define IF_G(v) (filter_globals.v) +#endif + + +#define PHP_INPUT_FILTER_PARAM_DECL zval *value, long flags, zval *option_array, char *charset TSRMLS_DC +void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL); + +void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_magic_quotes(PHP_INPUT_FILTER_PARAM_DECL); + +void php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL); + +#endif /* FILTER_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + */ diff --git a/ext/filter/sanitizing_filters.c b/ext/filter/sanitizing_filters.c new file mode 100644 index 0000000..30da05a --- /dev/null +++ b/ext/filter/sanitizing_filters.c @@ -0,0 +1,389 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans <derick@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include "php_filter.h" +#include "filter_private.h" +#include "ext/standard/php_smart_str.h" + +/* {{{ STRUCTS */ +typedef unsigned long filter_map[256]; +/* }}} */ + +/* {{{ HELPER FUNCTIONS */ +static void php_filter_encode_html(zval *value, const unsigned char *chars) +{ + smart_str str = {0}; + int len = Z_STRLEN_P(value); + unsigned char *s = (unsigned char *)Z_STRVAL_P(value); + unsigned char *e = s + len; + + if (Z_STRLEN_P(value) == 0) { + return; + } + + while (s < e) { + if (chars[*s]) { + smart_str_appendl(&str, "&#", 2); + smart_str_append_unsigned(&str, (unsigned long)*s); + smart_str_appendc(&str, ';'); + } else { + /* XXX: this needs to be optimized to work with blocks of 'safe' chars */ + smart_str_appendc(&str, *s); + } + s++; + } + + smart_str_0(&str); + str_efree(Z_STRVAL_P(value)); + Z_STRVAL_P(value) = str.c; + Z_STRLEN_P(value) = str.len; +} + +static const unsigned char hexchars[] = "0123456789ABCDEF"; + +#define LOWALPHA "abcdefghijklmnopqrstuvwxyz" +#define HIALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define DIGIT "0123456789" + +#define DEFAULT_URL_ENCODE LOWALPHA HIALPHA DIGIT "-._" + +static void php_filter_encode_url(zval *value, const unsigned char* chars, const int char_len, int high, int low, int encode_nul) +{ + unsigned char *str, *p; + unsigned char tmp[256]; + unsigned char *s = (unsigned char *)chars; + unsigned char *e = s + char_len; + + memset(tmp, 1, sizeof(tmp)-1); + + while (s < e) { + tmp[*s++] = 0; + } +/* XXX: This is not needed since these chars in the allowed list never include the high/low/null value + if (encode_nul) { + tmp[0] = 1; + } + if (high) { + memset(tmp + 127, 1, sizeof(tmp) - 127); + } + if (low) { + memset(tmp, 1, 32); + } +*/ + p = str = (unsigned char *) safe_emalloc(3, Z_STRLEN_P(value), 1); + s = (unsigned char *)Z_STRVAL_P(value); + e = s + Z_STRLEN_P(value); + + while (s < e) { + if (tmp[*s]) { + *p++ = '%'; + *p++ = hexchars[(unsigned char) *s >> 4]; + *p++ = hexchars[(unsigned char) *s & 15]; + } else { + *p++ = *s; + } + s++; + } + *p = '\0'; + str_efree(Z_STRVAL_P(value)); + Z_STRVAL_P(value) = (char *)str; + Z_STRLEN_P(value) = p - str; +} + +static void php_filter_strip(zval *value, long flags) +{ + unsigned char *buf, *str; + int i, c; + + /* Optimization for if no strip flags are set */ + if (! ((flags & FILTER_FLAG_STRIP_LOW) || (flags & FILTER_FLAG_STRIP_HIGH)) ) { + return; + } + + str = (unsigned char *)Z_STRVAL_P(value); + buf = safe_emalloc(1, Z_STRLEN_P(value) + 1, 1); + c = 0; + for (i = 0; i < Z_STRLEN_P(value); i++) { + if ((str[i] > 127) && (flags & FILTER_FLAG_STRIP_HIGH)) { + } else if ((str[i] < 32) && (flags & FILTER_FLAG_STRIP_LOW)) { + } else if ((str[i] == '`') && (flags & FILTER_FLAG_STRIP_BACKTICK)) { + } else { + buf[c] = str[i]; + ++c; + } + } + /* update zval string data */ + buf[c] = '\0'; + str_efree(Z_STRVAL_P(value)); + Z_STRVAL_P(value) = (char *)buf; + Z_STRLEN_P(value) = c; +} +/* }}} */ + +/* {{{ FILTER MAP HELPERS */ +static void filter_map_init(filter_map *map) +{ + memset(map, 0, sizeof(filter_map)); +} + +static void filter_map_update(filter_map *map, int flag, const unsigned char *allowed_list) +{ + int l, i; + + l = strlen((const char*)allowed_list); + for (i = 0; i < l; ++i) { + (*map)[allowed_list[i]] = flag; + } +} + +static void filter_map_apply(zval *value, filter_map *map) +{ + unsigned char *buf, *str; + int i, c; + + str = (unsigned char *)Z_STRVAL_P(value); + buf = safe_emalloc(1, Z_STRLEN_P(value) + 1, 1); + c = 0; + for (i = 0; i < Z_STRLEN_P(value); i++) { + if ((*map)[str[i]]) { + buf[c] = str[i]; + ++c; + } + } + /* update zval string data */ + buf[c] = '\0'; + str_efree(Z_STRVAL_P(value)); + Z_STRVAL_P(value) = (char *)buf; + Z_STRLEN_P(value) = c; +} +/* }}} */ + +/* {{{ php_filter_string */ +void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL) +{ + size_t new_len; + unsigned char enc[256] = {0}; + + /* strip high/strip low ( see flags )*/ + php_filter_strip(value, flags); + + if (!(flags & FILTER_FLAG_NO_ENCODE_QUOTES)) { + enc['\''] = enc['"'] = 1; + } + if (flags & FILTER_FLAG_ENCODE_AMP) { + enc['&'] = 1; + } + if (flags & FILTER_FLAG_ENCODE_LOW) { + memset(enc, 1, 32); + } + if (flags & FILTER_FLAG_ENCODE_HIGH) { + memset(enc + 127, 1, sizeof(enc) - 127); + } + + php_filter_encode_html(value, enc); + + /* strip tags, implicitly also removes \0 chars */ + new_len = php_strip_tags_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), NULL, NULL, 0, 1); + Z_STRLEN_P(value) = new_len; + + if (new_len == 0) { + zval_dtor(value); + if (flags & FILTER_FLAG_EMPTY_STRING_NULL) { + ZVAL_NULL(value); + } else { + ZVAL_EMPTY_STRING(value); + } + return; + } +} +/* }}} */ + +/* {{{ php_filter_encoded */ +void php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL) +{ + /* apply strip_high and strip_low filters */ + php_filter_strip(value, flags); + /* urlencode */ + php_filter_encode_url(value, (unsigned char *)DEFAULT_URL_ENCODE, sizeof(DEFAULT_URL_ENCODE)-1, flags & FILTER_FLAG_ENCODE_HIGH, flags & FILTER_FLAG_ENCODE_LOW, 1); +} +/* }}} */ + +/* {{{ php_filter_special_chars */ +void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL) +{ + unsigned char enc[256] = {0}; + + php_filter_strip(value, flags); + + /* encodes ' " < > & \0 to numerical entities */ + enc['\''] = enc['"'] = enc['<'] = enc['>'] = enc['&'] = enc[0] = 1; + + /* if strip low is not set, then we encode them as &#xx; */ + memset(enc, 1, 32); + + if (flags & FILTER_FLAG_ENCODE_HIGH) { + memset(enc + 127, 1, sizeof(enc) - 127); + } + + php_filter_encode_html(value, enc); +} +/* }}} */ + +/* {{{ php_filter_full_special_chars */ +void php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL) +{ + char *buf; + size_t len; + int quotes; + + if (!(flags & FILTER_FLAG_NO_ENCODE_QUOTES)) { + quotes = ENT_QUOTES; + } else { + quotes = ENT_NOQUOTES; + } + buf = php_escape_html_entities_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), &len, 1, quotes, SG(default_charset), 0 TSRMLS_CC); + str_efree(Z_STRVAL_P(value)); + Z_STRVAL_P(value) = buf; + Z_STRLEN_P(value) = len; +} +/* }}} */ + +/* {{{ php_filter_unsafe_raw */ +void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL) +{ + /* Only if no flags are set (optimization) */ + if (flags != 0 && Z_STRLEN_P(value) > 0) { + unsigned char enc[256] = {0}; + + php_filter_strip(value, flags); + + if (flags & FILTER_FLAG_ENCODE_AMP) { + enc['&'] = 1; + } + if (flags & FILTER_FLAG_ENCODE_LOW) { + memset(enc, 1, 32); + } + if (flags & FILTER_FLAG_ENCODE_HIGH) { + memset(enc + 127, 1, sizeof(enc) - 127); + } + + php_filter_encode_html(value, enc); + } else if (flags & FILTER_FLAG_EMPTY_STRING_NULL && Z_STRLEN_P(value) == 0) { + zval_dtor(value); + ZVAL_NULL(value); + } +} +/* }}} */ + + + +/* {{{ php_filter_email */ +#define SAFE "$-_.+" +#define EXTRA "!*'()," +#define NATIONAL "{}|\\^~[]`" +#define PUNCTUATION "<>#%\"" +#define RESERVED ";/?:@&=" + +void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL) +{ + /* Check section 6 of rfc 822 http://www.faqs.org/rfcs/rfc822.html */ + const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT "!#$%&'*+-=?^_`{|}~@.[]"; + filter_map map; + + filter_map_init(&map); + filter_map_update(&map, 1, allowed_list); + filter_map_apply(value, &map); +} +/* }}} */ + +/* {{{ php_filter_url */ +void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL) +{ + /* Strip all chars not part of section 5 of + * http://www.faqs.org/rfcs/rfc1738.html */ + const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT SAFE EXTRA NATIONAL PUNCTUATION RESERVED; + filter_map map; + + filter_map_init(&map); + filter_map_update(&map, 1, allowed_list); + filter_map_apply(value, &map); +} +/* }}} */ + +/* {{{ php_filter_number_int */ +void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL) +{ + /* strip everything [^0-9+-] */ + const unsigned char allowed_list[] = "+-" DIGIT; + filter_map map; + + filter_map_init(&map); + filter_map_update(&map, 1, allowed_list); + filter_map_apply(value, &map); +} +/* }}} */ + +/* {{{ php_filter_number_float */ +void php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL) +{ + /* strip everything [^0-9+-] */ + const unsigned char allowed_list[] = "+-" DIGIT; + filter_map map; + + filter_map_init(&map); + filter_map_update(&map, 1, allowed_list); + + /* depending on flags, strip '.', 'e', ",", "'" */ + if (flags & FILTER_FLAG_ALLOW_FRACTION) { + filter_map_update(&map, 2, (const unsigned char *) "."); + } + if (flags & FILTER_FLAG_ALLOW_THOUSAND) { + filter_map_update(&map, 3, (const unsigned char *) ","); + } + if (flags & FILTER_FLAG_ALLOW_SCIENTIFIC) { + filter_map_update(&map, 4, (const unsigned char *) "eE"); + } + filter_map_apply(value, &map); +} +/* }}} */ + +/* {{{ php_filter_magic_quotes */ +void php_filter_magic_quotes(PHP_INPUT_FILTER_PARAM_DECL) +{ + char *buf; + int len; + + /* just call php_addslashes quotes */ + buf = php_addslashes(Z_STRVAL_P(value), Z_STRLEN_P(value), &len, 0 TSRMLS_CC); + + str_efree(Z_STRVAL_P(value)); + Z_STRVAL_P(value) = buf; + Z_STRLEN_P(value) = len; +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/filter/tests/001.phpt b/ext/filter/tests/001.phpt new file mode 100644 index 0000000..2755a57 --- /dev/null +++ b/ext/filter/tests/001.phpt @@ -0,0 +1,8 @@ +--TEST-- +Simple GET test +--GET-- +a=1 +--FILE-- +<?php echo $_GET['a']; ?> +--EXPECT-- +1 diff --git a/ext/filter/tests/002.phpt b/ext/filter/tests/002.phpt new file mode 100644 index 0000000..7136b25 --- /dev/null +++ b/ext/filter/tests/002.phpt @@ -0,0 +1,11 @@ +--TEST-- +GET test with 2 values and an empty one +--GET-- +a=1&b=&c=3 +--FILE-- +<?php echo $_GET['a']; +echo $_GET['b']; +echo $_GET['c']; +?> +--EXPECT-- +13 diff --git a/ext/filter/tests/003.phpt b/ext/filter/tests/003.phpt new file mode 100644 index 0000000..43e6cd9 --- /dev/null +++ b/ext/filter/tests/003.phpt @@ -0,0 +1,22 @@ +--TEST-- +GET/POST/REQUEST Test +--POST-- +d=4&e=5 +--GET-- +a=1&b=&c=3 +--FILE-- +<?php echo $_GET['a']; +echo $_GET['b']; +echo $_GET['c']; +echo $_POST['d']; +echo $_POST['e']; +echo "\n"; +echo $_REQUEST['a']; +echo $_REQUEST['b']; +echo $_REQUEST['c']; +echo $_REQUEST['d']; +echo $_REQUEST['e']; +?> +--EXPECT-- +1345 +1345 diff --git a/ext/filter/tests/004.phpt b/ext/filter/tests/004.phpt new file mode 100644 index 0000000..b899124 --- /dev/null +++ b/ext/filter/tests/004.phpt @@ -0,0 +1,26 @@ +--TEST-- +GET/POST/REQUEST Test with filtered data +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +filter.default=special_chars +--POST-- +d="quotes"&e=\slash +--GET-- +a=O'Henry&b=&c=<b>Bold</b> +--FILE-- +<?php echo $_GET['a']; +echo $_GET['b']; +echo $_GET['c']; +echo $_POST['d']; +echo $_POST['e']; +echo "\n"; +echo $_REQUEST['a']; +echo $_REQUEST['b']; +echo $_REQUEST['c']; +echo $_REQUEST['d']; +echo $_REQUEST['e']; +?> +--EXPECT-- +O'Henry<b>Bold</b>"quotes"\slash +O'Henry<b>Bold</b>"quotes"\slash diff --git a/ext/filter/tests/005.phpt b/ext/filter/tests/005.phpt new file mode 100644 index 0000000..b3735f5 --- /dev/null +++ b/ext/filter/tests/005.phpt @@ -0,0 +1,23 @@ +--TEST-- +GET/REQUEST Test with fifa example data +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +filter.default=stripped +--GET-- +id=f03_photos&pgurl=http%3A//fifaworldcup.yahoo.com/03/en/photozone/index.html +--FILE-- +<?php +echo $_GET['id']; +echo "\n"; +echo $_GET['pgurl']; +echo "\n"; +echo $_REQUEST['id']; +echo "\n"; +echo $_REQUEST['pgurl']; +?> +--EXPECT-- +f03_photos +http://fifaworldcup.yahoo.com/03/en/photozone/index.html +f03_photos +http://fifaworldcup.yahoo.com/03/en/photozone/index.html diff --git a/ext/filter/tests/006.phpt b/ext/filter/tests/006.phpt new file mode 100644 index 0000000..9439e47 --- /dev/null +++ b/ext/filter/tests/006.phpt @@ -0,0 +1,12 @@ +--TEST-- +filter() test +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--POST-- +foo=<b>abc</b> +--FILE-- +<?php +echo filter_input(INPUT_POST, 'foo', FILTER_SANITIZE_STRIPPED); +?> +--EXPECT-- +abc diff --git a/ext/filter/tests/007.phpt b/ext/filter/tests/007.phpt new file mode 100644 index 0000000..96e0b5f --- /dev/null +++ b/ext/filter/tests/007.phpt @@ -0,0 +1,64 @@ +--TEST-- +filter_has_var() +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--GET-- +a=qwe&abc=<a>href</a> +--POST-- +b=qwe&bbc=<a>href</a> +--FILE-- +<?php + +var_dump(filter_has_var(INPUT_GET, "a")); +var_dump(filter_has_var(INPUT_GET, "abc")); +var_dump(filter_has_var(INPUT_GET, "nonex")); +var_dump(filter_has_var(INPUT_GET, " ")); +var_dump(filter_has_var(INPUT_GET, "")); +var_dump(filter_has_var(INPUT_GET, array())); + +var_dump(filter_has_var(INPUT_POST, "b")); +var_dump(filter_has_var(INPUT_POST, "bbc")); +var_dump(filter_has_var(INPUT_POST, "nonex")); +var_dump(filter_has_var(INPUT_POST, " ")); +var_dump(filter_has_var(INPUT_POST, "")); +var_dump(filter_has_var(INPUT_POST, array())); + +var_dump(filter_has_var(-1, "")); +var_dump(filter_has_var("", "")); +var_dump(filter_has_var(array(), array())); +var_dump(filter_has_var(array(), "")); +var_dump(filter_has_var("", array())); + +echo "Done\n"; +?> +--EXPECTF-- +bool(true) +bool(true) +bool(false) +bool(false) +bool(false) + +Warning: filter_has_var() expects parameter 2 to be string, array given in %s007.php on line %d +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) +bool(false) + +Warning: filter_has_var() expects parameter 2 to be string, array given in %s007.php on line %d +bool(false) +bool(false) + +Warning: filter_has_var() expects parameter 1 to be long, string given in %s007.php on line %d +bool(false) + +Warning: filter_has_var() expects parameter 1 to be long, array given in %s007.php on line %d +bool(false) + +Warning: filter_has_var() expects parameter 1 to be long, array given in %s007.php on line %d +bool(false) + +Warning: filter_has_var() expects parameter 1 to be long, string given in %s007.php on line %d +bool(false) +Done diff --git a/ext/filter/tests/008.phpt b/ext/filter/tests/008.phpt new file mode 100644 index 0000000..8a43405 --- /dev/null +++ b/ext/filter/tests/008.phpt @@ -0,0 +1,57 @@ +--TEST-- +filter_list() +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_list()); +var_dump(filter_list(array())); + +echo "Done\n"; +?> +--EXPECTF-- +array(19) { + [0]=> + string(3) "int" + [1]=> + string(7) "boolean" + [2]=> + string(5) "float" + [3]=> + string(15) "validate_regexp" + [4]=> + string(12) "validate_url" + [5]=> + string(14) "validate_email" + [6]=> + string(11) "validate_ip" + [7]=> + string(6) "string" + [8]=> + string(8) "stripped" + [9]=> + string(7) "encoded" + [10]=> + string(13) "special_chars" + [11]=> + string(18) "full_special_chars" + [12]=> + string(10) "unsafe_raw" + [13]=> + string(5) "email" + [14]=> + string(3) "url" + [15]=> + string(10) "number_int" + [16]=> + string(12) "number_float" + [17]=> + string(12) "magic_quotes" + [18]=> + string(8) "callback" +} + +Warning: filter_list() expects exactly 0 parameters, 1 given in %s on line %d +NULL +Done diff --git a/ext/filter/tests/009.phpt b/ext/filter/tests/009.phpt new file mode 100644 index 0000000..d09f996 --- /dev/null +++ b/ext/filter/tests/009.phpt @@ -0,0 +1,32 @@ +--TEST-- +filter_id() +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_id("stripped")); +var_dump(filter_id("string")); +var_dump(filter_id("url")); +var_dump(filter_id("int")); +var_dump(filter_id("none")); +var_dump(filter_id(array())); +var_dump(filter_id(-1)); +var_dump(filter_id(0,0,0)); + +echo "Done\n"; +?> +--EXPECTF-- +int(513) +int(513) +int(518) +int(257) +bool(false) + +Warning: filter_id() expects parameter 1 to be string, array given in %s on line %d +NULL +bool(false) + +Warning: filter_id() expects exactly 1 parameter, 3 given in %s on line %d +NULL +Done diff --git a/ext/filter/tests/010.phpt b/ext/filter/tests/010.phpt new file mode 100644 index 0000000..e868c10 --- /dev/null +++ b/ext/filter/tests/010.phpt @@ -0,0 +1,64 @@ +--TEST-- +filter_var() +--INI-- +precision=14 +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var(array(1,"1","", "-23234", "text", "asdf234asdfgs", array()), FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY)); +var_dump(filter_var(array(1.2,"1.7","", "-23234.123", "text", "asdf234.2asdfgs", array()), FILTER_VALIDATE_FLOAT, FILTER_REQUIRE_ARRAY)); +var_dump(filter_var(1, array())); +var_dump(filter_var(1, FILTER_SANITIZE_STRING, 1)); +var_dump(filter_var(1, FILTER_SANITIZE_STRING, 0)); +var_dump(filter_var(1, FILTER_SANITIZE_STRING, array())); +var_dump(filter_var(1, -1, array(123))); +var_dump(filter_var(1, 0, array())); + +echo "Done\n"; +?> +--EXPECTF-- +array(7) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + bool(false) + [3]=> + int(-23234) + [4]=> + bool(false) + [5]=> + bool(false) + [6]=> + array(0) { + } +} +array(7) { + [0]=> + float(1.2) + [1]=> + float(1.7) + [2]=> + bool(false) + [3]=> + float(-23234.123) + [4]=> + bool(false) + [5]=> + bool(false) + [6]=> + array(0) { + } +} + +Warning: filter_var() expects parameter 2 to be long, array given in %s on line %d +NULL +string(1) "1" +string(1) "1" +string(1) "1" +bool(false) +bool(false) +Done diff --git a/ext/filter/tests/011.phpt b/ext/filter/tests/011.phpt new file mode 100644 index 0000000..6a9bf1f --- /dev/null +++ b/ext/filter/tests/011.phpt @@ -0,0 +1,54 @@ +--TEST-- +input_get() +--INI-- +precision=14 +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--GET-- +a=<b>test</b>&b=http://example.com +--POST-- +c=<p>string</p>&d=12345.7 +--FILE-- +<?php +ini_set('html_errors', false); +var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_STRIPPED)); +var_dump(filter_input(INPUT_GET, "b", FILTER_SANITIZE_URL)); +var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_SPECIAL_CHARS, array(1,2,3,4,5))); +var_dump(filter_input(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass)); +var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_STRIPPED, array(5,6,7,8))); +var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_FLOAT)); +var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_SPECIAL_CHARS)); +var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_INT)); + +var_dump(filter_var(new stdClass, "d")); + +var_dump(filter_input(INPUT_POST, "c", "", "")); +var_dump(filter_var("", "", "", "", "")); +var_dump(filter_var(0, 0, 0, 0, 0)); + +echo "Done\n"; +?> +--EXPECTF-- +string(4) "test" +string(18) "http://example.com" +string(27) "<b>test</b>" + +Notice: Object of class stdClass could not be converted to int in %s011.php on line %d +bool(false) +string(6) "string" +float(12345.7) +string(29) "<p>string</p>" +bool(false) + +Warning: filter_var() expects parameter 2 to be long, string given in %s011.php on line %d +NULL + +Warning: filter_input() expects parameter 3 to be long, string given in %s011.php on line %d +NULL + +Warning: filter_var() expects at most 3 parameters, 5 given in %s011.php on line %d +NULL + +Warning: filter_var() expects at most 3 parameters, 5 given in %s011.php on line %d +NULL +Done diff --git a/ext/filter/tests/012.phpt b/ext/filter/tests/012.phpt new file mode 100644 index 0000000..9a8ead9 --- /dev/null +++ b/ext/filter/tests/012.phpt @@ -0,0 +1,18 @@ +--TEST-- +filter_input() +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_input(INPUT_GET, "test")); +var_dump(filter_input(INPUT_POST, "test")); +var_dump(filter_input(INPUT_COOKIE, "")); + +echo "Done\n"; +?> +--EXPECT-- +NULL +NULL +NULL +Done diff --git a/ext/filter/tests/013.phpt b/ext/filter/tests/013.phpt new file mode 100644 index 0000000..421c5d5 --- /dev/null +++ b/ext/filter/tests/013.phpt @@ -0,0 +1,74 @@ +--TEST-- +filter_var() and flags +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_var(" 234", FILTER_VALIDATE_INT)); +var_dump(filter_var("234 ", FILTER_VALIDATE_INT)); +var_dump(filter_var(" 234 ", FILTER_VALIDATE_INT)); +var_dump(filter_var("0xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("0Xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("0xFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("0XFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("07", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +var_dump(filter_var("0xff0000", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("0666", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +var_dump(filter_var("08", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +var_dump(filter_var("00", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +var_dump(filter_var("000", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); + +var_dump(filter_var("-0xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("-0Xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("-0xFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("-0XFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("-07", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +var_dump(filter_var("-0xff0000", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +var_dump(filter_var("-0666", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); + +var_dump(filter_var("6", FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>7)))); +var_dump(filter_var("6", FILTER_VALIDATE_INT, array("options" => array("min_range"=>0, "max_range"=>5)))); +var_dump(filter_var(-1, FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>7)))); +var_dump(filter_var(-1, FILTER_VALIDATE_INT, array("options" => array("min_range"=>-4, "max_range"=>7)))); + +var_dump(filter_var("", FILTER_VALIDATE_INT, array("options" => array("min_range"=>-4, "max_range"=>7)))); +var_dump(filter_var("", FILTER_VALIDATE_INT, array("options" => array("min_range"=>2, "max_range"=>7)))); +var_dump(filter_var("", FILTER_VALIDATE_INT, array("options" => array("min_range"=>-5, "max_range"=>-3)))); +var_dump(filter_var(345, FILTER_VALIDATE_INT, array("options" => array("min_range"=>500, "max_range"=>100)))); +var_dump(filter_var("0ff", FILTER_VALIDATE_INT)); +var_dump(filter_var("010", FILTER_VALIDATE_INT)); + +echo "Done\n"; +?> +--EXPECT-- +int(234) +int(234) +int(234) +int(255) +int(255) +int(255) +int(255) +int(7) +int(16711680) +int(438) +bool(false) +int(0) +int(0) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +int(6) +bool(false) +bool(false) +int(-1) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +Done diff --git a/ext/filter/tests/014.phpt b/ext/filter/tests/014.phpt new file mode 100644 index 0000000..8837457 --- /dev/null +++ b/ext/filter/tests/014.phpt @@ -0,0 +1,70 @@ +--TEST-- +filter_var() and FILTER_VALIDATE_BOOLEAN +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +class test { + + function __toString() { + return "blah"; + } +} + +$t = new test; + +var_dump(filter_var("no", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var(NULL, FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var($t, FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var(array(1,2,3,0,array("", "123")), FILTER_VALIDATE_BOOLEAN, FILTER_REQUIRE_ARRAY)); +var_dump(filter_var("yes", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("true", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("false", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("off", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("on", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("0", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("1", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("NONE", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var(-1, FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("000000", FILTER_VALIDATE_BOOLEAN)); +var_dump(filter_var("111111", FILTER_VALIDATE_BOOLEAN)); + + +echo "Done\n"; +?> +--EXPECT-- +bool(false) +bool(false) +bool(false) +array(5) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + bool(false) + [3]=> + bool(false) + [4]=> + array(2) { + [0]=> + bool(false) + [1]=> + bool(false) + } +} +bool(true) +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +Done diff --git a/ext/filter/tests/015.phpt b/ext/filter/tests/015.phpt new file mode 100644 index 0000000..476615a --- /dev/null +++ b/ext/filter/tests/015.phpt @@ -0,0 +1,89 @@ +--TEST-- +filter_var() and FILTER_VALIDATE_URL +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +$values = Array( +'http://example.com/index.html', +'http://www.example.com/index.php', +'http://www.example/img/test.png', +'http://www.example/img/dir/', +'http://www.example/img/dir', +'http//www.example/wrong/url/', +'http:/www.example', +'file:///tmp/test.c', +'ftp://ftp.example.com/tmp/', +'/tmp/test.c', +'/', +'http://', +'http:/', +'http:', +'http', +'', +-1, +array(), +'mailto:foo@bar.com', +'news:news.php.net', +'file://foo/bar', +"http://\r\n/bar", +"http://example.com:qq", +"http://example.com:-2", +"http://example.com:65536", +"http://example.com:65537", +); +foreach ($values as $value) { + var_dump(filter_var($value, FILTER_VALIDATE_URL)); +} + + +var_dump(filter_var("qwe", FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)); +var_dump(filter_var("http://qwe", FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)); +var_dump(filter_var("http://", FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)); +var_dump(filter_var("/tmp/test", FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)); +var_dump(filter_var("http://www.example.com", FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)); +var_dump(filter_var("http://www.example.com", FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)); +var_dump(filter_var("http://www.example.com/path/at/the/server/", FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)); +var_dump(filter_var("http://www.example.com/index.html", FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED)); +var_dump(filter_var("http://www.example.com/index.php?a=b&c=d", FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED)); + +echo "Done\n"; +?> +--EXPECT-- +string(29) "http://example.com/index.html" +string(32) "http://www.example.com/index.php" +string(31) "http://www.example/img/test.png" +string(27) "http://www.example/img/dir/" +string(26) "http://www.example/img/dir" +bool(false) +bool(false) +string(18) "file:///tmp/test.c" +string(26) "ftp://ftp.example.com/tmp/" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(18) "mailto:foo@bar.com" +string(17) "news:news.php.net" +string(14) "file://foo/bar" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(10) "http://qwe" +bool(false) +bool(false) +string(22) "http://www.example.com" +bool(false) +string(42) "http://www.example.com/path/at/the/server/" +bool(false) +string(40) "http://www.example.com/index.php?a=b&c=d" +Done diff --git a/ext/filter/tests/016.phpt b/ext/filter/tests/016.phpt new file mode 100644 index 0000000..c678344 --- /dev/null +++ b/ext/filter/tests/016.phpt @@ -0,0 +1,46 @@ +--TEST-- +filter_var() and FILTER_VALIDATE_EMAIL +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$values = Array( +'a@b.c', +'abuse@example.com', +'test!.!@#$%^&*@example.com', +'test@@#$%^&*())).com', +'test@.com', +'test@com', +'@', +'[]()/@example.com', +'QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET', +'e.x.a.m.p.l.e.@example.com', +'firstname.lastname@employee.2something.com', +'-@foo.com', +'foo@-.com', +'foo@bar.123', +'foo@bar.-' +); +foreach ($values as $value) { + var_dump(filter_var($value, FILTER_VALIDATE_EMAIL)); +} + +echo "Done\n"; +?> +--EXPECT-- +string(5) "a@b.c" +string(17) "abuse@example.com" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(57) "QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET" +bool(false) +string(42) "firstname.lastname@employee.2something.com" +string(9) "-@foo.com" +bool(false) +bool(false) +bool(false) +Done diff --git a/ext/filter/tests/017.phpt b/ext/filter/tests/017.phpt new file mode 100644 index 0000000..518ee79 --- /dev/null +++ b/ext/filter/tests/017.phpt @@ -0,0 +1,26 @@ +--TEST-- +filter_var() and FILTER_VALIDATE_REGEXP +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/.*/')))); +var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/^b(.*)/')))); +var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/^d(.*)/')))); +var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/blah/')))); +var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/\[/')))); +var_dump(filter_var("data", FILTER_VALIDATE_REGEXP)); + +echo "Done\n"; +?> +--EXPECTF-- +string(4) "data" +bool(false) +string(4) "data" +bool(false) +bool(false) + +Warning: filter_var(): 'regexp' option missing in %s on line %d +bool(false) +Done diff --git a/ext/filter/tests/018.phpt b/ext/filter/tests/018.phpt new file mode 100644 index 0000000..af52b2e --- /dev/null +++ b/ext/filter/tests/018.phpt @@ -0,0 +1,54 @@ +--TEST-- +filter_var() and FILTER_VALIDATE_IP +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_var("192.168.0.1", FILTER_VALIDATE_IP)); +var_dump(filter_var("192.168.0.1.1", FILTER_VALIDATE_IP)); +var_dump(filter_var("::1", FILTER_VALIDATE_IP)); +var_dump(filter_var("fe00::0", FILTER_VALIDATE_IP)); +var_dump(filter_var("::123456", FILTER_VALIDATE_IP)); +var_dump(filter_var("::1::b", FILTER_VALIDATE_IP)); +var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP)); +var_dump(filter_var("192.168.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)); +var_dump(filter_var("192.0.34.166", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)); +var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var("192.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var("192.0.34.166", FILTER_VALIDATE_IP)); +var_dump(filter_var("256.1237.123.1", FILTER_VALIDATE_IP)); +var_dump(filter_var("255.255.255.255", FILTER_VALIDATE_IP)); +var_dump(filter_var("255.255.255.255", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var("", FILTER_VALIDATE_IP)); +var_dump(filter_var(-1, FILTER_VALIDATE_IP)); +var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)); +var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); +var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); +var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)); +echo "Done\n"; +?> +--EXPECT-- +string(11) "192.168.0.1" +bool(false) +string(3) "::1" +string(7) "fe00::0" +bool(false) +bool(false) +string(9) "127.0.0.1" +bool(false) +string(12) "192.0.34.166" +bool(false) +string(9) "192.0.0.1" +string(12) "192.0.34.166" +bool(false) +string(15) "255.255.255.255" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(3) "::1" +bool(false) +string(9) "127.0.0.1" +Done diff --git a/ext/filter/tests/019.phpt b/ext/filter/tests/019.phpt new file mode 100644 index 0000000..1665181 --- /dev/null +++ b/ext/filter/tests/019.phpt @@ -0,0 +1,22 @@ +--TEST-- +filter_var() & FILTER_VALIDATE_IP and weird data +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("....", FILTER_VALIDATE_IP)); +var_dump(filter_var("...", FILTER_VALIDATE_IP)); +var_dump(filter_var("..", FILTER_VALIDATE_IP)); +var_dump(filter_var(".", FILTER_VALIDATE_IP)); +var_dump(filter_var("1.1.1.1", FILTER_VALIDATE_IP)); + +echo "Done\n"; +?> +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(false) +string(7) "1.1.1.1" +Done diff --git a/ext/filter/tests/020.phpt b/ext/filter/tests/020.phpt new file mode 100644 index 0000000..c2ab609 --- /dev/null +++ b/ext/filter/tests/020.phpt @@ -0,0 +1,20 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_MAGIC_QUOTES +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("test'asd'asd'' asd\'\"asdfasdf", FILTER_SANITIZE_MAGIC_QUOTES)); +var_dump(filter_var("'", FILTER_SANITIZE_MAGIC_QUOTES)); +var_dump(filter_var("", FILTER_SANITIZE_MAGIC_QUOTES)); +var_dump(filter_var(-1, FILTER_SANITIZE_MAGIC_QUOTES)); + +echo "Done\n"; +?> +--EXPECT-- +string(36) "test\'asd\'asd\'\' asd\\\'\"asdfasdf" +string(2) "\'" +string(0) "" +string(2) "-1" +Done diff --git a/ext/filter/tests/021.phpt b/ext/filter/tests/021.phpt new file mode 100644 index 0000000..994dac2 --- /dev/null +++ b/ext/filter/tests/021.phpt @@ -0,0 +1,46 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_NUMBER_* +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("qwertyu123456dfghj", FILTER_SANITIZE_NUMBER_INT)); +var_dump(filter_var("asd123123.asd123.23", FILTER_SANITIZE_NUMBER_INT)); +var_dump(filter_var("123,23", FILTER_SANITIZE_NUMBER_INT)); +var_dump(filter_var("", FILTER_SANITIZE_NUMBER_INT)); +var_dump(filter_var("0", FILTER_SANITIZE_NUMBER_INT)); +var_dump(filter_var("asd123.2asd", FILTER_SANITIZE_NUMBER_INT)); +var_dump(filter_var("qwertyuiop", FILTER_SANITIZE_NUMBER_INT)); +var_dump(filter_var("123.4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); +var_dump(filter_var("123,4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); +var_dump(filter_var("123.4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND)); +var_dump(filter_var("123,4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND)); +var_dump(filter_var("123.4e", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC)); +var_dump(filter_var("123,4E", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC)); +var_dump(filter_var("qwe123,4qwe", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); +var_dump(filter_var("werty65456.34", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); +var_dump(filter_var("234.56fsfd", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); +var_dump(filter_var("", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); + +echo "Done\n"; +?> +--EXPECT-- +string(6) "123456" +string(11) "12312312323" +string(5) "12323" +string(0) "" +string(1) "0" +string(4) "1232" +string(0) "" +string(5) "123.4" +string(4) "1234" +string(4) "1234" +string(5) "123,4" +string(5) "1234e" +string(5) "1234E" +string(4) "1234" +string(8) "65456.34" +string(6) "234.56" +string(0) "" +Done diff --git a/ext/filter/tests/022.phpt b/ext/filter/tests/022.phpt new file mode 100644 index 0000000..649c6e4 --- /dev/null +++ b/ext/filter/tests/022.phpt @@ -0,0 +1,22 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_EMAIL +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("a@b.c", FILTER_SANITIZE_EMAIL)); +var_dump(filter_var("a[!@#$%^&*()@a@#$%^&*(.com@#$%^&*(", FILTER_SANITIZE_EMAIL)); +var_dump(filter_var("white space here \ \ \" som more", FILTER_SANITIZE_EMAIL)); +var_dump(filter_var("", FILTER_SANITIZE_EMAIL)); +var_dump(filter_var("123456789000000", FILTER_SANITIZE_EMAIL)); + +echo "Done\n"; +?> +--EXPECTF-- +string(5) "a@b.c" +string(30) "a[!@#$%^&*@a@#$%^&*.com@#$%^&*" +string(21) "whitespaceheresommore" +string(0) "" +string(15) "123456789000000" +Done diff --git a/ext/filter/tests/023.phpt b/ext/filter/tests/023.phpt new file mode 100644 index 0000000..f8d4137 --- /dev/null +++ b/ext/filter/tests/023.phpt @@ -0,0 +1,22 @@ +--TEST-- +filter_var() and FILTER_UNSAFE_RAW +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("}\"<p>test para</p>", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP)); +var_dump(filter_var("a[!@#<b>$%^&*()@a@#$%^&*(.<br>com@#$%^&*(", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP)); +var_dump(filter_var("white space here \ \ \" some more", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP)); +var_dump(filter_var("", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP)); +var_dump(filter_var(" 123456789000000 <qwertyuiop> ", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP)); + +echo "Done\n"; +?> +--EXPECT-- +string(18) "}"<p>test para</p>" +string(53) "a[!@#<b>$%^&*()@a@#$%^&*(.<br>com@#$%^&*(" +string(32) "white space here \ \ " some more" +string(0) "" +string(48) " 123456789000000 <qwertyuiop> " +Done diff --git a/ext/filter/tests/024.phpt b/ext/filter/tests/024.phpt new file mode 100644 index 0000000..7d7349f --- /dev/null +++ b/ext/filter/tests/024.phpt @@ -0,0 +1,20 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_ENCODED +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("\"<br>blah</ph>", FILTER_SANITIZE_ENCODED)); +var_dump(filter_var("", FILTER_SANITIZE_ENCODED)); +var_dump(filter_var(" text here ", FILTER_SANITIZE_ENCODED)); +var_dump(filter_var("!@#$%^&*()QWERTYUIOP{ASDFGHJKL:\"ZXCVBNM<>?", FILTER_SANITIZE_ENCODED)); + +echo "Done\n"; +?> +--EXPECT-- +string(26) "%22%3Cbr%3Eblah%3C%2Fph%3E" +string(0) "" +string(23) "%20%20text%20here%20%20" +string(74) "%21%40%23%24%25%5E%26%2A%28%29QWERTYUIOP%7BASDFGHJKL%3A%22ZXCVBNM%3C%3E%3F" +Done diff --git a/ext/filter/tests/025.phpt b/ext/filter/tests/025.phpt new file mode 100644 index 0000000..df8c373 --- /dev/null +++ b/ext/filter/tests/025.phpt @@ -0,0 +1,26 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_STRING +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("", FILTER_SANITIZE_STRING)); +var_dump(filter_var("<>", FILTER_SANITIZE_STRING)); +var_dump(filter_var("<>!@#$%^&*()'\"", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES)); +var_dump(filter_var("<>!@#$%^&*()'\"", FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_AMP)); +var_dump(filter_var("<>`1234567890", FILTER_SANITIZE_STRING)); +var_dump(filter_var("`123`", FILTER_SANITIZE_STRING)); +var_dump(filter_var(".", FILTER_SANITIZE_STRING)); + +echo "Done\n"; +?> +--EXPECT-- +string(0) "" +string(0) "" +string(12) "!@#$%^&*()'"" +string(24) "!@#$%^&*()'"" +string(11) "`1234567890" +string(5) "`123`" +string(1) "." +Done diff --git a/ext/filter/tests/026.phpt b/ext/filter/tests/026.phpt new file mode 100644 index 0000000..38d15e7 --- /dev/null +++ b/ext/filter/tests/026.phpt @@ -0,0 +1,32 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_STRIPPED +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED)); +var_dump(filter_var("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED)); +var_dump(filter_var("", FILTER_SANITIZE_STRIPPED)); + +var_dump(filter_var("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW)); +var_dump(filter_var("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW)); +var_dump(filter_var("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW)); + +var_dump(filter_var("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH)); +var_dump(filter_var("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH)); +var_dump(filter_var("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH)); + +echo "Done\n"; +?> +--EXPECTF-- +string(40) "Let me see you Stripped down to the bone" +string(11) "!@#$%^&*()>" +string(0) "" +string(40) "Let me see you Stripped down to the bone" +string(11) "!@#$%^&*()>" +string(0) "" +string(40) "Let me see you Stripped down to the bone" +string(11) "!@#$%^&*()>" +string(0) "" +Done diff --git a/ext/filter/tests/027.phpt b/ext/filter/tests/027.phpt new file mode 100644 index 0000000..759030a --- /dev/null +++ b/ext/filter/tests/027.phpt @@ -0,0 +1,32 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_ENCODED +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED)); +var_dump(filter_var("<data&sons>", FILTER_SANITIZE_ENCODED)); +var_dump(filter_var("", FILTER_SANITIZE_ENCODED)); + +var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW)); +var_dump(filter_var("<data&sons>", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW)); +var_dump(filter_var("", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW)); + +var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH)); +var_dump(filter_var("<data&sons>", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH)); +var_dump(filter_var("", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH)); + +echo "Done\n"; +?> +--EXPECT-- +string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn" +string(17) "%3Cdata%26sons%3E" +string(0) "" +string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn" +string(17) "%3Cdata%26sons%3E" +string(0) "" +string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn" +string(17) "%3Cdata%26sons%3E" +string(0) "" +Done diff --git a/ext/filter/tests/028.phpt b/ext/filter/tests/028.phpt new file mode 100644 index 0000000..c0ab16f --- /dev/null +++ b/ext/filter/tests/028.phpt @@ -0,0 +1,37 @@ +--TEST-- +filter_var() and FILTER_SANITIZE_SPECIAL_CHARS +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS)); +var_dump(filter_var("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS)); +var_dump(filter_var("", FILTER_SANITIZE_SPECIAL_CHARS)); + +var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW)); +var_dump(filter_var("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW)); +var_dump(filter_var("", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW)); + +var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH)); +var_dump(filter_var("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH)); +var_dump(filter_var("", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH)); + +var_dump(filter_var("ะบะธัะธะปะปะธัะฐ", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH)); +var_dump(filter_var("ะบะธัะธะปะปะธัะฐ", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW)); + +echo "Done\n"; +?> +--EXPECT-- +string(55) "?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn" +string(23) "<data&sons>" +string(0) "" +string(55) "?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn" +string(23) "<data&sons>" +string(0) "" +string(55) "?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn" +string(23) "<data&sons>" +string(0) "" +string(108) "кириллица" +string(18) "ะบะธัะธะปะปะธัะฐ" +Done diff --git a/ext/filter/tests/029.phpt b/ext/filter/tests/029.phpt new file mode 100644 index 0000000..c1ede74 --- /dev/null +++ b/ext/filter/tests/029.phpt @@ -0,0 +1,105 @@ +--TEST-- +filter_var() and FILTER_CALLBACK +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +/* Simple callback function */ +function test($var) { + return strtoupper($var); +} + +var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test"))); +var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test"))); +var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test"))); +var_dump(filter_var("qwe", FILTER_CALLBACK, array("options"=>"no such func"))); +var_dump(filter_var("qwe", FILTER_CALLBACK, array("options"=>""))); +var_dump(filter_var("qwe", FILTER_CALLBACK)); + +/* Simple class method callback */ +class test_class { + static function test ($var) { + return strtolower($var); + } +} + +var_dump(filter_var("dAtA", FILTER_CALLBACK, array("options"=>array("test_class", "test")))); +var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>array("test_class","test")))); +var_dump(filter_var("", FILTER_CALLBACK, array("options"=>array("test_class","test")))); + +/* empty function without return value */ +function test1($var) { +} + +var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test1"))); +var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test1"))); +var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test1"))); + +/* attempting to change data by reference */ +function test2(&$var) { + $var = 1; +} + +var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test2"))); +var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test2"))); +var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test2"))); + +/* unsetting data */ +function test3(&$var) { + unset($var); +} + +var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test3"))); +var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test3"))); +var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test3"))); + +/* unset data and return value */ +function test4(&$var) { + unset($var); + return 1; +} + +var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test4"))); + +/* thrown exception in the callback */ +function test5(&$var) { + throw new Exception("test"); +} + +try { + var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test5"))); +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +echo "Done\n"; +?> +--EXPECTF-- +string(4) "DATA" +string(46) "~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?"}{:" +string(0) "" + +Warning: filter_var(): First argument is expected to be a valid callback in %s on line %d +NULL + +Warning: filter_var(): First argument is expected to be a valid callback in %s on line %d +NULL + +Warning: filter_var(): First argument is expected to be a valid callback in %s on line %d +NULL +string(4) "data" +string(46) "~!@#$%^&*()_qwertyuiopasdfghjklzxcvbnm<>>?"}{:" +string(0) "" +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +int(1) +string(4) "test" +Done diff --git a/ext/filter/tests/030.phpt b/ext/filter/tests/030.phpt new file mode 100644 index 0000000..c5af15e --- /dev/null +++ b/ext/filter/tests/030.phpt @@ -0,0 +1,64 @@ +--TEST-- +filter_var() and IPv6 +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$ipv6_test = array( + "::127.0.0.1" => true, + "FF01::101:127.0.1" => false, + "FF01:0:0:0:101:127.0.1.1" => false, + "FF01:0:0:0:237:101:127.0.1.1" => true, + "FF01::101" => true, + "A1080::8:800:200C:417A" => false, + "1080::8:Z00:200C:417A" => false, + "FF01::101::1" => false, + "1080::8:800:200C:417A" => true, + "1080:0:0:0:8:800:200C:417A" => true, + "2001:ec8:1:1:1:1:1:1" => true, + "ffff::FFFF:129.144.52.38" => true, + "::ffff:1.2.3.4" => true, + "0:0:0:0:0:FFFF:129.144.52.38" => true, + "0:0:0:0:0:0:13.1.68.3" => true, + "0:0:0:0:0:0:0:13.1.68.3" => false, + "::13.1.68.3" => true, + "::FFFF:129.144.52.38" => true, + + "1:2:3:4:5:6::129.144.52.38" => false, + "::1:2:3:4:5:6:129.144.52.38" => false, + "1:2:3::4:5:6:129.144.52.38" => false, + + "1:2:3:4::5:6:7:8" => false, + "::1:2:3:4:5:6:7" => true, + "::1:2:3:4:5:6:7:8" => false, + "1:2:3:4:5:6:7::" => true, + "1:2:3:4:5:6:7:8::" => false, + "1:2:3:4:5:6:7::8" => false, + + "1:2:3:4:5:6:7:8g" => false, + "1:2:3:4:5:6:7:g" => false, + "1:2:3:4:5g:6:7:8" => false, + + 'a:b:c:d:e::1.2.3.4' => true, + '::0:a:b:c:d:e:f' => true, + '0:a:b:c:d:e:f::' => true, + ':::1.2.3.4' => false, + '8:::1.2.3.4' => false, + '::01.02.03.04' => false, + '::1.00.3.4' => false, + '0:0:0:255.255.255.255' => false, + '0:0:0::255.255.255.255' => true, +); +foreach ($ipv6_test as $ip => $exp) { + $out = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); + $out = (int) ($out === false ? 0 : 1); + if ($exp != $out) { + echo "$ip failed (expected ", $exp?"true":"false", ", got ", + $out?"true":"false", ")\n"; + } +} + +echo "Ok\n"; +?> +--EXPECT-- +Ok diff --git a/ext/filter/tests/031.phpt b/ext/filter/tests/031.phpt new file mode 100644 index 0000000..23691fb --- /dev/null +++ b/ext/filter/tests/031.phpt @@ -0,0 +1,58 @@ +--TEST-- +filter_var() and FLOAT +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +precision=14 +--FILE-- +<?php + +$floats = array( +'1.234 ', +' 1.234', +'1.234' , +'1.2e3', +'7E3', +'7E3 ', +' 7E3 ', +' 7E-3 ' +); + +foreach ($floats as $float) { + $out = filter_var($float, FILTER_VALIDATE_FLOAT); + var_dump($out); +} + +$floats = array( +'1.234 ' => ',', +'1,234' => ',', +' 1.234' => '.', +'1.234' => '..', +'1.2e3' => ',' +); + +echo "\ncustom decimal:\n"; +foreach ($floats as $float => $dec) { + $out = filter_var($float, FILTER_VALIDATE_FLOAT, array("options"=>array('decimal' => $dec))); + var_dump($out); +} + +?> +--EXPECTF-- +float(1.234) +float(1.234) +float(1.234) +float(1200) +float(7000) +float(7000) +float(7000) +float(0.007) + +custom decimal: +bool(false) +float(1.234) +float(1.234) + +Warning: filter_var(): decimal separator must be one char in %s on line %d +bool(false) +bool(false) diff --git a/ext/filter/tests/032.phpt b/ext/filter/tests/032.phpt new file mode 100644 index 0000000..d88d502 --- /dev/null +++ b/ext/filter/tests/032.phpt @@ -0,0 +1,57 @@ +--TEST-- +input_get_args() +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$data = array( + 'product_id' => 'libgd<script>', + 'component' => '10dhsajkkdhk <do>', + 'versions' => '2.0.33', + 'testscalar' => array('2','23','10','12'), + 'testarray' => '2', +); + +$args = array( + 'product_id' => FILTER_SANITIZE_ENCODED, + 'component' => array(//'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FORCE_ARRAY, + 'options' => array("min_range"=>1, "max_range"=>10) + ), + 'versions' => array( + 'filter' => FILTER_SANITIZE_ENCODED, + 'flags' => FILTER_REQUIRE_SCALAR, + ), + 'doesnotexist' => FILTER_VALIDATE_INT, + 'testscalar' => FILTER_VALIDATE_INT, + 'testarray' => array( + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FORCE_ARRAY, + ) + +); + +$myinputs = filter_var_array($data, $args); +var_dump($myinputs); +?> +--EXPECT-- +array(6) { + ["product_id"]=> + string(17) "libgd%3Cscript%3E" + ["component"]=> + array(1) { + [0]=> + string(17) "10dhsajkkdhk <do>" + } + ["versions"]=> + string(6) "2.0.33" + ["doesnotexist"]=> + NULL + ["testscalar"]=> + bool(false) + ["testarray"]=> + array(1) { + [0]=> + int(2) + } +} diff --git a/ext/filter/tests/033.phpt b/ext/filter/tests/033.phpt new file mode 100644 index 0000000..04daa61 --- /dev/null +++ b/ext/filter/tests/033.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test all filters returned by filter_list() +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +precision=14 +default_charset=UTF-8 +--FILE-- +<?php +include dirname(__FILE__) . '/033_run.inc'; +?> +--EXPECT-- +int 1 123 +boolean 1 +float 1 123 +validate_regexp O'Henry +validate_url http://a.b.c +validate_email foo@bar.com +validate_ip 1.2.3.4 +string PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc() O'Henry ํํผ +stripped PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc() O'Henry ํํผ +encoded PHP 1 foo%40bar.com http%3A%2F%2Fa.b.c 1.2.3.4 123 123abc%3C%3E%28%29 O%27Henry %ED%95%98%ED%8D%BC +special_chars PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry ํํผ +full_special_chars PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry ํํผ +unsafe_raw PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry ํํผ +email PHP 1 foo@bar.com httpa.b.c 1.2.3.4 123 123abc O'Henry +url PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry +number_int 1 1234 123 123 +number_float 1 1234 123 123 +magic_quotes PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O\'Henry ํํผ +callback PHP 1 FOO@BAR.COM HTTP://A.B.C 1.2.3.4 123 123ABC<>() O'HENRY ํํผ diff --git a/ext/filter/tests/033_run.inc b/ext/filter/tests/033_run.inc new file mode 100644 index 0000000..e3b6738 --- /dev/null +++ b/ext/filter/tests/033_run.inc @@ -0,0 +1,40 @@ +<?php +if (function_exists('setlocale')) { + setlocale(LC_ALL, 'C'); +} + +function test($data) { + return strtoupper($data); +} + +$data = array( + "PHP", + "1", + "foo@bar.com", + "http://a.b.c", + "1.2.3.4", + "123", + "123abc<>()", + "O'Henry", + "ํํผ" +); + + +foreach(filter_list() as $filter) { + if($filter=="validate_regexp") { + foreach($data as $k=>$d) $result[$k] = filter_var($d,filter_id($filter),array("options"=>array("regexp"=>'/^O.*/'))); + } else { + foreach($data as $k=>$d) $result[$k] = filter_var($d,filter_id($filter),array("options"=>"test")); + } + printf("%-20s",$filter); + printf("%-5s",$result[0]); + printf("%-3s",$result[1]); + printf("%-15s",$result[2]); + printf("%-20s",$result[3]); + printf("%-10s",$result[4]); + printf("%-5s",$result[5]); + printf("%-20s",$result[6]); + printf("%-15s",$result[7]); + printf("%-10s\n",$result[8]); +} +?> diff --git a/ext/filter/tests/034.phpt b/ext/filter/tests/034.phpt new file mode 100644 index 0000000..364f902 --- /dev/null +++ b/ext/filter/tests/034.phpt @@ -0,0 +1,33 @@ +--TEST-- +Logical filter: boolean +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$booleans = array( +'1' => true, +'On' => true, +'Off' => true, +'True' => true, +'TrUe' => true, +'oN' => true, + +'0' => false, +'Off' => false, +'False' => false, +'faLsE' => false, +'oFf' => false, + +'' => false +); + +foreach($booleans as $val=>$exp) { + $res =filter_var($val, FILTER_VALIDATE_BOOLEAN); + if ($res !== $exp) { + echo "$val failed,'$exp' expect, '$res' received.\n"; + } +} +echo "Ok."; +?> +--EXPECTF-- +Ok. diff --git a/ext/filter/tests/035.phpt b/ext/filter/tests/035.phpt new file mode 100644 index 0000000..e2d3325 --- /dev/null +++ b/ext/filter/tests/035.phpt @@ -0,0 +1,38 @@ +--TEST-- +GET/POST/REQUEST Test with input_filter +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--POST-- +d=379 +--GET-- +ar[elm1]=1234&ar[elm2]=0660&a=0234 +--FILE-- +<?php +$ret = filter_input(INPUT_GET, 'a', FILTER_VALIDATE_INT); +var_dump($ret); + +$ret = filter_input(INPUT_GET, 'a', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL)); +var_dump($ret); + +$ret = filter_input(INPUT_GET, 'ar', FILTER_VALIDATE_INT, array('flags'=>FILTER_REQUIRE_ARRAY)); +var_dump($ret); + +$ret = filter_input(INPUT_GET, 'ar', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_REQUIRE_ARRAY)); +var_dump($ret); + +?> +--EXPECT-- +bool(false) +int(156) +array(2) { + ["elm1"]=> + int(1234) + ["elm2"]=> + bool(false) +} +array(2) { + ["elm1"]=> + int(1234) + ["elm2"]=> + int(432) +} diff --git a/ext/filter/tests/036.phpt b/ext/filter/tests/036.phpt new file mode 100644 index 0000000..9543266 --- /dev/null +++ b/ext/filter/tests/036.phpt @@ -0,0 +1,39 @@ +--TEST-- +input_get_args() and references +--SKIPIF-- +<?php if (!extension_loaded("filter")) print "skip"; ?> +--FILE-- +<?php + +$var = "1"; + +$data = array(); +$data["test1"] = 1; +$data["test2"] = &$var; + +$args = array(); +$args["test1"] = FILTER_VALIDATE_INT; +$args["test2"] = FILTER_VALIDATE_INT; + +$ret = filter_var_array($data, $args); +var_dump($ret); +var_dump($data); //should be separated, i.e. not reference anymore. looks like we can't change this, or it'd change the original zval instead.. +var_dump($var); //should be still string(1) "1" + +echo "Done\n"; +?> +--EXPECTF-- +array(2) { + ["test1"]=> + int(1) + ["test2"]=> + int(1) +} +array(2) { + ["test1"]=> + int(1) + ["test2"]=> + &string(1) "1" +} +string(1) "1" +Done diff --git a/ext/filter/tests/037.phpt b/ext/filter/tests/037.phpt new file mode 100644 index 0000000..f8497c6 --- /dev/null +++ b/ext/filter/tests/037.phpt @@ -0,0 +1,41 @@ +--TEST-- +GET and data callback tests +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--GET-- +a=1&b=2 +--FILE-- +<?php +function myfunc($val) { + return $val . '_callback'; +} +echo filter_input(INPUT_GET, 'a', FILTER_CALLBACK, array("options"=>'myfunc')); +echo "\n"; +echo filter_input(INPUT_GET, 'b', FILTER_VALIDATE_INT); +echo "\n"; +$data = "data"; + +echo filter_var($data, FILTER_CALLBACK, array("options"=>'myfunc')); +echo "\n"; + +$res = filter_input_array(INPUT_GET, array( + 'a' => array( + 'filter' => FILTER_CALLBACK, + 'options' => 'myfunc' + ), + 'b' => FILTER_VALIDATE_INT + ) + ); + +var_dump($res); +?> +--EXPECT-- +1_callback +2 +data_callback +array(2) { + ["a"]=> + string(10) "1_callback" + ["b"]=> + int(2) +} diff --git a/ext/filter/tests/038.phpt b/ext/filter/tests/038.phpt new file mode 100644 index 0000000..998c80f --- /dev/null +++ b/ext/filter/tests/038.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test scalar, array +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +$var = 12; +$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL)); +var_dump($res); + +$var = array(12); +$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL)); +var_dump($res); + +$var = 12; +$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_FORCE_ARRAY)); +var_dump($res); + + + +$var = 12; +$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_REQUIRE_ARRAY)); +var_dump($res); + +$var = array(12); +$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_REQUIRE_ARRAY)); +var_dump($res); + +$var = array(12); +$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_FORCE_ARRAY|FILTER_REQUIRE_ARRAY)); +var_dump($res); + +$var = array(12); +$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_FORCE_ARRAY)); +var_dump($res); + +?> +--EXPECT-- +int(12) +bool(false) +array(1) { + [0]=> + int(12) +} +bool(false) +array(1) { + [0]=> + int(12) +} +array(1) { + [0]=> + int(12) +} +array(1) { + [0]=> + int(12) +} diff --git a/ext/filter/tests/039.phpt b/ext/filter/tests/039.phpt new file mode 100644 index 0000000..ae883db --- /dev/null +++ b/ext/filter/tests/039.phpt @@ -0,0 +1,117 @@ +--TEST-- +filter_var_array() and different arguments +--SKIPIF-- +<?php if (!extension_loaded("filter")) print "skip"; ?> +--FILE-- +<?php + +echo "-- (1)\n"; +var_dump(filter_var_array(NULL)); +var_dump(filter_var_array(array())); +var_dump(filter_var_array(array(1,"blah"=>"hoho"))); +var_dump(filter_var_array(array(), -1)); +var_dump(filter_var_array(array(), 1000000)); +var_dump(filter_var_array(array(), "")); + +echo "-- (2)\n"; +var_dump(filter_var_array(array(""=>""), -1)); +var_dump(filter_var_array(array(""=>""), 1000000)); +var_dump(filter_var_array(array(""=>""), "")); + +echo "-- (3)\n"; +var_dump(filter_var_array(array("aaa"=>"bbb"), -1)); +var_dump(filter_var_array(array("aaa"=>"bbb"), 1000000)); +var_dump(filter_var_array(array("aaa"=>"bbb"), "")); + +echo "-- (4)\n"; +var_dump(filter_var_array(array(), new stdclass)); +var_dump(filter_var_array(array(), array())); +var_dump(filter_var_array(array(), array("var_name"=>1))); +var_dump(filter_var_array(array(), array("var_name"=>-1))); +var_dump(filter_var_array(array("var_name"=>""), array("var_name"=>-1))); + +echo "-- (5)\n"; +var_dump(filter_var_array(array("var_name"=>""), array("var_name"=>-1, "asdas"=>"asdasd", "qwe"=>"rty", ""=>""))); +var_dump(filter_var_array(array("asdas"=>"text"), array("var_name"=>-1, "asdas"=>"asdasd", "qwe"=>"rty", ""=>""))); + + +$a = array(""=>""); $b = -1; +var_dump(filter_var_array($a, $b)); +var_dump($a, $b); + +$a = array(""=>""); $b = 100000; +var_dump(filter_var_array($a, $b)); +var_dump($a, $b); + +$a = array(""=>""); $b = ""; +var_dump(filter_var_array($a, $b)); +var_dump($a, $b); + +echo "Done\n"; +?> +--EXPECTF-- +-- (1) + +Warning: filter_var_array() expects parameter 1 to be array, null given in %s on line %d +NULL +array(0) { +} +array(2) { + [0]=> + string(1) "1" + ["blah"]=> + string(4) "hoho" +} +bool(false) +bool(false) +bool(false) +-- (2) +bool(false) +bool(false) +bool(false) +-- (3) +bool(false) +bool(false) +bool(false) +-- (4) +bool(false) +array(0) { +} +array(1) { + ["var_name"]=> + NULL +} +array(1) { + ["var_name"]=> + NULL +} +array(1) { + ["var_name"]=> + string(0) "" +} +-- (5) + +Warning: filter_var_array(): Empty keys are not allowed in the definition array in %s on line %d +bool(false) + +Warning: filter_var_array(): Empty keys are not allowed in the definition array in %s on line %d +bool(false) +bool(false) +array(1) { + [""]=> + string(0) "" +} +int(-1) +bool(false) +array(1) { + [""]=> + string(0) "" +} +int(100000) +bool(false) +array(1) { + [""]=> + string(0) "" +} +string(0) "" +Done diff --git a/ext/filter/tests/040.phpt b/ext/filter/tests/040.phpt new file mode 100644 index 0000000..fd39b36 --- /dev/null +++ b/ext/filter/tests/040.phpt @@ -0,0 +1,45 @@ +--TEST-- +filter_has_var() tests +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--GET-- +a=1&b=2&c=0 +--POST-- +ap[]=1&bp=test&cp= +--FILE-- +<?php + +var_dump(filter_has_var()); +var_dump(filter_has_var(INPUT_GET,"")); +var_dump(filter_has_var(INPUT_GET,array())); +var_dump(filter_has_var(INPUT_POST, "ap")); +var_dump(filter_has_var(INPUT_POST, "cp")); +var_dump(filter_has_var(INPUT_GET, "a")); +var_dump(filter_has_var(INPUT_GET, "c")); +var_dump(filter_has_var(INPUT_GET, "abc")); +var_dump(filter_has_var(INPUT_GET, "cc")); +var_dump(filter_has_var(-1, "cc")); +var_dump(filter_has_var(0, "cc")); +var_dump(filter_has_var("", "cc")); + +echo "Done\n"; +?> +--EXPECTF-- +Warning: filter_has_var() expects exactly 2 parameters, 0 given in %s on line %d +bool(false) +bool(false) + +Warning: filter_has_var() expects parameter 2 to be string, array given in %s on line %d +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) + +Warning: filter_has_var() expects parameter 1 to be long, string given in %s on line %d +bool(false) +Done diff --git a/ext/filter/tests/041.phpt b/ext/filter/tests/041.phpt new file mode 100644 index 0000000..0a2e3f0 --- /dev/null +++ b/ext/filter/tests/041.phpt @@ -0,0 +1,34 @@ +--TEST-- +COOKIE multiple cookie test +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +filter.default=stripped +filter.default_flags=0 +--COOKIE-- +abc=dir; def=true; abc=root; xyz="foo bar"; +--FILE-- +<?php +var_dump($_COOKIE); +var_dump(filter_has_var(INPUT_COOKIE, "abc")); +var_dump(filter_input(INPUT_COOKIE, "abc")); +var_dump(filter_input(INPUT_COOKIE, "def")); +var_dump(filter_input(INPUT_COOKIE, "xyz")); +var_dump(filter_has_var(INPUT_COOKIE, "bogus")); +var_dump(filter_input(INPUT_COOKIE, "xyz", FILTER_SANITIZE_SPECIAL_CHARS)); +?> +--EXPECT-- +array(3) { + ["abc"]=> + string(3) "dir" + ["def"]=> + string(4) "true" + ["xyz"]=> + string(17) ""foo bar"" +} +bool(true) +string(3) "dir" +string(4) "true" +string(9) ""foo bar"" +bool(false) +string(17) ""foo bar"" diff --git a/ext/filter/tests/042.phpt b/ext/filter/tests/042.phpt new file mode 100644 index 0000000..08f4dd6 --- /dev/null +++ b/ext/filter/tests/042.phpt @@ -0,0 +1,19 @@ +--TEST-- +Combination of strip & sanitize filters +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$var = 'XYZ< script>alert(/ext/filter+bypass/);< /script>ABC'; +$a = filter_var($var, FILTER_SANITIZE_STRING, array("flags" => FILTER_FLAG_STRIP_LOW)); +echo $a . "\n"; + +$var = 'XYZ< +script>alert(/ext/filter+bypass/);< +/script>ABC'; +$a = filter_var($var, FILTER_SANITIZE_STRING, array("flags" => FILTER_FLAG_STRIP_LOW)); +echo $a . "\n"; +?> +--EXPECT-- +XYZalert(/ext/filter+bypass/);ABC +XYZalert(/ext/filter+bypass/);ABC diff --git a/ext/filter/tests/043.phpt b/ext/filter/tests/043.phpt new file mode 100644 index 0000000..92ac051 --- /dev/null +++ b/ext/filter/tests/043.phpt @@ -0,0 +1,269 @@ +--TEST-- +Character encoding test +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$flags = FILTER_FLAG_ENCODE_AMP|FILTER_FLAG_ENCODE_LOW|FILTER_FLAG_ENCODE_HIGH; + +for ($i = 0; $i < 256; $i++) { + var_dump(filter_var(chr($i), FILTER_SANITIZE_STRING, array("flags" => $flags))); +} +?> +--EXPECT-- +string(4) "�" +string(4) "" +string(4) "" +string(4) "" +string(4) "" +string(4) "" +string(4) "" +string(4) "" +string(4) "" +string(4) "	" +string(5) " " +string(5) "" +string(5) "" +string(5) " " +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(5) "" +string(1) " " +string(1) "!" +string(5) """ +string(1) "#" +string(1) "$" +string(1) "%" +string(5) "&" +string(5) "'" +string(1) "(" +string(1) ")" +string(1) "*" +string(1) "+" +string(1) "," +string(1) "-" +string(1) "." +string(1) "/" +string(1) "0" +string(1) "1" +string(1) "2" +string(1) "3" +string(1) "4" +string(1) "5" +string(1) "6" +string(1) "7" +string(1) "8" +string(1) "9" +string(1) ":" +string(1) ";" +string(0) "" +string(1) "=" +string(1) ">" +string(1) "?" +string(1) "@" +string(1) "A" +string(1) "B" +string(1) "C" +string(1) "D" +string(1) "E" +string(1) "F" +string(1) "G" +string(1) "H" +string(1) "I" +string(1) "J" +string(1) "K" +string(1) "L" +string(1) "M" +string(1) "N" +string(1) "O" +string(1) "P" +string(1) "Q" +string(1) "R" +string(1) "S" +string(1) "T" +string(1) "U" +string(1) "V" +string(1) "W" +string(1) "X" +string(1) "Y" +string(1) "Z" +string(1) "[" +string(1) "\" +string(1) "]" +string(1) "^" +string(1) "_" +string(1) "`" +string(1) "a" +string(1) "b" +string(1) "c" +string(1) "d" +string(1) "e" +string(1) "f" +string(1) "g" +string(1) "h" +string(1) "i" +string(1) "j" +string(1) "k" +string(1) "l" +string(1) "m" +string(1) "n" +string(1) "o" +string(1) "p" +string(1) "q" +string(1) "r" +string(1) "s" +string(1) "t" +string(1) "u" +string(1) "v" +string(1) "w" +string(1) "x" +string(1) "y" +string(1) "z" +string(1) "{" +string(1) "|" +string(1) "}" +string(1) "~" +string(6) "" +string(6) "€" +string(6) "" +string(6) "‚" +string(6) "ƒ" +string(6) "„" +string(6) "…" +string(6) "†" +string(6) "‡" +string(6) "ˆ" +string(6) "‰" +string(6) "Š" +string(6) "‹" +string(6) "Œ" +string(6) "" +string(6) "Ž" +string(6) "" +string(6) "" +string(6) "‘" +string(6) "’" +string(6) "“" +string(6) "”" +string(6) "•" +string(6) "–" +string(6) "—" +string(6) "˜" +string(6) "™" +string(6) "š" +string(6) "›" +string(6) "œ" +string(6) "" +string(6) "ž" +string(6) "Ÿ" +string(6) " " +string(6) "¡" +string(6) "¢" +string(6) "£" +string(6) "¤" +string(6) "¥" +string(6) "¦" +string(6) "§" +string(6) "¨" +string(6) "©" +string(6) "ª" +string(6) "«" +string(6) "¬" +string(6) "­" +string(6) "®" +string(6) "¯" +string(6) "°" +string(6) "±" +string(6) "²" +string(6) "³" +string(6) "´" +string(6) "µ" +string(6) "¶" +string(6) "·" +string(6) "¸" +string(6) "¹" +string(6) "º" +string(6) "»" +string(6) "¼" +string(6) "½" +string(6) "¾" +string(6) "¿" +string(6) "À" +string(6) "Á" +string(6) "Â" +string(6) "Ã" +string(6) "Ä" +string(6) "Å" +string(6) "Æ" +string(6) "Ç" +string(6) "È" +string(6) "É" +string(6) "Ê" +string(6) "Ë" +string(6) "Ì" +string(6) "Í" +string(6) "Î" +string(6) "Ï" +string(6) "Ð" +string(6) "Ñ" +string(6) "Ò" +string(6) "Ó" +string(6) "Ô" +string(6) "Õ" +string(6) "Ö" +string(6) "×" +string(6) "Ø" +string(6) "Ù" +string(6) "Ú" +string(6) "Û" +string(6) "Ü" +string(6) "Ý" +string(6) "Þ" +string(6) "ß" +string(6) "à" +string(6) "á" +string(6) "â" +string(6) "ã" +string(6) "ä" +string(6) "å" +string(6) "æ" +string(6) "ç" +string(6) "è" +string(6) "é" +string(6) "ê" +string(6) "ë" +string(6) "ì" +string(6) "í" +string(6) "î" +string(6) "ï" +string(6) "ð" +string(6) "ñ" +string(6) "ò" +string(6) "ó" +string(6) "ô" +string(6) "õ" +string(6) "ö" +string(6) "÷" +string(6) "ø" +string(6) "ù" +string(6) "ú" +string(6) "û" +string(6) "ü" +string(6) "ý" +string(6) "þ" +string(6) "ÿ" diff --git a/ext/filter/tests/044.phpt b/ext/filter/tests/044.phpt new file mode 100644 index 0000000..ff46893 --- /dev/null +++ b/ext/filter/tests/044.phpt @@ -0,0 +1,25 @@ +--TEST-- +Integer validation with spaces +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +precision=14 +--FILE-- +<?php +$vals = array( +" + ", +" ", +" 123", +" 123.01 ", +); + +foreach ($vals as $var) { + var_dump(filter_var($var, FILTER_VALIDATE_FLOAT)); +} +?> +--EXPECT-- +bool(false) +bool(false) +float(123) +float(123.01) diff --git a/ext/filter/tests/045.phpt b/ext/filter/tests/045.phpt new file mode 100644 index 0000000..ad8f47e --- /dev/null +++ b/ext/filter/tests/045.phpt @@ -0,0 +1,30 @@ +--TEST-- +Options must not be changed by filter_var() +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$a = array("flags"=>(string)FILTER_FLAG_ALLOW_HEX, "options" => array("min_range"=>"0", "max_range"=>"1024")); +$ret = filter_var("0xff", FILTER_VALIDATE_INT, $a); +echo ($ret === 255 && $a["options"]["min_range"] === "0")?"ok\n":"bug\n"; +echo ($ret === 255 && $a["options"]["max_range"] === "1024")?"ok\n":"bug\n"; +echo ($ret === 255 && is_string($a["flags"]) && $a["flags"] == FILTER_FLAG_ALLOW_HEX)?"ok\n":"bug\n"; +$a = (string)FILTER_FLAG_ALLOW_HEX; +$ret = filter_var("0xff", FILTER_VALIDATE_INT, $a); +echo ($ret === 255 && is_string($a) && $a == FILTER_FLAG_ALLOW_HEX)?"ok\n":"bug\n"; +$a = array("test"=>array("filter"=>(string)FILTER_VALIDATE_INT, "flags"=>(string)FILTER_FLAG_ALLOW_HEX)); +$ret = filter_var_array(array("test"=>"0xff"), $a); +echo ($ret["test"] === 255 && is_string($a["test"]["filter"]) && $a["test"]["filter"] == FILTER_VALIDATE_INT)?"ok\n":"bug\n"; +echo ($ret["test"] === 255 && is_string($a["test"]["flags"]) && $a["test"]["flags"] == FILTER_FLAG_ALLOW_HEX)?"ok\n":"bug\n"; +$a = array("test"=>(string)FILTER_VALIDATE_INT); +$ret = filter_var_array(array("test"=>"255"), $a); +echo ($ret["test"] === 255 && is_string($a["test"]) && $a["test"] == FILTER_VALIDATE_INT)?"ok\n":"bug\n"; +?> +--EXPECT-- +ok +ok +ok +ok +ok +ok +ok diff --git a/ext/filter/tests/046.phpt b/ext/filter/tests/046.phpt new file mode 100644 index 0000000..bc45442 --- /dev/null +++ b/ext/filter/tests/046.phpt @@ -0,0 +1,49 @@ +--TEST-- +Integer overflow +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$max = sprintf("%d", PHP_INT_MAX); +switch($max) { +case "2147483647": /* 32-bit systems */ + $min = "-2147483648"; + $overflow = "2147483648"; + $underflow = "-2147483649"; + break; +case "9223372036854775807": /* 64-bit systems */ + $min = "-9223372036854775808"; + $overflow = "9223372036854775808"; + $underflow = "-9223372036854775809"; + break; +default: + die("failed: unknown value for PHP_MAX_INT"); + break; +} + +function test_validation($val, $msg) { + $f = filter_var($val, FILTER_VALIDATE_INT); + echo "$msg filtered: "; var_dump($f); // filtered value (or false) + echo "$msg is_long: "; var_dump(is_long($f)); // test validation + echo "$msg equal: "; var_dump($val == $f); // test equality of result +} + +// PHP_INT_MAX +test_validation($max, "max"); +test_validation($overflow, "overflow"); +test_validation($min, "min"); +test_validation($underflow, "underflow"); +?> +--EXPECTF-- +max filtered: int(%d) +max is_long: bool(true) +max equal: bool(true) +overflow filtered: bool(false) +overflow is_long: bool(false) +overflow equal: bool(false) +min filtered: int(-%d) +min is_long: bool(true) +min equal: bool(true) +underflow filtered: bool(false) +underflow is_long: bool(false) +underflow equal: bool(false) diff --git a/ext/filter/tests/047.phpt b/ext/filter/tests/047.phpt new file mode 100644 index 0000000..cc41eab --- /dev/null +++ b/ext/filter/tests/047.phpt @@ -0,0 +1,37 @@ +--TEST-- +Octal integer overflow +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +function octal_inc($s) { + $len = strlen($s); + while ($len > 0) { + $len--; + if ($s[$len] != '7') { + $s[$len] = $s[$len] + 1; + return $s; + } + $s[$len] = '0'; + } + return '1'.$s; +} + + +$s = sprintf("%o", PHP_INT_MAX); +var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); + +$s = octal_inc($s); +var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); + +$s = sprintf("%o", ~0); +var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); + +$s = octal_inc($s); +var_dump(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/ext/filter/tests/048.phpt b/ext/filter/tests/048.phpt new file mode 100644 index 0000000..92ab690 --- /dev/null +++ b/ext/filter/tests/048.phpt @@ -0,0 +1,41 @@ +--TEST-- +Hex integer overflow +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +function hex_inc($s) { + $len = strlen($s); + while ($len > 0) { + $len--; + if ($s[$len] != 'f') { + if ($s[$len] == '9') { + $s[$len] = 'a'; + } else { + $s[$len] = $s[$len] + 1; + } + return $s; + } + $s[$len] = '0'; + } + return '1'.$s; +} + + +$s = sprintf("%x", PHP_INT_MAX); +var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); + +$s = hex_inc($s); +var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); + +$s = sprintf("%x", ~0); +var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); + +$s = hex_inc($s); +var_dump(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/ext/filter/tests/049.phpt b/ext/filter/tests/049.phpt new file mode 100644 index 0000000..5a9977b --- /dev/null +++ b/ext/filter/tests/049.phpt @@ -0,0 +1,34 @@ +--TEST-- +filter_var() and doubles with thousend separators +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$test = array( + '0' => 0.0, + '12345678900.1234567165' => 12345678900.1234567165, + '1,234,567,890.1234567165' => 1234567890.1234567165, + '-1,234,567,890.1234567165' => -1234567890.1234567165, + '1234,567,890.1234567165' => false, + '1,234,567,89.1234567165' => false, + '1,234,567,8900.1234567165' => false, + '1.234.567.890.1234567165' => false, + '1,234,567,8900.123,456' => false, +); +foreach ($test as $src => $dst) { + $out = filter_var($src, FILTER_VALIDATE_FLOAT, array("flags"=>FILTER_FLAG_ALLOW_THOUSAND)); + if ($dst !== $out) { + if ($out === false) { + echo "$src -> false != $dst\n"; + } elseif ($dst === false) { + echo "$src -> $out != false\n"; + } else { + echo "$src -> $out != $dst\n"; + } + } +} + +echo "Ok\n"; +?> +--EXPECT-- +Ok diff --git a/ext/filter/tests/050.phpt b/ext/filter/tests/050.phpt new file mode 100644 index 0000000..69a269f --- /dev/null +++ b/ext/filter/tests/050.phpt @@ -0,0 +1,29 @@ +--TEST-- +filter_var() and double overflow/underflow +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$test = array( + '1e+308' => 1e+308, + '1e+309' => false, + '1e-323' => 1e-323, + '1e-324' => false, +); +foreach ($test as $src => $dst) { + $out = filter_var($src, FILTER_VALIDATE_FLOAT); + if ($dst !== $out) { + if ($out === false) { + echo "$src -> false != $dst\n"; + } elseif ($dst === false) { + echo "$src -> $out != false\n"; + } else { + echo "$src -> $out != $dst\n"; + } + } +} + +echo "Ok\n"; +?> +--EXPECT-- +Ok diff --git a/ext/filter/tests/051.phpt b/ext/filter/tests/051.phpt new file mode 100644 index 0000000..e34289d --- /dev/null +++ b/ext/filter/tests/051.phpt @@ -0,0 +1,11 @@ +--TEST-- +filter_var() and default values +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$tmp = $default = 321; +var_dump(filter_var("123asd", FILTER_VALIDATE_INT, array("options"=>array("default"=>$default)))); +?> +--EXPECT-- +int(321) diff --git a/ext/filter/tests/052.phpt b/ext/filter/tests/052.phpt new file mode 100644 index 0000000..257613e --- /dev/null +++ b/ext/filter/tests/052.phpt @@ -0,0 +1,73 @@ +--TEST-- +filter_var() / filter_var_array() and passed data integrity +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +function filter_cb($var) +{ + return 1; +} + +$data = array ('bar' => array ('fu<script>bar', 'bar<script>fu') ); +var_dump(filter_var($data, FILTER_SANITIZE_STRING, FILTER_FORCE_ARRAY)); +var_dump($data); +var_dump(filter_var($data, FILTER_CALLBACK, array('options' => 'filter_cb'))); +var_dump($data); +var_dump(filter_var_array($data, array('bar' => array('filter' => FILTER_CALLBACK, 'options' => 'filter_cb')))); +var_dump($data); +--EXPECT-- +array(1) { + ["bar"]=> + array(2) { + [0]=> + string(5) "fubar" + [1]=> + string(5) "barfu" + } +} +array(1) { + ["bar"]=> + array(2) { + [0]=> + string(13) "fu<script>bar" + [1]=> + string(13) "bar<script>fu" + } +} +array(1) { + ["bar"]=> + array(2) { + [0]=> + int(1) + [1]=> + int(1) + } +} +array(1) { + ["bar"]=> + array(2) { + [0]=> + string(13) "fu<script>bar" + [1]=> + string(13) "bar<script>fu" + } +} +array(1) { + ["bar"]=> + array(2) { + [0]=> + int(1) + [1]=> + int(1) + } +} +array(1) { + ["bar"]=> + array(2) { + [0]=> + string(13) "fu<script>bar" + [1]=> + string(13) "bar<script>fu" + } +} diff --git a/ext/filter/tests/053.phpt b/ext/filter/tests/053.phpt new file mode 100644 index 0000000..a179f3e --- /dev/null +++ b/ext/filter/tests/053.phpt @@ -0,0 +1,17 @@ +--TEST-- +filter_var() - using callback +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +function filter_test($str) { return FALSE; } +filter_var('durty/boy', FILTER_CALLBACK, array( + 'options' => 'filter_test', +)); + +print "Done\n"; + +?> +--EXPECTF-- +Done diff --git a/ext/filter/tests/054.phpt b/ext/filter/tests/054.phpt new file mode 100644 index 0000000..c8a5dad --- /dev/null +++ b/ext/filter/tests/054.phpt @@ -0,0 +1,26 @@ +--TEST-- +filter_var_array() - using the add_empty option +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +$data = array('foo' => 123); + +var_dump( + filter_var_array($data, array('foo' => array('filter' => FILTER_DEFAULT), 'bar' => array('filter' => FILTER_DEFAULT)), false), + filter_var_array($data, array('foo' => array('filter' => FILTER_DEFAULT), 'bar' => array('filter' => FILTER_DEFAULT))) +); + +?> +--EXPECT-- +array(1) { + ["foo"]=> + string(3) "123" +} +array(2) { + ["foo"]=> + string(3) "123" + ["bar"]=> + NULL +} diff --git a/ext/filter/tests/PMOPB45.phpt b/ext/filter/tests/PMOPB45.phpt new file mode 100644 index 0000000..532eb21 --- /dev/null +++ b/ext/filter/tests/PMOPB45.phpt @@ -0,0 +1,11 @@ +--TEST-- +PMOPB-45-2007:PHP ext/filter Email Validation Vulnerability +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + $var = "test@example.com\n"; + var_dump(filter_var($var, FILTER_VALIDATE_EMAIL)); +?> +--EXPECT-- +bool(false) diff --git a/ext/filter/tests/bug39846.phpt b/ext/filter/tests/bug39846.phpt new file mode 100644 index 0000000..57407f1 --- /dev/null +++ b/ext/filter/tests/bug39846.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #39846 (ipv4 trailing data validation) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_var('192.168.1.100random-text-here', FILTER_VALIDATE_IP)); +var_dump(filter_var("192.168.1.155\0foo", FILTER_VALIDATE_IP)); +?> +--EXPECT-- +bool(false) +bool(false) diff --git a/ext/filter/tests/bug42718-2.phpt b/ext/filter/tests/bug42718-2.phpt new file mode 100644 index 0000000..ed21068 --- /dev/null +++ b/ext/filter/tests/bug42718-2.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #42718 - 2 (unsafe_raw filter not applied when configured as default filter) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +display_errors=0 +filter.default=unsafe_raw +filter.default_flags= +--GET-- +a=1%00 +--FILE-- +<?php +echo ini_get('filter.default') . "\n"; +echo ini_get('filter.default_flags') . "\n"; +?> +--EXPECT-- +unsafe_raw + diff --git a/ext/filter/tests/bug42718.phpt b/ext/filter/tests/bug42718.phpt new file mode 100644 index 0000000..ba56d39 --- /dev/null +++ b/ext/filter/tests/bug42718.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #42718 (unsafe_raw filter not applied when configured as default filter) +--XFAIL-- +FILTER_UNSAFE_RAW not applied when configured as default filter, even with flags +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +filter.default=unsafe_raw +filter.default_flags=4 +--GET-- +a=1%00 +--FILE-- +<?php +echo ini_get('filter.default') . "\n"; +echo ini_get('filter.default_flags') . "\n"; +var_dump(FILTER_FLAG_STRIP_LOW == 4); +echo addcslashes($_GET['a'],"\0") . "\n"; +?> +--EXPECT-- +unsafe_raw +4 +bool(true) +1 diff --git a/ext/filter/tests/bug44445.phpt b/ext/filter/tests/bug44445.phpt new file mode 100644 index 0000000..36a8641 --- /dev/null +++ b/ext/filter/tests/bug44445.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #44445 (email validator does not handle domains starting/ending with a -) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_var("foo@-foo.com",FILTER_VALIDATE_EMAIL)); +var_dump(filter_var("foo@foo-.com",FILTER_VALIDATE_EMAIL)); +?> +--EXPECT-- +bool(false) +bool(false) diff --git a/ext/filter/tests/bug44779.phpt b/ext/filter/tests/bug44779.phpt new file mode 100644 index 0000000..65a1e09 --- /dev/null +++ b/ext/filter/tests/bug44779.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #44779 (filter returns NULL in CLI when it shouldn't) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_input(INPUT_SERVER, "PHP_SELF")); +?> +--EXPECTF-- +%unicode|string%(%d) "%s" diff --git a/ext/filter/tests/bug46973.phpt b/ext/filter/tests/bug46973.phpt new file mode 100644 index 0000000..eacacf5 --- /dev/null +++ b/ext/filter/tests/bug46973.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #46973 (IPv6 address filter rejects valid address) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var('1fff::a88:85a3::172.31.128.1', FILTER_VALIDATE_IP,FILTER_FLAG_IPV6)); +var_dump(filter_var('3ffe:6a88:85a3:08d3:1319:8a2e:0370:7344', FILTER_VALIDATE_IP,FILTER_FLAG_IPV6)); +var_dump(filter_var('1fff::a88:85a3::172.31.128.1', FILTER_VALIDATE_IP,FILTER_FLAG_IPV6)); + +?> +--EXPECTF-- +bool(false) +string(39) "3ffe:6a88:85a3:08d3:1319:8a2e:0370:7344" +bool(false) diff --git a/ext/filter/tests/bug47435.phpt b/ext/filter/tests/bug47435.phpt new file mode 100644 index 0000000..957a001 --- /dev/null +++ b/ext/filter/tests/bug47435.phpt @@ -0,0 +1,36 @@ +--TEST--
+Bug #47435 (FILTER_FLAG_NO_PRIV_RANGE and FILTER_FLAG_NO_RES_RANGE don't work with ipv6)
+--SKIPIF--
+<?php if (!extension_loaded("filter")) die("skip"); ?>
+--FILE--
+<?php
+var_dump(filter_var("FC00::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
+var_dump(filter_var("FC00::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE));
+var_dump(filter_var("::", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
+var_dump(filter_var("::", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
+var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
+var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
+var_dump(filter_var("fe8:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
+var_dump(filter_var("fe8:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
+var_dump(filter_var("2001:0db8::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
+var_dump(filter_var("2001:0db8::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
+var_dump(filter_var("5f::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
+var_dump(filter_var("5f::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
+var_dump(filter_var("3ff3::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
+var_dump(filter_var("3ff3::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
+?>
+--EXPECT--
+string(7) "FC00::1"
+bool(false)
+string(2) "::"
+bool(false)
+string(3) "::1"
+bool(false)
+string(10) "fe8:5:6::1"
+bool(false)
+string(12) "2001:0db8::1"
+bool(false)
+string(5) "5f::1"
+bool(false)
+string(7) "3ff3::1"
+bool(false)
diff --git a/ext/filter/tests/bug47745.phpt b/ext/filter/tests/bug47745.phpt new file mode 100644 index 0000000..feb0c2b --- /dev/null +++ b/ext/filter/tests/bug47745.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #47745 (FILTER_VALIDATE_INT doesn't allow minimum integer) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$s = (string)(-PHP_INT_MAX-1); +var_dump(intval($s)); +var_dump(filter_var($s, FILTER_VALIDATE_INT)); +?> +--EXPECTF-- +int(-%d) +int(-%d) diff --git a/ext/filter/tests/bug48762.phpt b/ext/filter/tests/bug48762.phpt new file mode 100644 index 0000000..195a616 --- /dev/null +++ b/ext/filter/tests/bug48762.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #48762 (IPv6 address filter still rejects valid address) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +var_dump(filter_var('0b15:23::3:67.98.234.17', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); +var_dump(filter_var('::67:78b:34.43.43.2', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); + +?> +--EXPECT-- +string(23) "0b15:23::3:67.98.234.17" +string(19) "::67:78b:34.43.43.2" diff --git a/ext/filter/tests/bug49274.phpt b/ext/filter/tests/bug49274.phpt new file mode 100644 index 0000000..c87e6be --- /dev/null +++ b/ext/filter/tests/bug49274.phpt @@ -0,0 +1,10 @@ +--TEST--
+#49274, fatal error when an object does not implement toString
+--SKIPIF--
+<?php if (!extension_loaded("filter")) die("skip"); ?>
+--FILE--
+<?php
+var_dump(filter_var(new stdClass, FILTER_VALIDATE_EMAIL));
+?>
+--EXPECTF--
+bool(false)
diff --git a/ext/filter/tests/bug49510.phpt b/ext/filter/tests/bug49510.phpt new file mode 100644 index 0000000..3f365cc --- /dev/null +++ b/ext/filter/tests/bug49510.phpt @@ -0,0 +1,36 @@ +--TEST-- +#49510 boolean validation fails with FILTER_NULL_ON_FAILURE +--FILE-- +<?php +var_dump(filter_var(false, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var(0, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("0", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("off", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("false", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("no", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); + +var_dump(filter_var(true, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var(1, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("1", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("on", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +var_dump(filter_var("yes", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); + +var_dump(filter_var("invalid", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); +?> +==DONE== +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +NULL +==DONE== diff --git a/ext/filter/tests/bug50158.phpt b/ext/filter/tests/bug50158.phpt new file mode 100644 index 0000000..72c31a7 --- /dev/null +++ b/ext/filter/tests/bug50158.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #50158 (FILTER_VALIDATE_EMAIL fails with valid addresses containing = or ?) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +$email_address = "test=mail@example.com"; +var_dump(filter_var($email_address, FILTER_VALIDATE_EMAIL)); + +$email_address = "test-mail@example.com"; +var_dump(filter_var($email_address, FILTER_VALIDATE_EMAIL)); + +$email_address = "test+mail@example.com"; +var_dump(filter_var($email_address, FILTER_VALIDATE_EMAIL)); + +$email_address = "test?mail@example.com"; +var_dump(filter_var($email_address, FILTER_VALIDATE_EMAIL)); + +?> +--EXPECTF-- +%unicode|string%(21) "test=mail@example.com" +%unicode|string%(21) "test-mail@example.com" +%unicode|string%(21) "test+mail@example.com" +%unicode|string%(21) "test?mail@example.com" diff --git a/ext/filter/tests/bug50632.phpt b/ext/filter/tests/bug50632.phpt new file mode 100644 index 0000000..2f33b91 --- /dev/null +++ b/ext/filter/tests/bug50632.phpt @@ -0,0 +1,11 @@ +--TEST-- +bug 50632, filter_input() does not return default value if the variable does not exist +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$foo = filter_input(INPUT_GET, 'foo', FILTER_VALIDATE_INT, array('flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => 23))); +var_dump($foo); +?> +--EXPECT-- +int(23) diff --git a/ext/filter/tests/bug51192.phpt b/ext/filter/tests/bug51192.phpt new file mode 100644 index 0000000..96c67ea --- /dev/null +++ b/ext/filter/tests/bug51192.phpt @@ -0,0 +1,13 @@ +--TEST-- +bug 51192, FILTER_VALIDATE_URL will invalidate a hostname that includes '-' +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_var('http://example.com/path', FILTER_VALIDATE_URL)); +var_dump(filter_var('http://exa-mple.com/path', FILTER_VALIDATE_URL)); +var_dump(filter_var('http://exa_mple.com/path', FILTER_VALIDATE_URL)); +--EXPECT-- +string(23) "http://example.com/path" +string(24) "http://exa-mple.com/path" +bool(false) diff --git a/ext/filter/tests/bug52209.phpt b/ext/filter/tests/bug52209.phpt new file mode 100644 index 0000000..79db749 --- /dev/null +++ b/ext/filter/tests/bug52209.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #52209 (INPUT_ENV returns NULL for set variables (CLI)) +--SKIPIF-- +<?php +/* This test makes no sense on windows as an empty variable + would never show up in the "set" list. Which means, it's + always undefined in PHP. */ +if(substr(PHP_OS, 0, 3) == "WIN") die("skip Not for Windows"); +if (!extension_loaded("filter") || !empty($_ENV['PWD'])) die("skip"); +?> +--INI-- +variables_order=GPCSE +--FILE-- +<?php + var_dump(filter_input(INPUT_ENV, 'PWD')); +?> +--EXPECTF-- +string(%d) "%s" diff --git a/ext/filter/tests/bug52929.phpt b/ext/filter/tests/bug52929.phpt new file mode 100644 index 0000000..2933295 --- /dev/null +++ b/ext/filter/tests/bug52929.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #52929 (Segfault in filter_var with FILTER_VALIDATE_EMAIL with large amount of data) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_var('valid@email.address', FILTER_VALIDATE_EMAIL)); + +// Beyond the allowable limit for an e-mail address. +var_dump(filter_var('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.zz', FILTER_VALIDATE_EMAIL)); + +// An invalid address likely to crash PHP due to stack exhaustion if it goes to +// the validation regex. +var_dump(filter_var(str_repeat('x', 8000), FILTER_VALIDATE_EMAIL)); +--EXPECT-- +string(19) "valid@email.address" +bool(false) +bool(false) diff --git a/ext/filter/tests/bug53037.phpt b/ext/filter/tests/bug53037.phpt new file mode 100644 index 0000000..4a1e9e3 --- /dev/null +++ b/ext/filter/tests/bug53037.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #53037 (FILTER_FLAG_EMPTY_STRING_NULL is not implemented) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump( + filter_var("", FILTER_DEFAULT), + filter_var("", FILTER_DEFAULT, array('flags' => FILTER_FLAG_EMPTY_STRING_NULL)) +); +?> +--EXPECT-- +string(0) "" +NULL diff --git a/ext/filter/tests/bug53150.phpt b/ext/filter/tests/bug53150.phpt new file mode 100644 index 0000000..4baa4db --- /dev/null +++ b/ext/filter/tests/bug53150.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #53150 (FILTER_FLAG_NO_RES_RANGE is missing some IP ranges) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +var_dump(filter_var('127.0.0.1', FILTER_VALIDATE_IP)); +var_dump(filter_var("::1", FILTER_VALIDATE_IP)); + +var_dump(filter_var('127.0.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var('::1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); + +var_dump(filter_var('128.0.0.1', FILTER_VALIDATE_IP)); +var_dump(filter_var('128.0.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); + +var_dump(filter_var('191.255.0.0', FILTER_VALIDATE_IP)); +var_dump(filter_var('191.255.0.0', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); + +?> +--EXPECT-- +string(9) "127.0.0.1" +string(3) "::1" +bool(false) +bool(false) +string(9) "128.0.0.1" +bool(false) +string(11) "191.255.0.0" +bool(false) diff --git a/ext/filter/tests/bug55478.phpt b/ext/filter/tests/bug55478.phpt new file mode 100644 index 0000000..243d707 --- /dev/null +++ b/ext/filter/tests/bug55478.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #55478 (FILTER_VALIDATE_EMAIL fails with internationalized domain name addresses containing >1 -) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$email_address = "test@xn--example--7za.de"; // "example-รค.de" +var_dump(filter_var($email_address, FILTER_VALIDATE_EMAIL)); +?> +--EXPECT-- +string(24) "test@xn--example--7za.de" diff --git a/ext/filter/tests/bug7586.phpt b/ext/filter/tests/bug7586.phpt new file mode 100644 index 0000000..74e55ff --- /dev/null +++ b/ext/filter/tests/bug7586.phpt @@ -0,0 +1,55 @@ +--TEST-- +input_get_args() filter not reseted between elements +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$data = array( + 'product_id' => 'libgd<script>', + 'component' => '10dhsajkkdhk <do>', + 'versions' => '2.0.33', + 'testscalar' => array('2','23','10','12'), + 'testarray' => '2', +); + +$args = array( + 'product_id' => FILTER_SANITIZE_ENCODED, + 'component' => array('flags' => FILTER_FORCE_ARRAY, + 'options' => array("min_range"=>1, "max_range"=>10) + ), + 'versions' => array( + 'filter' => FILTER_SANITIZE_ENCODED, + 'flags' => FILTER_REQUIRE_SCALAR, + ), + 'doesnotexist' => FILTER_VALIDATE_INT, + 'testscalar' => FILTER_VALIDATE_INT, + 'testarray' => array( + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FORCE_ARRAY, + ) + +); +$out = filter_var_array($data, $args); +var_dump($out); +?> +--EXPECTF-- +array(6) { + ["product_id"]=> + string(17) "libgd%3Cscript%3E" + ["component"]=> + array(1) { + [0]=> + string(17) "%s" + } + ["versions"]=> + string(6) "2.0.33" + ["doesnotexist"]=> + NULL + ["testscalar"]=> + bool(false) + ["testarray"]=> + array(1) { + [0]=> + int(2) + } +} diff --git a/ext/filter/tests/bug7715.phpt b/ext/filter/tests/bug7715.phpt new file mode 100644 index 0000000..4298d50 --- /dev/null +++ b/ext/filter/tests/bug7715.phpt @@ -0,0 +1,33 @@ +--TEST-- +bug 7715, floats value with integer or incomplete input +--INI-- +precision=14 +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$data = array( + '.23', + '-42', + '+42', + '.4', + '-.4', + '1000000000000', + '-1000000000000', + '02.324' +); +foreach ($data as $val) { + $res = filter_var($val, FILTER_VALIDATE_FLOAT); + var_dump($res); +} +echo "\n"; +?> +--EXPECTF-- +float(0.23) +float(-42) +float(42) +float(0.4) +float(-0.4) +float(1000000000000) +float(-1000000000000) +float(2.324) diff --git a/ext/filter/tests/bug7733.phpt b/ext/filter/tests/bug7733.phpt new file mode 100644 index 0000000..ab02123 --- /dev/null +++ b/ext/filter/tests/bug7733.phpt @@ -0,0 +1,29 @@ +--TEST-- +filter_data() Float exponential weird result +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$data = array( + 'E2', + '10E', + '2E-', + 'E-2', + '+E2' + ); +$out = filter_var($data, FILTER_VALIDATE_FLOAT, FILTER_REQUIRE_ARRAY); +var_dump($out); +?> +--EXPECTF-- +array(5) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + bool(false) + [3]=> + bool(false) + [4]=> + bool(false) +} diff --git a/ext/filter/tests/bug8315.phpt b/ext/filter/tests/bug8315.phpt new file mode 100644 index 0000000..094d82f --- /dev/null +++ b/ext/filter/tests/bug8315.phpt @@ -0,0 +1,15 @@ +--TEST-- +bug 8315, NULL values halt the validation +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +$var="3".chr(0)."foo"; +var_dump(filter_var($var, FILTER_VALIDATE_INT)); +$var="3".chr(0)."foo"; +var_dump(filter_var($var, FILTER_VALIDATE_FLOAT)); +?> +--EXPECT-- +bool(false) +bool(false) diff --git a/ext/filter/tests/callback_closure.phpt b/ext/filter/tests/callback_closure.phpt new file mode 100644 index 0000000..e27a31b --- /dev/null +++ b/ext/filter/tests/callback_closure.phpt @@ -0,0 +1,14 @@ +--TEST-- +callback function is a closure +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +$callback = function ($var) { + return $var; +}; +$var = "test"; +var_dump(filter_var($var, FILTER_CALLBACK, array('options'=> $callback))); +?> +--EXPECT-- +string(4) "test" diff --git a/ext/filter/tests/callback_non_modified_var.phpt b/ext/filter/tests/callback_non_modified_var.phpt new file mode 100644 index 0000000..f0d5575 --- /dev/null +++ b/ext/filter/tests/callback_non_modified_var.phpt @@ -0,0 +1,14 @@ +--TEST-- +callback function returns non modified value +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +function callback($var) { + return $var; +} +$var = "test"; +var_dump(filter_var($var, FILTER_CALLBACK, array('options'=>'callback'))); +?> +--EXPECT-- +string(4) "test" diff --git a/ext/filter/tests/filter_data.phpt b/ext/filter/tests/filter_data.phpt new file mode 100644 index 0000000..f83d986 --- /dev/null +++ b/ext/filter/tests/filter_data.phpt @@ -0,0 +1,83 @@ +--TEST-- +Simple filter_var() tests +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--INI-- +precision=14 +--FILE-- +<?php + +/* Integer */ +$data = "-123"; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = "0"; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = "-0"; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = "+0"; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = "123"; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = -123; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = 0; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = -0; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = +0; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = 123; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +$data = ""; var_dump(filter_var($data, FILTER_VALIDATE_INT)); +echo "\n"; + +/* Float */ +$data = "-0.123"; var_dump(filter_var($data, FILTER_VALIDATE_FLOAT)); +$data = "0.00"; var_dump(filter_var($data, FILTER_VALIDATE_FLOAT)); +$data = "1.23"; var_dump(filter_var($data, FILTER_VALIDATE_FLOAT)); +$data = -1.23; var_dump(filter_var($data, FILTER_VALIDATE_FLOAT)); +$data = 0.0; var_dump(filter_var($data, FILTER_VALIDATE_FLOAT)); +$data = 1.23; var_dump(filter_var($data, FILTER_VALIDATE_FLOAT)); +$data = ""; var_dump(filter_var($data, FILTER_VALIDATE_FLOAT)); +echo "\n"; + +/* Boolean */ +$data = "on"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = "off"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = "yes"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = "no"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = "true"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = "false"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = "1"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = "0"; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = 1; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = 0; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = true; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = false; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); +$data = ""; var_dump(filter_var($data, FILTER_VALIDATE_BOOLEAN)); + +?> +--EXPECT-- +int(-123) +int(0) +int(0) +int(0) +int(123) +int(-123) +int(0) +int(0) +int(0) +int(123) +bool(false) + +float(-0.123) +float(0) +float(1.23) +float(-1.23) +float(0) +float(1.23) +bool(false) + +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) |