andrei          Wed Jun 15 16:51:37 2005 EDT

  Modified files:              
    /php-src/ext/standard       basic_functions.c basic_functions.h array.c 
  Log:
  Fix FCI cache for array_walk and user array compare functions. Bug
  #33286. (Patch from [EMAIL PROTECTED])
  
  
http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.719&r2=1.720&ty=u
Index: php-src/ext/standard/basic_functions.c
diff -u php-src/ext/standard/basic_functions.c:1.719 
php-src/ext/standard/basic_functions.c:1.720
--- php-src/ext/standard/basic_functions.c:1.719        Tue Jun 14 17:32:27 2005
+++ php-src/ext/standard/basic_functions.c      Wed Jun 15 16:51:31 2005
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: basic_functions.c,v 1.719 2005/06/14 21:32:27 derick Exp $ */
+/* $Id: basic_functions.c,v 1.720 2005/06/15 20:51:31 andrei Exp $ */
 
 #include "php.h"
 #include "php_streams.h"
@@ -955,7 +955,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.137&r2=1.138&ty=u
Index: php-src/ext/standard/basic_functions.h
diff -u php-src/ext/standard/basic_functions.h:1.137 
php-src/ext/standard/basic_functions.h:1.138
--- php-src/ext/standard/basic_functions.h:1.137        Sun Apr 10 12:25:11 2005
+++ php-src/ext/standard/basic_functions.h      Wed Jun 15 16:51:33 2005
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: basic_functions.h,v 1.137 2005/04/10 16:25:11 iliaa Exp $ */
+/* $Id: basic_functions.h,v 1.138 2005/06/15 20:51:33 andrei Exp $ */
 
 #ifndef BASIC_FUNCTIONS_H
 #define BASIC_FUNCTIONS_H
@@ -160,7 +160,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;
http://cvs.php.net/diff.php/php-src/ext/standard/array.c?r1=1.300&r2=1.301&ty=u
Index: php-src/ext/standard/array.c
diff -u php-src/ext/standard/array.c:1.300 php-src/ext/standard/array.c:1.301
--- php-src/ext/standard/array.c:1.300  Wed Jun  8 15:54:24 2005
+++ php-src/ext/standard/array.c        Wed Jun 15 16:51:33 2005
@@ -21,7 +21,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: array.c,v 1.300 2005/06/08 19:54:24 dmitry Exp $ */
+/* $Id: array.c,v 1.301 2005/06/15 20:51:33 andrei Exp $ */
 
 #include "php.h"
 #include "php_ini.h"
@@ -610,43 +610,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;
 }
 /* }}} */
@@ -656,29 +679,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;
 }
 /* }}} */
@@ -735,28 +759,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;
 }
 /* }}} */
@@ -1030,6 +1059,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;
@@ -1073,7 +1103,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);
                                }
@@ -1115,7 +1145,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) {
@@ -1152,7 +1181,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) {
@@ -2830,7 +2858,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);
@@ -2844,13 +2873,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;
@@ -3121,7 +3144,8 @@
                pefree(lists[i], hash->persistent);
        }
        
-       BG(user_compare_func_name) = old_compare_func;
+    PHP_ARRAY_CMP_FUNC_RESTORE();
+
        
        efree(ptrs);
        efree(lists);
@@ -3210,7 +3234,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);
        
@@ -3224,13 +3249,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;
@@ -3499,7 +3518,8 @@
                pefree(lists[i], hash->persistent);
        }
 
-       BG(user_compare_func_name) = old_compare_func;                  
+    PHP_ARRAY_CMP_FUNC_RESTORE();
+
        
        efree(ptrs);
        efree(lists);

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to