andrei          Fri Mar 16 11:29:23 2001 EDT

  Modified files:              
    /php4/ext/standard  array.c 
  Log:
  @- Fixed all relevant array functions to avoid moving the internal array
  @ pointer during operations. (Andrei)
  
  
Index: php4/ext/standard/array.c
diff -u php4/ext/standard/array.c:1.101 php4/ext/standard/array.c:1.102
--- php4/ext/standard/array.c:1.101     Mon Mar 12 02:14:00 2001
+++ php4/ext/standard/array.c   Fri Mar 16 11:29:23 2001
@@ -21,7 +21,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: array.c,v 1.101 2001/03/12 10:14:00 stas Exp $ */
+/* $Id: array.c,v 1.102 2001/03/16 19:29:23 andrei Exp $ */
 
 #include "php.h"
 #include "php_ini.h"
@@ -954,9 +954,11 @@
                  *retval_ptr,                  /* Return value - unused */
                  *key;                         /* Entry key */
        char  *string_key;
+       ulong  string_key_len;
        ulong  num_key;
+       HashPosition pos;
        CLS_FETCH();
-       BLS_FETCH();
+       ELS_FETCH();
 
        /* Allocate space for key */
        MAKE_STD_ZVAL(key);
@@ -965,22 +967,22 @@
        args[1] = &key;
        args[2] = userdata;
 
-       zend_hash_internal_pointer_reset(target_hash);
+       zend_hash_internal_pointer_reset_ex(target_hash, &pos);
 
        /* Iterate through hash */
-       while(zend_hash_get_current_data(target_hash, (void **)&args[0]) == SUCCESS) {
+       while(zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == 
+SUCCESS) {
                /* Set up the key */
-               if (zend_hash_get_current_key(target_hash, &string_key, &num_key, 1) 
== HASH_KEY_IS_LONG) {
+               if (zend_hash_get_current_key_ex(target_hash, &string_key, 
+&string_key_len, &num_key, 0, &pos) == HASH_KEY_IS_LONG) {
                        Z_TYPE_P(key) = IS_LONG;
                        Z_LVAL_P(key) = num_key;
                } else {
                        Z_TYPE_P(key) = IS_STRING;
                        Z_STRVAL_P(key) = string_key;
-                       Z_STRLEN_P(key) = strlen(string_key);
+                       Z_STRLEN_P(key) = string_key_len-1;
                }
                
                /* Call the userland function */
-               if (call_user_function_ex(CG(function_table), NULL, 
*BG(array_walk_func_name),
+               if (call_user_function_ex(EG(function_table), NULL, 
+*BG(array_walk_func_name),
                                                   &retval_ptr, userdata ? 3 : 2, 
args, 0, NULL) == SUCCESS) {
                
                        zval_ptr_dtor(&retval_ptr);
@@ -988,11 +990,7 @@
                        php_error(E_WARNING,"Unable to call %s() - function does not 
exist",
                                          (*BG(array_walk_func_name))->value.str.val);
 
-               /* Clean up the key */
-               if (zend_hash_get_current_key_type(target_hash) == HASH_KEY_IS_STRING)
-                       efree(Z_STRVAL_P(key));
-               
-               zend_hash_move_forward(target_hash);
+               zend_hash_move_forward_ex(target_hash, &pos);
     }
        efree(key);
        
@@ -1156,6 +1154,7 @@
        char *var_name, *final_name;
        ulong num_key, var_name_len;
        int var_exists, extract_type, key_type, count = 0;
+       HashPosition pos;
 
        switch(ZEND_NUM_ARGS()) {
                case 1:
@@ -1204,9 +1203,9 @@
                return;
        }
                
-       zend_hash_internal_pointer_reset(Z_ARRVAL_PP(var_array));
-       while(zend_hash_get_current_data(Z_ARRVAL_PP(var_array), (void **)&entry) == 
SUCCESS) {
-               key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), 
&var_name, &var_name_len, &num_key, 0, NULL);
+       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos);
+       while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, 
+&pos) == SUCCESS) {
+               key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), 
+&var_name, &var_name_len, &num_key, 0, &pos);
                final_name = NULL;
                var_exists = 0;
 
@@ -1217,7 +1216,7 @@
                        final_name = emalloc(MAX_LENGTH_OF_LONG + Z_STRLEN_PP(prefix) 
+ 2);
                        zend_sprintf(final_name, "%s_%ld", Z_STRVAL_PP(prefix), 
num_key);
                } else {
-                       zend_hash_move_forward(Z_ARRVAL_PP(var_array));
+                       zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos);
                        continue;
                }
                        
