From: Andrei Zmievski Date: Fri, 16 Mar 2001 19:29:23 +0000 (+0000) Subject: @- Fixed all relevant array functions to avoid moving the internal array X-Git-Tag: php-4.0.6RC1~672 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=561cc7438982d63fc0ff3c48eed6953272cf6695;p=php @- Fixed all relevant array functions to avoid moving the internal array @ pointer during operations. (Andrei) --- diff --git a/ext/standard/array.c b/ext/standard/array.c index dee9a57c99..e5c77f7112 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -954,9 +954,11 @@ static int php_array_walk(HashTable *target_hash, zval **userdata) *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 @@ static int php_array_walk(HashTable *target_hash, zval **userdata) 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 @@ static int php_array_walk(HashTable *target_hash, zval **userdata) 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 @@ PHP_FUNCTION(extract) 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 @@ PHP_FUNCTION(extract) 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 @@ PHP_FUNCTION(extract) 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 @@ PHP_FUNCTION(extract) 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 @@ PHP_FUNCTION(extract) /* }}} */ -/* {{{ 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 @@ static void _compact_var(HashTable *eg_active_symbol_table, zval *return_value, } } 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 @@ PHP_FUNCTION(compact) array_init(return_value); - for (i=0; irefcount++; - 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 @@ PHP_FUNCTION(array_slice) break; } pos++; - zend_hash_move_forward(Z_ARRVAL_PP(input)); + zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos); } } /* }}} */ @@ -1807,14 +1806,16 @@ PHPAPI void php_array_merge(HashTable *dest, HashTable *src, int recursive) 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 @@ PHPAPI void php_array_merge(HashTable *dest, HashTable *src, int recursive) break; } - zend_hash_move_forward(src); + zend_hash_move_forward_ex(src, &pos); } } @@ -1897,7 +1898,9 @@ PHP_FUNCTION(array_keys) *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 @@ PHP_FUNCTION(array_keys) 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 @@ PHP_FUNCTION(array_keys) 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 @@ PHP_FUNCTION(array_keys) } } - zend_hash_move_forward(Z_ARRVAL_PP(input)); + zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos); } } /* }}} */ @@ -1957,6 +1960,7 @@ PHP_FUNCTION(array_values) { 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 @@ PHP_FUNCTION(array_values) 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 @@ PHP_FUNCTION(array_count_values) **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 @@ PHP_FUNCTION(array_count_values) /* 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_FUNCTION(array_count_values) 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 @@ PHP_FUNCTION(array_reverse) **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 @@ PHP_FUNCTION(array_reverse) /* 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 @@ PHP_FUNCTION(array_reverse) break; } - zend_hash_move_backwards(Z_ARRVAL_PP(input)); + zend_hash_move_backwards_ex(Z_ARRVAL_PP(input), &pos); } } /* }}} */ @@ -2700,7 +2707,9 @@ PHP_FUNCTION(array_rand) 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 @@ PHP_FUNCTION(array_rand) 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 @@ PHP_FUNCTION(array_rand) /* 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 @@ PHP_FUNCTION(array_sum) 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 @@ PHP_FUNCTION(array_sum) 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 @@ PHP_FUNCTION(array_reduce) 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 @@ PHP_FUNCTION(array_reduce) 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 @@ PHP_FUNCTION(array_reduce) } else result = *operand; - zend_hash_move_forward(Z_ARRVAL_PP(input)); + zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos); } *return_value = *result;