diff options
Diffstat (limited to 'dev-lang/php/files/4.3.11/php4.3.11-globals_overwrite.patch')
-rw-r--r-- | dev-lang/php/files/4.3.11/php4.3.11-globals_overwrite.patch | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/dev-lang/php/files/4.3.11/php4.3.11-globals_overwrite.patch b/dev-lang/php/files/4.3.11/php4.3.11-globals_overwrite.patch new file mode 100644 index 0000000..d3eb55c --- /dev/null +++ b/dev-lang/php/files/4.3.11/php4.3.11-globals_overwrite.patch @@ -0,0 +1,559 @@ +--- ext/standard/array.c 2004-12-23 17:40:03.000000000 +0100 ++++ ext/standard/array.c 2005-10-31 23:26:23.000000000 +0100 +@@ -22,7 +22,7 @@ + */ + + +-/* $Id: array.c,v 1.199.2.42 2004/12/23 16:40:03 tony2001 Exp $ */ ++/* $Id: array.c,v 1.199.2.44.2.9 2005/10/03 14:05:07 iliaa Exp $ */ + + #include "php.h" + #include "php_ini.h" +@@ -631,7 +640,7 @@ + s = *((Bucket **) b); + + if (f->nKeyLength) { +- Z_STRVAL(key1) = estrndup(f->arKey, f->nKeyLength); ++ Z_STRVAL(key1) = estrndup(f->arKey, f->nKeyLength-1); + Z_STRLEN(key1) = f->nKeyLength-1; + Z_TYPE(key1) = IS_STRING; + } else { +@@ -639,7 +648,7 @@ + Z_TYPE(key1) = IS_LONG; + } + if (s->nKeyLength) { +- Z_STRVAL(key2) = estrndup(s->arKey, s->nKeyLength); ++ Z_STRVAL(key2) = estrndup(s->arKey, s->nKeyLength-1); + Z_STRLEN(key2) = s->nKeyLength-1; + Z_TYPE(key2) = IS_STRING; + } else { +@@ -1243,6 +1252,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; + +@@ -1291,14 +1304,18 @@ + zval **orig_var; + + if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) { +- zval_ptr_dtor(orig_var); +- + SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); + zval_add_ref(entry); + ++ zval_ptr_dtor(orig_var); ++ + *orig_var = *entry; + } else { +- (*entry)->is_ref = 1; ++ if ((*var_array)->refcount > 1) { ++ SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); ++ } else { ++ (*entry)->is_ref = 1; ++ } + zval_add_ref(entry); + zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) entry, sizeof(zval *), NULL); + } +@@ -1818,8 +1835,8 @@ + hashtable and replace it with new one */ + new_hash = php_splice(Z_ARRVAL_P(stack), 0, 0, &args[1], argc-1, NULL); + zend_hash_destroy(Z_ARRVAL_P(stack)); +- efree(Z_ARRVAL_P(stack)); +- Z_ARRVAL_P(stack) = new_hash; ++ *Z_ARRVAL_P(stack) = *new_hash; ++ FREE_HASHTABLE(new_hash); + + /* Clean up and return the number of elements in the stack */ + efree(args); +@@ -1896,8 +1913,8 @@ + + /* Replace input array's hashtable with the new one */ + zend_hash_destroy(Z_ARRVAL_P(array)); +- efree(Z_ARRVAL_P(array)); +- Z_ARRVAL_P(array) = new_hash; ++ *Z_ARRVAL_P(array) = *new_hash; ++ FREE_HASHTABLE(new_hash); + + /* Clean up */ + if (argc == 4) +@@ -2384,8 +2401,8 @@ + + /* Copy the result hash into return value */ + zend_hash_destroy(Z_ARRVAL_P(return_value)); +- efree(Z_ARRVAL_P(return_value)); +- Z_ARRVAL_P(return_value) = new_hash; ++ *Z_ARRVAL_P(return_value) = *new_hash; ++ FREE_HASHTABLE(new_hash); + + /* Clean up */ + efree(pads); +@@ -2483,7 +2500,7 @@ + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry, sizeof(entry), NULL); + break; + case HASH_KEY_IS_STRING: +- new_key=estrndup(string_key,str_key_len); ++ new_key=estrndup(string_key,str_key_len - 1); + if (change_to_upper) + php_strtoupper(new_key, str_key_len - 1); + else +@@ -2609,6 +2626,15 @@ + /* copy the argument array */ + *return_value = **args[0]; + zval_copy_ctor(return_value); ++ if (return_value->value.ht == &EG(symbol_table)) { ++ HashTable *ht; ++ zval *tmp; ++ ++ ALLOC_HASHTABLE(ht); ++ zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0); ++ zend_hash_copy(ht, return_value->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); ++ return_value->value.ht = ht; ++ } + + /* go through the lists and look for common values */ + while (*ptrs[0]) { +@@ -2759,6 +2785,15 @@ + /* copy the argument array */ + *return_value = **args[0]; + zval_copy_ctor(return_value); ++ if (return_value->value.ht == &EG(symbol_table)) { ++ HashTable *ht; ++ zval *tmp; ++ ++ ALLOC_HASHTABLE(ht); ++ zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0); ++ zend_hash_copy(ht, return_value->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); ++ return_value->value.ht = ht; ++ } + + /* go through the lists and look for values of ptr[0] + that are not in the others */ +@@ -3229,8 +3264,11 @@ + efree(callback_name); + + if (ZEND_NUM_ARGS() > 2) { +- convert_to_long_ex(initial); +- result = *initial; ++ ALLOC_ZVAL(result); ++ *result = **initial; ++ zval_copy_ctor(result); ++ convert_to_long(result); ++ INIT_PZVAL(result); + } else { + MAKE_STD_ZVAL(result); + ZVAL_NULL(result); +@@ -3246,6 +3284,7 @@ + if (result) { + *return_value = *result; + zval_copy_ctor(return_value); ++ zval_ptr_dtor(&result); + } + return; + } +@@ -3282,6 +3321,7 @@ + PHP_FUNCTION(array_filter) + { + zval **input, **callback = NULL; ++ zval *array, *func = NULL; + zval **operand; + zval **args[1]; + zval *retval = NULL; +@@ -3300,9 +3340,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; +@@ -3311,16 +3355,16 @@ + } + + array_init(return_value); +- if (zend_hash_num_elements(Z_ARRVAL_PP(input)) == 0) ++ if (zend_hash_num_elements(Z_ARRVAL_P(array)) == 0) + return; + +- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos); +- zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&operand, &pos) == SUCCESS; +- zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos)) { ++ for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); ++ 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) { + args[0] = operand; +- if (call_user_function_ex(EG(function_table), NULL, *callback, &retval, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && retval) { ++ if (call_user_function_ex(EG(function_table), NULL, func, &retval, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && retval) { + if (!zend_is_true(retval)) { + zval_ptr_dtor(&retval); + continue; +@@ -3334,7 +3378,7 @@ + continue; + + zval_add_ref(operand); +- switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, &num_key, 0, &pos)) { ++ switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos)) { + case HASH_KEY_IS_STRING: + zend_hash_update(Z_ARRVAL_P(return_value), string_key, + string_key_len, operand, sizeof(zval *), NULL); +@@ -3401,6 +3445,7 @@ + efree(array_pos); + return; + } ++ SEPARATE_ZVAL_IF_NOT_REF(pargs[i]); + args[i] = *pargs[i]; + array_len[i] = zend_hash_num_elements(Z_ARRVAL_PP(pargs[i])); + if (array_len[i] > maxlen) { +--- ext/standard/basic_functions.c 2005-01-18 12:01:20.000000000 +0100 ++++ ext/standard/basic_functions.c 2005-10-31 23:29:26.000000000 +0100 +@@ -17,7 +17,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: basic_functions.c,v 1.543.2.47 2005/01/18 11:01:20 sniper Exp $ */ ++/* $Id: basic_functions.c,v 1.543.2.51.2.3 2005/09/29 16:31:48 iliaa Exp $ */ + + #include "php.h" + #include "php_streams.h" +@@ -42,18 +42,7 @@ + #include <time.h> + #include <stdio.h> + +-#ifndef NETWARE + #include <netdb.h> +-#else +-/*#include "netware/env.h"*/ /* Temporary */ +-#ifdef NEW_LIBC /* Same headers hold good for Winsock and Berkeley sockets */ +-#include <netinet/in.h> +-/*#include <arpa/inet.h>*/ +-#include <netdb.h> +-#else +-#include <sys/socket.h> +-#endif +-#endif + + #if HAVE_ARPA_INET_H + # include <arpa/inet.h> +@@ -813,8 +802,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) +@@ -944,6 +933,13 @@ + static void php_putenv_destructor(putenv_entry *pe) + { + if (pe->previous_value) { ++#if _MSC_VER ++ /* VS.Net has a bug in putenv() when setting a variable that ++ * is already set; if the SetEnvironmentVariable() API call ++ * fails, the Crt will double free() a string. ++ * We try to avoid this by setting our own value first */ ++ SetEnvironmentVariable(pe->key, "bugbug"); ++#endif + putenv(pe->previous_value); + } else { + # if HAVE_UNSETENV +@@ -1232,11 +1228,10 @@ + } + STR_FREE(BG(locale_string)); + +- if (FG(stream_wrappers)) { +- zend_hash_destroy(FG(stream_wrappers)); +- efree(FG(stream_wrappers)); +- FG(stream_wrappers) = NULL; +- } ++ /* ++ FG(stream_wrappers) are destroyed ++ during php_request_shutdown() ++ */ + + PHP_RSHUTDOWN(fsock) (SHUTDOWN_FUNC_ARGS_PASSTHRU); + PHP_RSHUTDOWN(filestat) (SHUTDOWN_FUNC_ARGS_PASSTHRU); +@@ -1430,6 +1425,14 @@ + } + } + ++#if _MSC_VER ++ /* VS.Net has a bug in putenv() when setting a variable that ++ * is already set; if the SetEnvironmentVariable() API call ++ * fails, the Crt will double free() a string. ++ * We try to avoid this by setting our own value first */ ++ SetEnvironmentVariable(pe.key, "bugbug"); ++#endif ++ + if (putenv(pe.putenv_string) == 0) { /* success */ + zend_hash_add(&BG(putenv_ht), pe.key, pe.key_len+1, (void **) &pe, sizeof(putenv_entry), NULL); + #ifdef HAVE_TZSET +@@ -2089,17 +2092,21 @@ + static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC) + { + zval retval; ++ char *function_name = NULL; + +- if (call_user_function( EG(function_table), NULL, +- shutdown_function_entry->arguments[0], +- &retval, +- shutdown_function_entry->arg_count - 1, +- shutdown_function_entry->arguments + 1 +- TSRMLS_CC ) == SUCCESS ) { ++ if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { ++ php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); ++ } else if (call_user_function(EG(function_table), NULL, ++ shutdown_function_entry->arguments[0], ++ &retval, ++ shutdown_function_entry->arg_count - 1, ++ shutdown_function_entry->arguments + 1 ++ TSRMLS_CC ) == SUCCESS) ++ { + zval_dtor(&retval); +- +- } else { +- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0])); ++ } ++ if (function_name) { ++ efree(function_name); + } + return 0; + } +@@ -2192,6 +2199,7 @@ + PHP_FUNCTION(register_shutdown_function) + { + php_shutdown_function_entry shutdown_function_entry; ++ char *function_name = NULL; + int i; + + shutdown_function_entry.arg_count = ZEND_NUM_ARGS(); +@@ -2200,26 +2208,31 @@ + WRONG_PARAM_COUNT; + } + +- shutdown_function_entry.arguments = (pval **) safe_emalloc(sizeof(pval *), shutdown_function_entry.arg_count, 0); ++ shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); + + if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { + RETURN_FALSE; + } + +- /* Prevent entering of anything but arrays/strings */ +- if (Z_TYPE_P(shutdown_function_entry.arguments[0]) != IS_ARRAY) { +- convert_to_string(shutdown_function_entry.arguments[0]); +- } +- +- if (!BG(user_shutdown_function_names)) { +- ALLOC_HASHTABLE(BG(user_shutdown_function_names)); +- zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0); +- } ++ /* Prevent entering of anything but valid callback (syntax check only!) */ ++ if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", function_name); ++ efree(shutdown_function_entry.arguments); ++ RETVAL_FALSE; ++ } else { ++ if (!BG(user_shutdown_function_names)) { ++ ALLOC_HASHTABLE(BG(user_shutdown_function_names)); ++ zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0); ++ } + +- for (i = 0; i < shutdown_function_entry.arg_count; i++) { +- shutdown_function_entry.arguments[i]->refcount++; ++ for (i = 0; i < shutdown_function_entry.arg_count; i++) { ++ shutdown_function_entry.arguments[i]->refcount++; ++ } ++ zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL); ++ } ++ if (function_name) { ++ efree(function_name); + } +- zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL); + } + /* }}} */ + +@@ -3014,11 +3027,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-01-20 18:57:41.000000000 +0100 ++++ ext/standard/string.c 2005-10-31 23:34:37.000000000 +0100 +@@ -18,7 +18,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: string.c,v 1.333.2.48 2005/01/20 17:57:41 iliaa Exp $ */ ++/* $Id: string.c,v 1.333.2.52.2.1 2005/09/28 22:34:04 iliaa Exp $ */ + + /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ + +@@ -1317,8 +1317,6 @@ + if (!Z_STRLEN_PP(needle)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); + efree(haystack_orig); +- zval_ptr_dtor(haystack); +- zval_ptr_dtor(needle); + RETURN_FALSE; + } + +@@ -1339,8 +1337,6 @@ + RETVAL_FALSE; + } + +- zval_ptr_dtor(haystack); +- zval_ptr_dtor(needle); + efree(haystack_orig); + } + /* }}} */ +@@ -1576,7 +1572,13 @@ + } + + if (chunklen > Z_STRLEN_PP(p_str)) { +- RETURN_STRINGL(Z_STRVAL_PP(p_str), Z_STRLEN_PP(p_str), 1); ++ /* to maintain BC, we must return original string + ending */ ++ result_len = endlen + Z_STRLEN_PP(p_str); ++ result = emalloc(result_len + 1); ++ memcpy(result, Z_STRVAL_PP(p_str), Z_STRLEN_PP(p_str)); ++ memcpy(result + Z_STRLEN_PP(p_str), end, endlen); ++ result[result_len] = '\0'; ++ RETURN_STRINGL(result, result_len, 0); + } + + if (!Z_STRLEN_PP(p_str)) { +@@ -3169,7 +3179,6 @@ + zval *sarg; + char *res = NULL; + int argCount; +- int old_rg; + + argCount = ARG_COUNT(ht); + if (argCount < 1 || argCount > 2 || zend_get_parameters_ex(argCount, &arg, &arrayArg) == FAILURE) { +@@ -3182,19 +3191,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 2004-10-18 17:08:46.000000000 +0200 ++++ main/php_variables.c 2005-10-31 23:39:38.000000000 +0100 +@@ -16,7 +16,7 @@ + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ +-/* $Id: php_variables.c,v 1.45.2.8 2004/10/18 15:08:46 tony2001 Exp $ */ ++/* $Id: php_variables.c,v 1.45.2.13.2.4 2005/10/02 11:33:27 rrichards Exp $ */ + + #include <stdio.h> + #include "php.h" +@@ -73,6 +73,10 @@ + symtable1 = Z_ARRVAL_P(track_vars_array); + } else if (PG(register_globals)) { + symtable1 = EG(active_symbol_table); ++ /* GLOBALS hijack attempt, reject parameter */ ++ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) { ++ return; ++ } + } + if (!symtable1) { + /* Nothing to do */ +@@ -99,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) { +@@ -182,11 +193,25 @@ + if (!index) { + zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } else { ++ zval **tmp; ++ + if (PG(magic_quotes_gpc) && (index!=var)) { + char *escaped_index = php_addslashes(index, index_len, &index_len, 0 TSRMLS_CC); ++ ++ if (PG(http_globals)[TRACK_VARS_COOKIE] && symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) && ++ zend_hash_find(symtable1, escaped_index, index_len+1, (void **) &tmp) != FAILURE) { ++ efree(escaped_index); ++ break; ++ } ++ + zend_hash_update(symtable1, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + efree(escaped_index); + } else { ++ if (PG(http_globals)[TRACK_VARS_COOKIE] && symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) && ++ zend_hash_find(symtable1, index, index_len+1, (void **) &tmp) != FAILURE) { ++ break; ++ } ++ + zend_hash_update(symtable1, index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } + } |