zeev Sun Aug 21 14:36:35 2005 EDT Modified files: (Branch: PHP_5_0) /php-src NEWS /php-src/ext/standard array.c basic_functions.c basic_functions.h Log: Backport Mike's patch for user sort functions
http://cvs.php.net/diff.php/php-src/NEWS?r1=1.1760.2.464&r2=1.1760.2.465&ty=u Index: php-src/NEWS diff -u php-src/NEWS:1.1760.2.464 php-src/NEWS:1.1760.2.465 --- php-src/NEWS:1.1760.2.464 Wed Aug 17 07:53:59 2005 +++ php-src/NEWS Sun Aug 21 14:36:32 2005 @@ -1,6 +1,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2005, PHP 5.0.5 +- Fixed various reentrancy bugs in user-sort functions, solves bugs #33286 and + #33295. (Mike Bretz) - Upgraded PCRE library to version 5.0. (Andrei) - Removed php_check_syntax() function which never worked properly. (Ilia) - Added new function mysqli_set_charset(). (Georg) http://cvs.php.net/diff.php/php-src/ext/standard/array.c?r1=1.266.2.23&r2=1.266.2.24&ty=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.266.2.23 php-src/ext/standard/array.c:1.266.2.24 --- php-src/ext/standard/array.c:1.266.2.23 Wed Aug 10 04:23:52 2005 +++ php-src/ext/standard/array.c Sun Aug 21 14:36:33 2005 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.266.2.23 2005/08/10 08:23:52 dmitry Exp $ */ +/* $Id: array.c,v 1.266.2.24 2005/08/21 18:36:33 zeev Exp $ */ #include "php.h" #include "php_ini.h" @@ -578,43 +578,66 @@ } } -/* check is comparison function is valid */ +/* check if comparison function is valid */ #define PHP_ARRAY_CMP_FUNC_CHECK(func_name) \ if (!zend_is_callable(*func_name, 0, NULL)) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid comparison function."); \ + BG(user_compare_fci_cache) = old_user_compare_fci_cache; \ BG(user_compare_func_name) = old_compare_func; \ RETURN_FALSE; \ } \ + /* clear FCI cache otherwise : for example the same or other array with + (partly) the same key values has been sorted with uasort() or + other sorting function the comparison is cached, however the the name + of the function for comparison is not respected. see bug #28739 AND #33295 + + following defines will assist in backup / restore values. + */ + +#define PHP_ARRAY_CMP_FUNC_VARS \ + zval **old_compare_func; \ + zend_fcall_info_cache old_user_compare_fci_cache + +#define PHP_ARRAY_CMP_FUNC_BACKUP() \ + old_compare_func = BG(user_compare_func_name); \ + old_user_compare_fci_cache = BG(user_compare_fci_cache); \ + BG(user_compare_fci_cache) = empty_fcall_info_cache + +#define PHP_ARRAY_CMP_FUNC_RESTORE() \ + BG(user_compare_fci_cache) = old_user_compare_fci_cache; \ + BG(user_compare_func_name) = old_compare_func + + /* {{{ proto bool usort(array array_arg, string cmp_function) Sort an array by values using a user-defined comparison function */ PHP_FUNCTION(usort) { zval **array; - zval **old_compare_func; HashTable *target_hash; + PHP_ARRAY_CMP_FUNC_VARS; + + PHP_ARRAY_CMP_FUNC_BACKUP(); - old_compare_func = BG(user_compare_func_name); - BG(user_compare_fci_cache) = empty_fcall_info_cache; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array, &BG(user_compare_func_name)) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); WRONG_PARAM_COUNT; } target_hash = HASH_OF(*array); if (!target_hash) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name)) if (zend_hash_sort(target_hash, zend_qsort, array_user_compare, 1 TSRMLS_CC) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_TRUE; } /* }}} */ @@ -624,29 +647,30 @@ PHP_FUNCTION(uasort) { zval **array; - zval **old_compare_func; HashTable *target_hash; + PHP_ARRAY_CMP_FUNC_VARS; + + PHP_ARRAY_CMP_FUNC_BACKUP(); - old_compare_func = BG(user_compare_func_name); - BG(user_compare_fci_cache) = empty_fcall_info_cache; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array, &BG(user_compare_func_name)) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); WRONG_PARAM_COUNT; } target_hash = HASH_OF(*array); if (!target_hash) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name)) if (zend_hash_sort(target_hash, zend_qsort, array_user_compare, 0 TSRMLS_CC) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_TRUE; } /* }}} */ @@ -703,28 +727,33 @@ PHP_FUNCTION(uksort) { zval **array; - zval **old_compare_func; HashTable *target_hash; + PHP_ARRAY_CMP_FUNC_VARS; + + + PHP_ARRAY_CMP_FUNC_BACKUP(); - old_compare_func = BG(user_compare_func_name); if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array, &BG(user_compare_func_name)) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); WRONG_PARAM_COUNT; } target_hash = HASH_OF(*array); if (!target_hash) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_FALSE; } PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name)) if (zend_hash_sort(target_hash, zend_qsort, array_user_key_compare, 0 TSRMLS_CC) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_FALSE; } - BG(user_compare_func_name) = old_compare_func; + + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_TRUE; } /* }}} */ @@ -1008,6 +1037,7 @@ uint string_key_len; ulong num_key; HashPosition pos; + zend_fcall_info_cache array_walk_fci_cache = empty_fcall_info_cache; /* Set up known arguments */ args[1] = &key; @@ -1051,7 +1081,7 @@ fci.no_separation = 0; /* Call the userland function */ - if (zend_call_function(&fci, &BG(array_walk_fci_cache) TSRMLS_CC) == SUCCESS) { + if (zend_call_function(&fci, &array_walk_fci_cache TSRMLS_CC) == SUCCESS) { if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } @@ -1094,7 +1124,6 @@ HashTable *target_hash; argc = ZEND_NUM_ARGS(); - BG(array_walk_fci_cache) = empty_fcall_info_cache; old_walk_func_name = BG(array_walk_func_name); if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &array, &BG(array_walk_func_name), &userdata) == FAILURE) { @@ -1131,7 +1160,6 @@ argc = ZEND_NUM_ARGS(); old_walk_func_name = BG(array_walk_func_name); - BG(array_walk_fci_cache) = empty_fcall_info_cache; if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &array, &BG(array_walk_func_name), &userdata) == FAILURE) { @@ -2809,7 +2837,8 @@ Bucket ***lists, **list, ***ptrs, *p; char *callback_name; - zval **old_compare_func; + PHP_ARRAY_CMP_FUNC_VARS; + int (*intersect_key_compare_func)(const void *, const void * TSRMLS_DC); int (*intersect_data_compare_func)(const void *, const void * TSRMLS_DC); @@ -2823,13 +2852,7 @@ WRONG_PARAM_COUNT; } - old_compare_func = BG(user_compare_func_name); - /* clear FCI cache otherwise : for example the same or other array with - (partly) the same key values has been sorted with uasort() or - other sorting function the comparison is cached, however the the name - of the function for comparison is not respected. see bug #28739 - */ - BG(user_compare_fci_cache) = empty_fcall_info_cache; + PHP_ARRAY_CMP_FUNC_BACKUP(); if (behavior == INTERSECT_NORMAL) { intersect_key_compare_func = array_key_compare; @@ -3100,7 +3123,8 @@ pefree(lists[i], hash->persistent); } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + efree(ptrs); efree(lists); @@ -3172,7 +3196,8 @@ Bucket ***lists, **list, ***ptrs, *p; char *callback_name; - zval **old_compare_func; + PHP_ARRAY_CMP_FUNC_VARS; + int (*diff_key_compare_func)(const void *, const void * TSRMLS_DC); int (*diff_data_compare_func)(const void *, const void * TSRMLS_DC); @@ -3186,13 +3211,7 @@ WRONG_PARAM_COUNT; } - old_compare_func = BG(user_compare_func_name); - /* clear FCI cache otherwise : for example the same or other array with - (partly) the same key values has been sorted with uasort() or - other sorting function the comparison is cached, however the the name - of the function for comparison is not respected. see bug #28739 - */ - BG(user_compare_fci_cache) = empty_fcall_info_cache; + PHP_ARRAY_CMP_FUNC_BACKUP(); if (behavior == DIFF_NORMAL) { diff_key_compare_func = array_key_compare; @@ -3450,7 +3469,8 @@ pefree(lists[i], hash->persistent); } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + efree(ptrs); efree(lists); http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.673.2.17&r2=1.673.2.18&ty=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.673.2.17 php-src/ext/standard/basic_functions.c:1.673.2.18 --- php-src/ext/standard/basic_functions.c:1.673.2.17 Mon May 16 04:37:41 2005 +++ php-src/ext/standard/basic_functions.c Sun Aug 21 14:36:33 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.673.2.17 2005/05/16 08:37:41 tony2001 Exp $ */ +/* $Id: basic_functions.c,v 1.673.2.18 2005/08/21 18:36:33 zeev Exp $ */ #include "php.h" #include "php_streams.h" @@ -929,7 +929,6 @@ BG(user_tick_functions) = NULL; BG(user_filter_map) = NULL; BG(user_compare_fci_cache) = empty_fcall_info_cache; - /*BG(array_walk_fci_cache) = empty_fcall_info_cache;*/ zend_hash_init(&BG(sm_protected_env_vars), 5, NULL, NULL, 1); BG(sm_allowed_env_vars) = NULL; http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.h?r1=1.133.2.1&r2=1.133.2.2&ty=u Index: php-src/ext/standard/basic_functions.h diff -u php-src/ext/standard/basic_functions.h:1.133.2.1 php-src/ext/standard/basic_functions.h:1.133.2.2 --- php-src/ext/standard/basic_functions.h:1.133.2.1 Wed Apr 6 10:21:03 2005 +++ php-src/ext/standard/basic_functions.h Sun Aug 21 14:36:34 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.h,v 1.133.2.1 2005/04/06 14:21:03 iliaa Exp $ */ +/* $Id: basic_functions.h,v 1.133.2.2 2005/08/21 18:36:34 zeev Exp $ */ #ifndef BASIC_FUNCTIONS_H #define BASIC_FUNCTIONS_H @@ -153,7 +153,6 @@ ulong strtok_len; char str_ebuf[40]; zval **array_walk_func_name; - zend_fcall_info_cache array_walk_fci_cache; zval **user_compare_func_name; zend_fcall_info_cache user_compare_fci_cache; zend_llist *user_tick_functions;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php