summaryrefslogtreecommitdiff
path: root/ext/filter/filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/filter/filter.c')
-rw-r--r--ext/filter/filter.c125
1 files changed, 97 insertions, 28 deletions
diff --git a/ext/filter/filter.c b/ext/filter/filter.c
index 9ef94a2ac..ba6367d5c 100644
--- a/ext/filter/filter.c
+++ b/ext/filter/filter.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 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 |
@@ -19,7 +19,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: filter.c,v 1.52.2.25 2006/10/17 15:26:14 iliaa Exp $ */
+/* $Id: filter.c,v 1.52.2.39 2007/04/04 20:50:26 pajoye Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -104,7 +104,7 @@ zend_module_entry filter_module_entry = {
NULL,
PHP_RSHUTDOWN(filter),
PHP_MINFO(filter),
- "0.9.5-dev",
+ "0.11.0",
STANDARD_MODULE_PROPERTIES
};
/* }}} */
@@ -123,7 +123,7 @@ static PHP_INI_MH(UpdateDefaultFilter) /* {{{ */
return SUCCESS;
}
}
- /* Fallback to "string" filter */
+ /* Fallback to the default filter */
IF_G(default_filter) = FILTER_DEFAULT;
return SUCCESS;
}
@@ -170,9 +170,9 @@ PHP_MINIT_FUNCTION(filter)
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_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_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);
@@ -274,8 +274,8 @@ PHP_RSHUTDOWN_FUNCTION(filter)
PHP_MINFO_FUNCTION(filter)
{
php_info_print_table_start();
- php_info_print_table_header( 2, "Input Validation and Filtering", "enabled" );
- php_info_print_table_row( 2, "Revision", "$Revision: 1.52.2.25 $");
+ php_info_print_table_row( 2, "Input Validation and Filtering", "enabled" );
+ php_info_print_table_row( 2, "Revision", "$Revision: 1.52.2.39 $");
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
@@ -320,6 +320,20 @@ static void php_zval_filter(zval **value, long filter, long flags, zval *options
convert_to_string(*value);
filter_func.function(*value, flags, options, charset TSRMLS_CC);
+
+ if (
+ options &&
+ ((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) {
+ **value = **tmp;
+ zval_copy_ctor(*value);
+ INIT_PZVAL(*value);
+ }
+ }
}
/* }}} */
@@ -357,6 +371,16 @@ static unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int
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) {
/* Make a copy of the variable name, as php_register_variable_ex seems to
* modify it */
@@ -382,8 +406,9 @@ static unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int
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 if (PG(magic_quotes_gpc)) {
+ } else if (PG(magic_quotes_gpc) && !retval) { /* for PARSE_STRING php_register_variable_safe() will do the addslashes() */
Z_STRVAL(new_var) = php_addslashes(*val, Z_STRLEN(new_var), &Z_STRLEN(new_var), 0 TSRMLS_CC);
} else {
Z_STRVAL(new_var) = estrndup(*val, val_len);
@@ -494,7 +519,6 @@ PHP_FUNCTION(filter_has_var)
long arg;
char *var;
int var_len;
- zval **tmp;
zval *array_ptr = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
@@ -503,7 +527,7 @@ PHP_FUNCTION(filter_has_var)
array_ptr = php_filter_get_storage(arg TSRMLS_CC);
- if (array_ptr && HASH_OF(array_ptr) && zend_hash_find(HASH_OF(array_ptr), var, var_len + 1, (void **)&tmp) == SUCCESS) {
+ if (array_ptr && HASH_OF(array_ptr) && zend_hash_exists(HASH_OF(array_ptr), var, var_len + 1)) {
RETURN_TRUE;
}
@@ -518,22 +542,27 @@ static void php_filter_call(zval **filtered, long filter, zval **filter_args, co
char *charset = NULL;
if (filter_args && Z_TYPE_PP(filter_args) != IS_ARRAY) {
- convert_to_long_ex(filter_args);
+ 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 = Z_LVAL_PP(filter_args);
+ filter_flags = lval;
+
+ if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
+ filter_flags |= FILTER_REQUIRE_SCALAR;
+ }
} else {
- filter = Z_LVAL_PP(filter_args);
+ filter = lval;
}
} else if (filter_args) {
if (zend_hash_find(HASH_OF(*filter_args), "filter", sizeof("filter"), (void **)&option) == SUCCESS) {
- convert_to_long(*option);
- filter = Z_LVAL_PP(option);
+ PHP_FILTER_GET_LONG_OPT(option, filter);
}
if (zend_hash_find(HASH_OF(*filter_args), "flags", sizeof("flags"), (void **)&option) == SUCCESS) {
- convert_to_long(*option);
- filter_flags = Z_LVAL_PP(option);
+ PHP_FILTER_GET_LONG_OPT(option, filter_flags);
if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
filter_flags |= FILTER_REQUIRE_SCALAR;
@@ -607,12 +636,16 @@ static void php_filter_array_handler(zval *input, zval **op, zval *return_value
zval **tmp, **arg_elm;
if (!op) {
- SEPARATE_ZVAL(&input);
+ zval_dtor(return_value);
*return_value = *input;
+ zval_copy_ctor(return_value);
+ INIT_PZVAL(return_value);
php_filter_call(&return_value, FILTER_DEFAULT, NULL, 0, FILTER_REQUIRE_ARRAY TSRMLS_CC);
} else if (Z_TYPE_PP(op) == IS_LONG) {
- SEPARATE_ZVAL(&input);
+ zval_dtor(return_value);
*return_value = *input;
+ zval_copy_ctor(return_value);
+ INIT_PZVAL(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);
@@ -620,13 +653,18 @@ static void php_filter_array_handler(zval *input, zval **op, zval *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))
+ 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.");
+ 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) {
add_assoc_null_ex(return_value, arg_key, arg_key_len);
} else {
@@ -662,17 +700,29 @@ PHP_FUNCTION(filter_input)
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;
+ 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) {
- convert_to_long(*option);
- filter_flags = Z_LVAL_PP(option);
+ PHP_FILTER_GET_LONG_OPT(option, filter_flags);
+ } else 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
+ ) {
+ *return_value = **def;
+ zval_copy_ctor(return_value);
+ INIT_PZVAL(return_value);
+ return;
}
}
if (filter_flags & FILTER_NULL_ON_FAILURE) {
@@ -684,6 +734,7 @@ PHP_FUNCTION(filter_input)
*return_value = **tmp;
zval_copy_ctor(return_value); /* Watch out for empty strings */
+ INIT_PZVAL(return_value);
php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC);
}
@@ -701,8 +752,13 @@ PHP_FUNCTION(filter_var)
return;
}
+ if (!PHP_FILTER_ID_EXISTS(filter)) {
+ RETURN_FALSE;
+ }
+
*return_value = *data;
zval_copy_ctor(data);
+ INIT_PZVAL(return_value);
php_filter_call(&return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR TSRMLS_CC);
}
@@ -720,6 +776,13 @@ PHP_FUNCTION(filter_input_array)
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)) {
@@ -729,8 +792,7 @@ PHP_FUNCTION(filter_input_array)
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) {
- convert_to_long(*option);
- filter_flags = Z_LVAL_PP(option);
+ PHP_FILTER_GET_LONG_OPT(option, filter_flags);
}
}
if (filter_flags & FILTER_NULL_ON_FAILURE) {
@@ -755,6 +817,13 @@ PHP_FUNCTION(filter_var_array)
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 TSRMLS_CC);
}
/* }}} */
@@ -766,7 +835,7 @@ PHP_FUNCTION(filter_list)
int i, size = sizeof(filter_list) / sizeof(filter_list_entry);
if (ZEND_NUM_ARGS()) {
- WRONG_PARAM_COUNT;
+ WRONG_PARAM_COUNT;
}
array_init(return_value);