diff options
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r-- | ext/standard/array.c | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index 7ee505601e..b7339b433c 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1613,7 +1613,6 @@ static inline void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) } } ZEND_HASH_FOREACH_END(); } else { - ZVAL_DEREF(value); if (Z_TYPE_P(value) == IS_LONG) { ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { if (fast_equal_check_long(value, entry)) { @@ -1765,6 +1764,7 @@ PHP_FUNCTION(extract) zend_ulong num_key; int var_exists, count = 0; int extract_refs = 0; + int exception_thrown = 0; zend_array *symbol_table; zval var_array; @@ -1847,12 +1847,6 @@ PHP_FUNCTION(extract) if (var_exists && ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) { break; } - if (var_exists && ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) { - zend_class_entry *scope = zend_get_executed_scope(); - if (scope && ZSTR_LEN(scope->name) != 0) { - break; - } - } ZVAL_STR_COPY(&final_name, var_name); break; @@ -1893,6 +1887,15 @@ PHP_FUNCTION(extract) if (Z_TYPE(final_name) == IS_STRING && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { zval *orig_var; + + if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) { + if (!exception_thrown) { + exception_thrown = 1; + zend_throw_error(NULL, "Cannot re-assign $this"); + } + zval_dtor(&final_name); + continue; + } if (extract_refs) { ZVAL_MAKE_REF(entry); @@ -2116,7 +2119,7 @@ PHP_FUNCTION(array_fill_keys) #define RANGE_CHECK_LONG_INIT_ARRAY(start, end) do { \ zend_ulong __calc_size = (start - end) / lstep; \ if (__calc_size >= HT_MAX_SIZE - 1) { \ - php_error_docref(NULL, E_WARNING, "The supplied range exceeds the maximum array size: start=%pd end=%pd", end, start); \ + php_error_docref(NULL, E_WARNING, "The supplied range exceeds the maximum array size: start=" ZEND_LONG_FMT " end=" ZEND_LONG_FMT, end, start); \ RETURN_FALSE; \ } \ size = (uint32_t)(__calc_size + 1); \ @@ -2283,7 +2286,7 @@ long_str: Z_TYPE_INFO(tmp) = IS_LONG; if (low > high) { /* Negative steps */ - if (low - high < lstep) { + if ((zend_ulong)(low - high) < lstep) { err = 1; goto err; } @@ -2297,7 +2300,7 @@ long_str: } } ZEND_HASH_FILL_END(); } else if (high > low) { /* Positive steps */ - if (high - low < lstep) { + if ((zend_ulong)(high - low) < lstep) { err = 1; goto err; } @@ -2333,7 +2336,7 @@ static void php_array_data_shuffle(zval *array) /* {{{ */ Bucket *p, temp; HashTable *hash; zend_long rnd_idx; - uint32_t n_left; + zend_long n_left; n_elems = zend_hash_num_elements(Z_ARRVAL_P(array)); @@ -2392,7 +2395,6 @@ static void php_array_data_shuffle(zval *array) /* {{{ */ } } } - HANDLE_BLOCK_INTERRUPTIONS(); hash->nNumUsed = n_elems; hash->nInternalPointer = 0; @@ -2408,7 +2410,6 @@ static void php_array_data_shuffle(zval *array) /* {{{ */ if (!(hash->u.flags & HASH_FLAG_PACKED)) { zend_hash_to_packed(hash); } - HANDLE_UNBLOCK_INTERRUPTIONS(); } /* }}} */ @@ -2428,12 +2429,12 @@ PHP_FUNCTION(shuffle) } /* }}} */ -static void php_splice(HashTable *in_hash, int offset, int length, HashTable *replace, HashTable *removed) /* {{{ */ +static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, HashTable *replace, HashTable *removed) /* {{{ */ { HashTable out_hash; /* Output hashtable */ - int num_in, /* Number of entries in the input hashtable */ - pos; /* Current position in the hashtable */ - uint idx; + zend_long num_in; /* Number of entries in the input hashtable */ + zend_long pos; /* Current position in the hashtable */ + uint32_t idx; Bucket *p; /* Pointer to hash bucket */ zval *entry; /* Hash entry */ uint32_t iter_pos = zend_hash_iterators_lower_pos(in_hash, 0); @@ -2472,7 +2473,7 @@ static void php_splice(HashTable *in_hash, int offset, int length, HashTable *re zend_hash_add_new(&out_hash, p->key, entry); } if (idx == iter_pos) { - if (idx != pos) { + if ((zend_long)idx != pos) { zend_hash_iterators_update(in_hash, idx, pos); } iter_pos = zend_hash_iterators_lower_pos(in_hash, iter_pos + 1); @@ -2542,7 +2543,7 @@ static void php_splice(HashTable *in_hash, int offset, int length, HashTable *re zend_hash_add_new(&out_hash, p->key, entry); } if (idx == iter_pos) { - if (idx != pos) { + if ((zend_long)idx != pos) { zend_hash_iterators_update(in_hash, idx, pos); } iter_pos = zend_hash_iterators_lower_pos(in_hash, iter_pos + 1); @@ -2901,7 +2902,7 @@ PHP_FUNCTION(array_splice) } /* Perform splice */ - php_splice(Z_ARRVAL_P(array), (int)offset, (int)length, repl_array ? Z_ARRVAL_P(repl_array) : NULL, rem_hash); + php_splice(Z_ARRVAL_P(array), offset, length, repl_array ? Z_ARRVAL_P(repl_array) : NULL, rem_hash); } /* }}} */ @@ -3046,7 +3047,7 @@ PHPAPI int php_array_merge_recursive(HashTable *dest, HashTable *src) /* {{{ */ convert_to_array_ex(dest_zval); add_next_index_null(dest_zval); } else if (Z_TYPE_P(dest_zval) == IS_ARRAY) { - if (UNEXPECTED(Z_ARRVAL_P(dest_zval)->nNextFreeElement > Z_ARRVAL_P(dest_zval)->nNumUsed)) { + if (UNEXPECTED(Z_ARRVAL_P(dest_zval)->nNextFreeElement > (zend_long)Z_ARRVAL_P(dest_zval)->nNumUsed)) { Z_ARRVAL_P(dest_zval)->nNextFreeElement = Z_ARRVAL_P(dest_zval)->nNumUsed; } } else { @@ -3099,15 +3100,20 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src) /* {{{ */ zend_string *string_key; ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) { - if (string_key) { - if (Z_REFCOUNTED_P(src_entry)) { + if (Z_REFCOUNTED_P(src_entry)) { + if (UNEXPECTED(Z_ISREF_P(src_entry)) + && UNEXPECTED(Z_REFCOUNT_P(src_entry) == 1)) { + ZVAL_UNREF(src_entry); + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + } else { Z_ADDREF_P(src_entry); } + } + if (string_key) { zend_hash_update(dest, string_key, src_entry); } else { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } zend_hash_next_index_insert_new(dest, src_entry); } } ZEND_HASH_FOREACH_END(); @@ -3234,18 +3240,19 @@ static inline void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETE src = Z_ARRVAL_P(arg); dest = Z_ARRVAL_P(return_value); ZEND_HASH_FOREACH_KEY_VAL(src, idx, string_key, src_entry) { - if (UNEXPECTED(Z_ISREF_P(src_entry) && Z_REFCOUNT_P(src_entry) == 1)) { - src_entry = Z_REFVAL_P(src_entry); - } - if (string_key) { - if (Z_REFCOUNTED_P(src_entry)) { + if (Z_REFCOUNTED_P(src_entry)) { + if (UNEXPECTED(Z_ISREF_P(src_entry) && Z_REFCOUNT_P(src_entry) == 1)) { + src_entry = Z_REFVAL_P(src_entry); + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + } else { Z_ADDREF_P(src_entry); } + } + if (string_key) { zend_hash_add_new(dest, string_key, src_entry); } else { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } zend_hash_index_add_new(dest, idx, src_entry); } } ZEND_HASH_FOREACH_END(); @@ -3274,18 +3281,19 @@ static inline void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETE src = Z_ARRVAL_P(arg); dest = Z_ARRVAL_P(return_value); ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) { - if (UNEXPECTED(Z_ISREF_P(src_entry) && Z_REFCOUNT_P(src_entry) == 1)) { - src_entry = Z_REFVAL_P(src_entry); - } - if (string_key) { - if (Z_REFCOUNTED_P(src_entry)) { + if (Z_REFCOUNTED_P(src_entry)) { + if (UNEXPECTED(Z_ISREF_P(src_entry) && Z_REFCOUNT_P(src_entry) == 1)) { + src_entry = Z_REFVAL_P(src_entry); + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + } else { Z_ADDREF_P(src_entry); } + } + if (string_key) { zend_hash_add_new(dest, string_key, src_entry); } else { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } zend_hash_next_index_insert_new(dest, src_entry); } } ZEND_HASH_FOREACH_END(); @@ -4946,7 +4954,7 @@ PHP_FUNCTION(array_multisort) /* Make sure the arrays are of the same size. */ array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0])); for (i = 0; i < num_arrays; i++) { - if (zend_hash_num_elements(Z_ARRVAL_P(arrays[i])) != array_size) { + if (zend_hash_num_elements(Z_ARRVAL_P(arrays[i])) != (uint32_t)array_size) { php_error_docref(NULL, E_WARNING, "Array sizes are inconsistent"); MULTISORT_ABORT; } @@ -4981,10 +4989,9 @@ PHP_FUNCTION(array_multisort) } /* Do the actual sort magic - bada-bim, bada-boom. */ - zend_qsort(indirect, array_size, sizeof(Bucket *), php_multisort_compare, (swap_func_t)array_bucket_p_sawp); + zend_sort(indirect, array_size, sizeof(Bucket *), php_multisort_compare, (swap_func_t)array_bucket_p_sawp); /* Restructure the arrays based on sorted indirect - this is mostly taken from zend_hash_sort() function. */ - HANDLE_BLOCK_INTERRUPTIONS(); for (i = 0; i < num_arrays; i++) { int repack; @@ -5008,7 +5015,6 @@ PHP_FUNCTION(array_multisort) zend_hash_rehash(hash); } } - HANDLE_UNBLOCK_INTERRUPTIONS(); /* Clean up. */ for (i = 0; i < array_size; i++) { |