@@ -1271,7 +1270,7 @@
                        efree(final_name);
                }
 
-               zend_hash_move_forward(Z_ARRVAL_PP(var_array));
+               zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos);
        }
 
        RETURN_LONG(count);
@@ -1279,8 +1278,7 @@
 /* }}} */
 
 
-/* {{{ void _compact_var(HashTable *eg_active_symbol_table, zval *return_value, zval 
*entry) */
-static void _compact_var(HashTable *eg_active_symbol_table, zval *return_value, zval 
*entry)
+static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_value, 
+zval *entry)
 {
        zval **value_ptr, *value, *data;
        
@@ -1298,17 +1296,17 @@
                }
        }
        else if (Z_TYPE_P(entry) == IS_ARRAY) {
-               zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
+               HashPosition pos;
 
-               while(zend_hash_get_current_data(Z_ARRVAL_P(entry), 
(void**)&value_ptr) == SUCCESS) {
+               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos);
+               while (zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), 
+(void**)&value_ptr, &pos) == SUCCESS) {
                        value = *value_ptr;
 
-                       _compact_var(eg_active_symbol_table, return_value, value);
-                       zend_hash_move_forward(Z_ARRVAL_P(entry));
+                       php_compact_var(eg_active_symbol_table, return_value, value);
+                       zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos);
                }
        }
 }
-/* }}} */
 
 
 /* {{{ proto array compact(mixed var_names [, mixed ...])
@@ -1327,9 +1325,8 @@
 
        array_init(return_value);
        
-       for (i=0; i<ZEND_NUM_ARGS(); i++)
-       {
-               _compact_var(EG(active_symbol_table), return_value, *args[i]);
+       for (i=0; i<ZEND_NUM_ARGS(); i++) {
+               php_compact_var(EG(active_symbol_table), return_value, *args[i]);
        }
        
        efree(args);
@@ -1723,7 +1720,9 @@
                                 argc;                  /* Number of function 
arguments */
                                 
        char            *string_key;
+       ulong            string_key_len;
        ulong            num_key;
+       HashPosition hpos;
        
 
        /* Get the arguments and do error-checking */   
@@ -1771,22 +1770,22 @@
        
        /* Start at the beginning and go until we hit offset */
        pos = 0;
-       zend_hash_internal_pointer_reset(Z_ARRVAL_PP(input));
+       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &hpos);
        while(pos < offset_val &&
-                 zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&entry) == 
SUCCESS) {
+                 zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, 
+&hpos) == SUCCESS) {
                pos++;
-               zend_hash_move_forward(Z_ARRVAL_PP(input));
+               zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos);
        }
        
        /* Copy elements from input array to the one that's returned */
        while(pos < offset_val+length_val &&
-                 zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&entry) == 
SUCCESS) {
+                 zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, 
+&hpos) == SUCCESS) {
                
                (*entry)->refcount++;
 
-               switch (zend_hash_get_current_key(Z_ARRVAL_PP(input), &string_key, 
&num_key, 0)) {
+               switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, 
+&string_key_len, &num_key, 0, &hpos)) {
                        case HASH_KEY_IS_STRING:
-                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, 
strlen(string_key)+1,
+                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, 
+string_key_len,
                                                                 entry, sizeof(zval 
*), NULL);
                                break;
        
@@ -1796,7 +1795,7 @@
                                break;
                }
                pos++;
-               zend_hash_move_forward(Z_ARRVAL_PP(input));
+               zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos);
        }
 }
 /* }}} */
@@ -1807,14 +1806,16 @@
        zval      **src_entry,
                          **dest_entry;
        char       *string_key;
+       ulong           string_key_len;
        ulong           num_key;
+       HashPosition pos;
 
