summaryrefslogtreecommitdiff
path: root/ext/filter
diff options
context:
space:
mode:
Diffstat (limited to 'ext/filter')
-rw-r--r--ext/filter/CREDITS2
-rw-r--r--ext/filter/callback_filter.c63
-rw-r--r--ext/filter/config.m447
-rw-r--r--ext/filter/config.w329
-rw-r--r--ext/filter/docs/filter.txt331
-rw-r--r--ext/filter/docs/input_get_args.php41
-rw-r--r--ext/filter/filter.c931
-rw-r--r--ext/filter/filter_private.h139
-rw-r--r--ext/filter/logical_filters.c794
-rw-r--r--ext/filter/php_filter.h103
-rw-r--r--ext/filter/sanitizing_filters.c389
-rw-r--r--ext/filter/tests/001.phpt8
-rw-r--r--ext/filter/tests/002.phpt11
-rw-r--r--ext/filter/tests/003.phpt22
-rw-r--r--ext/filter/tests/004.phpt26
-rw-r--r--ext/filter/tests/005.phpt23
-rw-r--r--ext/filter/tests/006.phpt12
-rw-r--r--ext/filter/tests/007.phpt64
-rw-r--r--ext/filter/tests/008.phpt57
-rw-r--r--ext/filter/tests/009.phpt32
-rw-r--r--ext/filter/tests/010.phpt64
-rw-r--r--ext/filter/tests/011.phpt54
-rw-r--r--ext/filter/tests/012.phpt18
-rw-r--r--ext/filter/tests/013.phpt74
-rw-r--r--ext/filter/tests/014.phpt70
-rw-r--r--ext/filter/tests/015.phpt89
-rw-r--r--ext/filter/tests/016.phpt46
-rw-r--r--ext/filter/tests/017.phpt26
-rw-r--r--ext/filter/tests/018.phpt54
-rw-r--r--ext/filter/tests/019.phpt22
-rw-r--r--ext/filter/tests/020.phpt20
-rw-r--r--ext/filter/tests/021.phpt46
-rw-r--r--ext/filter/tests/022.phpt22
-rw-r--r--ext/filter/tests/023.phpt22
-rw-r--r--ext/filter/tests/024.phpt20
-rw-r--r--ext/filter/tests/025.phpt26
-rw-r--r--ext/filter/tests/026.phpt32
-rw-r--r--ext/filter/tests/027.phpt32
-rw-r--r--ext/filter/tests/028.phpt37
-rw-r--r--ext/filter/tests/029.phpt105
-rw-r--r--ext/filter/tests/030.phpt64
-rw-r--r--ext/filter/tests/031.phpt58
-rw-r--r--ext/filter/tests/032.phpt57
-rw-r--r--ext/filter/tests/033.phpt31
-rw-r--r--ext/filter/tests/033_run.inc40
-rw-r--r--ext/filter/tests/034.phpt33
-rw-r--r--ext/filter/tests/035.phpt38
-rw-r--r--ext/filter/tests/036.phpt39
-rw-r--r--ext/filter/tests/037.phpt41
-rw-r--r--ext/filter/tests/038.phpt58
-rw-r--r--ext/filter/tests/039.phpt117
-rw-r--r--ext/filter/tests/040.phpt45
-rw-r--r--ext/filter/tests/041.phpt34
-rw-r--r--ext/filter/tests/042.phpt19
-rw-r--r--ext/filter/tests/043.phpt269
-rw-r--r--ext/filter/tests/044.phpt25
-rw-r--r--ext/filter/tests/045.phpt30
-rw-r--r--ext/filter/tests/046.phpt49
-rw-r--r--ext/filter/tests/047.phpt37
-rw-r--r--ext/filter/tests/048.phpt41
-rw-r--r--ext/filter/tests/049.phpt34
-rw-r--r--ext/filter/tests/050.phpt29
-rw-r--r--ext/filter/tests/051.phpt11
-rw-r--r--ext/filter/tests/052.phpt73
-rw-r--r--ext/filter/tests/053.phpt17
-rw-r--r--ext/filter/tests/054.phpt26
-rw-r--r--ext/filter/tests/PMOPB45.phpt11
-rw-r--r--ext/filter/tests/bug39846.phpt12
-rw-r--r--ext/filter/tests/bug42718-2.phpt18
-rw-r--r--ext/filter/tests/bug42718.phpt23
-rw-r--r--ext/filter/tests/bug44445.phpt12
-rw-r--r--ext/filter/tests/bug44779.phpt10
-rw-r--r--ext/filter/tests/bug46973.phpt16
-rw-r--r--ext/filter/tests/bug47435.phpt36
-rw-r--r--ext/filter/tests/bug47745.phpt13
-rw-r--r--ext/filter/tests/bug48762.phpt14
-rw-r--r--ext/filter/tests/bug49274.phpt10
-rw-r--r--ext/filter/tests/bug49510.phpt36
-rw-r--r--ext/filter/tests/bug50158.phpt25
-rw-r--r--ext/filter/tests/bug50632.phpt11
-rw-r--r--ext/filter/tests/bug51192.phpt13
-rw-r--r--ext/filter/tests/bug52209.phpt18
-rw-r--r--ext/filter/tests/bug52929.phpt18
-rw-r--r--ext/filter/tests/bug53037.phpt14
-rw-r--r--ext/filter/tests/bug53150.phpt28
-rw-r--r--ext/filter/tests/bug55478.phpt11
-rw-r--r--ext/filter/tests/bug7586.phpt55
-rw-r--r--ext/filter/tests/bug7715.phpt33
-rw-r--r--ext/filter/tests/bug7733.phpt29
-rw-r--r--ext/filter/tests/bug8315.phpt15
-rw-r--r--ext/filter/tests/callback_closure.phpt14
-rw-r--r--ext/filter/tests/callback_non_modified_var.phpt14
-rw-r--r--ext/filter/tests/filter_data.phpt83
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 &amp;
+
+ 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 &amp;
+
+ 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&#39;Henry&#60;b&#62;Bold&#60;/b&#62;&#34;quotes&#34;\slash
+O&#39;Henry&#60;b&#62;Bold&#60;/b&#62;&#34;quotes&#34;\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) "&#60;b&#62;test&#60;/b&#62;"
+
+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) "&#60;p&#62;string&#60;/p&#62;"
+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>$%^&#38;*()@a@#$%^&#38;*(.<br>com@#$%^&#38;*("
+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) "!@#$%^&#38;*()&#39;&#34;"
+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) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
+string(23) "&#60;data&#38;sons&#62;"
+string(0) ""
+string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
+string(23) "&#60;data&#38;sons&#62;"
+string(0) ""
+string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
+string(23) "&#60;data&#38;sons&#62;"
+string(0) ""
+string(108) "&#208;&#186;&#208;&#184;&#209;&#128;&#208;&#184;&#208;&#187;&#208;&#187;&#208;&#184;&#209;&#134;&#208;&#176;"
+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&#39;Henry ํ•˜ํผ
+stripped PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc() O&#39;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&#60;&#62;() O&#39;Henry ํ•˜ํผ
+full_special_chars PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc&lt;&gt;() O&#039;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) "&#34;foo bar&#34;"
+}
+bool(true)
+string(3) "dir"
+string(4) "true"
+string(9) ""foo bar""
+bool(false)
+string(17) "&#34;foo bar&#34;"
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) "&#0;"
+string(4) "&#1;"
+string(4) "&#2;"
+string(4) "&#3;"
+string(4) "&#4;"
+string(4) "&#5;"
+string(4) "&#6;"
+string(4) "&#7;"
+string(4) "&#8;"
+string(4) "&#9;"
+string(5) "&#10;"
+string(5) "&#11;"
+string(5) "&#12;"
+string(5) "&#13;"
+string(5) "&#14;"
+string(5) "&#15;"
+string(5) "&#16;"
+string(5) "&#17;"
+string(5) "&#18;"
+string(5) "&#19;"
+string(5) "&#20;"
+string(5) "&#21;"
+string(5) "&#22;"
+string(5) "&#23;"
+string(5) "&#24;"
+string(5) "&#25;"
+string(5) "&#26;"
+string(5) "&#27;"
+string(5) "&#28;"
+string(5) "&#29;"
+string(5) "&#30;"
+string(5) "&#31;"
+string(1) " "
+string(1) "!"
+string(5) "&#34;"
+string(1) "#"
+string(1) "$"
+string(1) "%"
+string(5) "&#38;"
+string(5) "&#39;"
+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) "&#127;"
+string(6) "&#128;"
+string(6) "&#129;"
+string(6) "&#130;"
+string(6) "&#131;"
+string(6) "&#132;"
+string(6) "&#133;"
+string(6) "&#134;"
+string(6) "&#135;"
+string(6) "&#136;"
+string(6) "&#137;"
+string(6) "&#138;"
+string(6) "&#139;"
+string(6) "&#140;"
+string(6) "&#141;"
+string(6) "&#142;"
+string(6) "&#143;"
+string(6) "&#144;"
+string(6) "&#145;"
+string(6) "&#146;"
+string(6) "&#147;"
+string(6) "&#148;"
+string(6) "&#149;"
+string(6) "&#150;"
+string(6) "&#151;"
+string(6) "&#152;"
+string(6) "&#153;"
+string(6) "&#154;"
+string(6) "&#155;"
+string(6) "&#156;"
+string(6) "&#157;"
+string(6) "&#158;"
+string(6) "&#159;"
+string(6) "&#160;"
+string(6) "&#161;"
+string(6) "&#162;"
+string(6) "&#163;"
+string(6) "&#164;"
+string(6) "&#165;"
+string(6) "&#166;"
+string(6) "&#167;"
+string(6) "&#168;"
+string(6) "&#169;"
+string(6) "&#170;"
+string(6) "&#171;"
+string(6) "&#172;"
+string(6) "&#173;"
+string(6) "&#174;"
+string(6) "&#175;"
+string(6) "&#176;"
+string(6) "&#177;"
+string(6) "&#178;"
+string(6) "&#179;"
+string(6) "&#180;"
+string(6) "&#181;"
+string(6) "&#182;"
+string(6) "&#183;"
+string(6) "&#184;"
+string(6) "&#185;"
+string(6) "&#186;"
+string(6) "&#187;"
+string(6) "&#188;"
+string(6) "&#189;"
+string(6) "&#190;"
+string(6) "&#191;"
+string(6) "&#192;"
+string(6) "&#193;"
+string(6) "&#194;"
+string(6) "&#195;"
+string(6) "&#196;"
+string(6) "&#197;"
+string(6) "&#198;"
+string(6) "&#199;"
+string(6) "&#200;"
+string(6) "&#201;"
+string(6) "&#202;"
+string(6) "&#203;"
+string(6) "&#204;"
+string(6) "&#205;"
+string(6) "&#206;"
+string(6) "&#207;"
+string(6) "&#208;"
+string(6) "&#209;"
+string(6) "&#210;"
+string(6) "&#211;"
+string(6) "&#212;"
+string(6) "&#213;"
+string(6) "&#214;"
+string(6) "&#215;"
+string(6) "&#216;"
+string(6) "&#217;"
+string(6) "&#218;"
+string(6) "&#219;"
+string(6) "&#220;"
+string(6) "&#221;"
+string(6) "&#222;"
+string(6) "&#223;"
+string(6) "&#224;"
+string(6) "&#225;"
+string(6) "&#226;"
+string(6) "&#227;"
+string(6) "&#228;"
+string(6) "&#229;"
+string(6) "&#230;"
+string(6) "&#231;"
+string(6) "&#232;"
+string(6) "&#233;"
+string(6) "&#234;"
+string(6) "&#235;"
+string(6) "&#236;"
+string(6) "&#237;"
+string(6) "&#238;"
+string(6) "&#239;"
+string(6) "&#240;"
+string(6) "&#241;"
+string(6) "&#242;"
+string(6) "&#243;"
+string(6) "&#244;"
+string(6) "&#245;"
+string(6) "&#246;"
+string(6) "&#247;"
+string(6) "&#248;"
+string(6) "&#249;"
+string(6) "&#250;"
+string(6) "&#251;"
+string(6) "&#252;"
+string(6) "&#253;"
+string(6) "&#254;"
+string(6) "&#255;"
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)