summaryrefslogtreecommitdiff
path: root/ext/standard/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r--ext/standard/array.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 045b80c28b..1398d45b7e 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -266,10 +266,14 @@ PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
cnt = zend_hash_num_elements(Z_ARRVAL_P(array));
if (mode == COUNT_RECURSIVE) {
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), element) {
- Z_ARRVAL_P(array)->u.v.nApplyCount++;
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(array))) {
+ Z_ARRVAL_P(array)->u.v.nApplyCount++;
+ }
ZVAL_DEREF(element);
cnt += php_count_recursive(element, COUNT_RECURSIVE TSRMLS_CC);
- Z_ARRVAL_P(array)->u.v.nApplyCount--;
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(array))) {
+ Z_ARRVAL_P(array)->u.v.nApplyCount--;
+ }
} ZEND_HASH_FOREACH_END();
}
}
@@ -1435,12 +1439,15 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
return;
}
- Z_ARRVAL_P(entry)->u.v.nApplyCount++;
-
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(entry))) {
+ Z_ARRVAL_P(entry)->u.v.nApplyCount++;
+ }
ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL_P(entry), value_ptr) {
php_compact_var(eg_active_symbol_table, return_value, value_ptr TSRMLS_CC);
} ZEND_HASH_FOREACH_END();
- Z_ARRVAL_P(entry)->u.v.nApplyCount--;
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(entry))) {
+ Z_ARRVAL_P(entry)->u.v.nApplyCount--;
+ }
}
}
/* }}} */
@@ -2207,6 +2214,7 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
zval *dest_zval = dest_entry;
HashTable *thash;
zval tmp;
+ int ret;
ZVAL_DEREF(src_zval);
ZVAL_DEREF(dest_zval);
@@ -2241,18 +2249,16 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
src_zval = &tmp;
}
if (Z_TYPE_P(src_zval) == IS_ARRAY) {
- if (thash) {
+ if (thash && ZEND_HASH_APPLY_PROTECTION(thash)) {
thash->u.v.nApplyCount++;
}
- if (!php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), 1 TSRMLS_CC)) {
- if (thash) {
- thash->u.v.nApplyCount--;
- }
- return 0;
- }
- if (thash) {
+ ret = php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), 1 TSRMLS_CC);
+ if (thash && ZEND_HASH_APPLY_PROTECTION(thash)) {
thash->u.v.nApplyCount--;
}
+ if (!ret) {
+ return 0;
+ }
} else {
if (Z_REFCOUNTED_P(src_entry)) {
Z_ADDREF_P(src_entry);
@@ -2264,7 +2270,7 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
if (Z_REFCOUNTED_P(src_entry)) {
Z_ADDREF_P(src_entry);
}
- zend_hash_update(dest, string_key, src_entry);
+ zend_hash_add_new(dest, string_key, src_entry);
}
} else {
if (Z_REFCOUNTED_P(src_entry)) {
@@ -2297,6 +2303,7 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC
zval *src_entry, *dest_entry, *src_zval, *dest_zval;
zend_string *string_key;
ulong num_key;
+ int ret;
ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) {
src_zval = src_entry;
@@ -2338,17 +2345,26 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC
return 0;
}
SEPARATE_ZVAL(dest_zval);
- Z_ARRVAL_P(dest_zval)->u.v.nApplyCount++;
- Z_ARRVAL_P(src_zval)->u.v.nApplyCount++;
-
- if (!php_array_replace_recursive(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval) TSRMLS_CC)) {
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(dest_zval))) {
+ Z_ARRVAL_P(dest_zval)->u.v.nApplyCount++;
+ }
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(src_zval))) {
+ Z_ARRVAL_P(src_zval)->u.v.nApplyCount++;
+ }
+
+ ret = php_array_replace_recursive(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval) TSRMLS_CC);
+
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(dest_zval))) {
Z_ARRVAL_P(dest_zval)->u.v.nApplyCount--;
+ }
+ if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(src_zval))) {
Z_ARRVAL_P(src_zval)->u.v.nApplyCount--;
+ }
+
+ if (!ret) {
return 0;
}
- Z_ARRVAL_P(dest_zval)->u.v.nApplyCount--;
- Z_ARRVAL_P(src_zval)->u.v.nApplyCount--;
} ZEND_HASH_FOREACH_END();
return 1;
@@ -3850,6 +3866,9 @@ PHP_FUNCTION(array_multisort)
ZVAL_DEREF(arg);
if (Z_TYPE_P(arg) == IS_ARRAY) {
+ if (Z_IMMUTABLE_P(arg)) {
+ zval_copy_ctor(arg);
+ }
/* We see the next array, so we update the sort flags of
* the previous array and reset the sort flags. */
if (i > 0) {