-       zend_hash_internal_pointer_reset(src);
-       while(zend_hash_get_current_data(src, (void **)&src_entry) == SUCCESS) {
-               switch (zend_hash_get_current_key(src, &string_key, &num_key, 0)) {
+       zend_hash_internal_pointer_reset_ex(src, &pos);
+       while(zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == 
+SUCCESS) {
+               switch (zend_hash_get_current_key_ex(src, &string_key, 
+&string_key_len, &num_key, 0, &pos)) {
                        case HASH_KEY_IS_STRING:
                                if (recursive &&
-                                       zend_hash_find(dest, string_key, 
strlen(string_key) + 1,
+                                       zend_hash_find(dest, string_key, 
+string_key_len,
                                                                   (void 
**)&dest_entry) == SUCCESS) {
                                        convert_to_array_ex(dest_entry);
                                        convert_to_array_ex(src_entry);
@@ -1834,7 +1835,7 @@
                                break;
                }
 
-               zend_hash_move_forward(src);
+               zend_hash_move_forward_ex(src, &pos);
        }
 }
 
@@ -1897,7 +1898,9 @@
                                *new_val;               /* New value */
        int                      add_key;               /* Flag to indicate whether a 
key should be added */
        char            *string_key;    /* String key */
+       ulong            string_key_len;
        ulong            num_key;               /* Numeric key */
+       HashPosition pos;
 
        search_value = NULL;
        
@@ -1917,8 +1920,8 @@
        add_key = 1;
        
        /* Go through input array and add keys to the return array */
-       zend_hash_internal_pointer_reset(Z_ARRVAL_PP(input));
-       while(zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&entry) == 
SUCCESS) {
+       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos);
+       while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) 
+== SUCCESS) {
                if (search_value != NULL) {
                is_equal_function(&res, *search_value, *entry);
                        add_key = zval_is_true(&res);
@@ -1927,11 +1930,11 @@
                if (add_key) {  
                        MAKE_STD_ZVAL(new_val);
 
-                       switch (zend_hash_get_current_key(Z_ARRVAL_PP(input), 
&string_key, &num_key, 1)) {
+                       switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), 
+&string_key, &string_key_len, &num_key, 1, &pos)) {
                                case HASH_KEY_IS_STRING:
                                        Z_TYPE_P(new_val) = IS_STRING;
                                        Z_STRVAL_P(new_val) = string_key;
-                                       Z_STRLEN_P(new_val) = strlen(string_key);
+                                       Z_STRLEN_P(new_val) = string_key_len-1;
                                        
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val,
                                                                                       
         sizeof(zval *), NULL);
                                        break;
@@ -1945,7 +1948,7 @@
                        }
                }
 
-               zend_hash_move_forward(Z_ARRVAL_PP(input));
+               zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos);
        }
 }
 /* }}} */
@@ -1957,6 +1960,7 @@
 {
        zval       **input,             /* Input array */
                           **entry;             /* An entry in the input array */
+       HashPosition pos;
        
        /* Get arguments and do error-checking */
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &input) == 
FAILURE) {
@@ -1972,14 +1976,14 @@
        array_init(return_value);
 
        /* Go through input array and add values to the return array */ 
-       zend_hash_internal_pointer_reset(Z_ARRVAL_PP(input));
-       while(zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&entry) == 
SUCCESS) {
+       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos);
+       while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) 
+== SUCCESS) {
                
                (*entry)->refcount++;
                zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry,
                                                                                       
 sizeof(zval *), NULL);
 
-               zend_hash_move_forward(Z_ARRVAL_PP(input));
+               zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos);
        }
 }
 /* }}} */
@@ -1993,6 +1997,7 @@
                           **entry;             /* An entry in the input array */
        zval       **tmp;
        HashTable   *myht;
+       HashPosition pos;
        
        /* Get arguments and do error-checking */
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &input) == FAILURE) {
@@ -2009,8 +2014,8 @@
 
        /* Go through input array and add values to the return array */ 
        myht = Z_ARRVAL_PP(input);
-       zend_hash_internal_pointer_reset(myht);
-       while (zend_hash_get_current_data(myht, (void **)&entry) == SUCCESS) {
+       zend_hash_internal_pointer_reset_ex(myht, &pos);
+       while (zend_hash_get_current_data_ex(myht, (void **)&entry, &pos) == SUCCESS) {
                if (Z_TYPE_PP(entry) == IS_LONG) {
                        if (zend_hash_index_find(Z_ARRVAL_P(return_value), 
                                                                         
Z_LVAL_PP(entry), 
@@ -2040,7 +2045,7 @@
                        php_error(E_WARNING, "Can only count STRING and INTEGER 
values!");
                }
 
-               zend_hash_move_forward(myht);
+               zend_hash_move_forward_ex(myht, &pos);
        }
 }
 /* }}} */
@@ -2054,8 +2059,10 @@
                           **z_preserve_keys, /* Flag: whether to preserve keys */
                           **entry;                       /* An entry in the input 
array */
        char            *string_key;
+       ulong            string_key_len;
        ulong            num_key;
        zend_bool        preserve_keys = 0;
+       HashPosition pos;
        
        /* Get arguments and do error-checking */
        if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 ||
@@ -2076,13 +2083,13 @@
        /* Initialize return array */
        array_init(return_value);
        
-       zend_hash_internal_pointer_end(Z_ARRVAL_PP(input));
-       while(zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&entry) == 
SUCCESS) {
+       zend_hash_internal_pointer_end_ex(Z_ARRVAL_PP(input), &pos);
+       while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) 
+== SUCCESS) {
                (*entry)->refcount++;
                
-               switch (zend_hash_get_current_key(Z_ARRVAL_PP(input), &string_key, 
&num_key, 0)) {
+               switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, 
+&string_key_len, &num_key, 0, &pos)) {
                        case HASH_KEY_IS_STRING:
-                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, 
strlen(string_key)+1,
+                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, 
+string_key_len,
                                                                 entry, sizeof(zval 
*), NULL);
                                break;
 
@@ -2096,7 +2103,7 @@
                                break;
                }
                
-               zend_hash_move_backwards(Z_ARRVAL_PP(input));
+               zend_hash_move_backwards_ex(Z_ARRVAL_PP(input), &pos);
        }
 }
 /* }}} */
