--- ext/standard/array.c 2005-09-01 14:01:01.000000000 +0200 +++ ext/standard/array.c 2005-11-01 01:15:13.000000000 +0100 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.266.2.25 2005/09/01 12:01:01 dmitry Exp $ */ +/* $Id: array.c,v 1.266.2.29 2005/10/28 09:57:15 dmitry Exp $ */ #include "php.h" #include "php_ini.h" @@ -1050,6 +1050,7 @@ if (recursive && Z_TYPE_PP(args[0]) == IS_ARRAY) { HashTable *thash; + SEPARATE_ZVAL_TO_MAKE_IS_REF(args[0]); thash = HASH_OF(*(args[0])); if (thash == target_hash) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); @@ -1373,6 +1374,10 @@ /* break omitted intentionally */ case EXTR_OVERWRITE: + /* GLOBALS protection */ + if (var_exists && !strcmp(var_name, "GLOBALS")) { + break; + } smart_str_appendl(&final_name, var_name, var_name_len); break; @@ -2487,8 +2492,9 @@ Z_LVAL_PP(tmp)++; } } else if (Z_TYPE_PP(entry) == IS_STRING) { - /* make sure our array does not end up with numeric string keys */ - if (is_numeric_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, NULL, 0) == IS_LONG) { + /* make sure our array does not end up with numeric string keys + * but don't touch those strings that start with 0 */ + if (!(Z_STRLEN_PP(entry) > 1 && Z_STRVAL_PP(entry)[0] == '0') && is_numeric_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, NULL, 0) == IS_LONG) { zval tmp_entry; tmp_entry = **entry; @@ -3975,7 +3981,7 @@ PHP_FUNCTION(array_filter) { zval **input, **callback = NULL; - zval *array; + zval *array, *func = NULL; zval **operand; zval **args[1]; zval *retval = NULL; @@ -3995,10 +4001,13 @@ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array"); return; } + if (callback) { + func = *callback; + } array = *input; if (ZEND_NUM_ARGS() > 1) { - if (!zend_is_callable(*callback, 0, &callback_name)) { + if (!zend_is_callable(func, 0, &callback_name)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument, '%s', should be a valid callback", callback_name); efree(callback_name); return; @@ -4015,14 +4024,14 @@ zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&operand, &pos) == SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos)) { - if (callback) { + if (func) { zend_fcall_info fci; args[0] = operand; fci.size = sizeof(fci); fci.function_table = EG(function_table); - fci.function_name = *callback; + fci.function_name = func; fci.symbol_table = NULL; fci.object_pp = NULL; fci.retval_ptr_ptr = &retval; --- ext/standard/basic_functions.c 2005-08-21 20:36:33.000000000 +0200 +++ ext/standard/basic_functions.c 2005-11-01 01:15:20.000000000 +0100 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.673.2.18 2005/08/21 18:36:33 zeev Exp $ */ +/* $Id: basic_functions.c,v 1.673.2.21 2005/09/29 16:31:20 iliaa Exp $ */ #include "php.h" #include "php_streams.h" @@ -742,8 +743,8 @@ PHP_FE(prev, first_arg_force_ref) PHP_FE(next, first_arg_force_ref) PHP_FE(reset, first_arg_force_ref) - PHP_FE(current, first_arg_force_ref) - PHP_FE(key, first_arg_force_ref) + PHP_FE(current, NULL) + PHP_FE(key, NULL) PHP_FE(min, NULL) PHP_FE(max, NULL) PHP_FE(in_array, NULL) @@ -3076,11 +3077,25 @@ prefix = va_arg(args, char *); prefix_len = va_arg(args, uint); - new_key_len = prefix_len + hash_key->nKeyLength; - new_key = (char *) emalloc(new_key_len); + if (!prefix_len) { + if (!hash_key->nKeyLength) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric key detected - possible security hazard."); + return 0; + } else if (!strcmp(hash_key->arKey, "GLOBALS")) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite."); + return 0; + } + } + + if (hash_key->nKeyLength) { + new_key_len = prefix_len + hash_key->nKeyLength; + new_key = (char *) emalloc(new_key_len); - memcpy(new_key, prefix, prefix_len); - memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength); + memcpy(new_key, prefix, prefix_len); + memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength); + } else { + new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); + } zend_hash_del(&EG(symbol_table), new_key, new_key_len); ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); --- ext/standard/string.c 2005-07-16 13:18:35.000000000 +0200 +++ ext/standard/string.c 2005-11-01 01:15:27.000000000 +0100 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: string.c,v 1.420.2.12 2005/07/16 11:18:35 hyanantha Exp $ */ +/* $Id: string.c,v 1.420.2.13 2005/09/28 22:35:43 iliaa Exp $ */ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ @@ -3809,7 +3809,6 @@ zval *sarg; char *res = NULL; int argCount; - int old_rg; argCount = ZEND_NUM_ARGS(); if (argCount < 1 || argCount > 2 || zend_get_parameters_ex(argCount, &arg, &arrayArg) == FAILURE) { @@ -3822,19 +3821,18 @@ res = estrndup(Z_STRVAL_P(sarg), Z_STRLEN_P(sarg)); } - old_rg = PG(register_globals); if (argCount == 1) { - PG(register_globals) = 1; - sapi_module.treat_data(PARSE_STRING, res, NULL TSRMLS_CC); + zval tmp; + Z_ARRVAL(tmp) = EG(active_symbol_table); + + sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC); } else { - PG(register_globals) = 0; /* Clear out the array that was passed in. */ zval_dtor(*arrayArg); array_init(*arrayArg); sapi_module.treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC); } - PG(register_globals) = old_rg; } /* }}} */ --- main/php_variables.c 2005-09-01 21:15:51.000000000 +0200 +++ main/php_variables.c 2005-11-01 01:16:22.000000000 +0100 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_variables.c,v 1.81.2.12 2005/09/01 19:15:51 iliaa Exp $ */ +/* $Id: php_variables.c,v 1.81.2.13 2005/09/28 22:35:42 iliaa Exp $ */ #include #include "php.h" @@ -103,6 +103,13 @@ zval_dtor(val); return; } + + /* GLOBALS hijack attempt, reject parameter */ + if (symtable1 == EG(active_symbol_table) && !strcmp("GLOBALS", var)) { + zval_dtor(val); + return; + } + /* ensure that we don't have spaces or dots in the variable name (not binary safe) */ for (p=var; *p; p++) { switch(*p) {