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

Reply via email to