@@ -2700,7 +2707,9 @@
        long randval;
        int num_req_val, num_avail, key_type;
        char *string_key;
+       ulong string_key_len;
        ulong num_key;
+       HashPosition pos;
 
        if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 ||
                zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &num_req) == FAILURE) {
@@ -2731,8 +2740,8 @@
                array_init(return_value);
 
        /* We can't use zend_hash_index_find() because the array may have string keys 
or gaps. */
-       zend_hash_internal_pointer_reset(Z_ARRVAL_PP(input));
-       while (num_req_val && (key_type = 
zend_hash_get_current_key(Z_ARRVAL_PP(input), &string_key, &num_key, 0)) != 
HASH_KEY_NON_EXISTANT) {
+       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos);
+       while (num_req_val && (key_type = 
+zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, 
+&num_key, 0, &pos)) != HASH_KEY_NON_EXISTANT) {
 
 #ifdef HAVE_RANDOM
                randval = random();
@@ -2748,21 +2757,21 @@
                        /* If we are returning a single result, just do it. */
                        if (Z_TYPE_P(return_value) != IS_ARRAY) {
                                if (key_type == HASH_KEY_IS_STRING) {
-                                       RETURN_STRING(string_key, 1);
+                                       RETURN_STRINGL(string_key, string_key_len-1, 
+1);
                                } else {
                                        RETURN_LONG(num_key);
                                }
                        } else {
                                /* Append the result to the return value. */
                                if (key_type == HASH_KEY_IS_STRING)
-                                       add_next_index_string(return_value, 
string_key, 1);
+                                       add_next_index_stringl(return_value, 
+string_key, string_key_len-1, 1);
                                else
                                        add_next_index_long(return_value, num_key);
                        }
                        num_req_val--;
                }
                num_avail--;
-               zend_hash_move_forward(Z_ARRVAL_PP(input));
+               zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos);
        }  
 
        if (num_req_val == num_avail) {
@@ -2782,6 +2791,7 @@
        zval **input,
                 **entry;
        int argc = ZEND_NUM_ARGS();
+       HashPosition pos;
        
        if (argc != 1 || zend_get_parameters_ex(argc, &input) == FAILURE) {
                WRONG_PARAM_COUNT;
@@ -2795,9 +2805,9 @@
 
        ZVAL_LONG(return_value, 0);
 
-       for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(input));
-                zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&entry) == 
SUCCESS;
-                zend_hash_move_forward(Z_ARRVAL_PP(input))) {
+       for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos);
+                zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, 
+&pos) == SUCCESS;
+                zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos)) {
                
                if (Z_TYPE_PP(entry) == IS_ARRAY || Z_TYPE_PP(entry) == IS_OBJECT)
                        continue;
@@ -2827,6 +2837,7 @@
        zval *result = NULL;
        zval *retval;
        char *callback_name;
+       HashPosition pos;
 
        if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
                zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &callback, &initial) 
== FAILURE) {
@@ -2857,8 +2868,8 @@
                return;
        }
 
-       zend_hash_internal_pointer_reset(Z_ARRVAL_PP(input));
-       while (zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&operand) == 
SUCCESS) {
+       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos);
+       while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&operand, 
+&pos) == SUCCESS) {
                if (result) {
                        args[0] = &result;
                        args[1] = operand;
@@ -2871,7 +2882,7 @@
                } else
                        result = *operand;
 
-               zend_hash_move_forward(Z_ARRVAL_PP(input));
+               zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos);
        }
        
        *return_value = *result;

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to