/* Iterate through hash */
do {
- zend_bool was_ref;
/* Retrieve value */
zv = zend_hash_get_current_data_ex(target_hash, &pos);
if (zv == NULL) {
}
}
- was_ref = Z_ISREF_P(zv);
-
/* Ensure the value is a reference. Otherwise the location of the value may be freed. */
ZVAL_MAKE_REF(zv);
HashTable *thash;
zend_fcall_info orig_array_walk_fci;
zend_fcall_info_cache orig_array_walk_fci_cache;
- zval rv;
+ zval ref;
+ ZVAL_COPY_VALUE(&ref, zv);
- SEPARATE_ARRAY(Z_REFVAL_P(zv));
- ZVAL_COPY_VALUE(&rv, Z_REFVAL_P(zv));
- thash = Z_ARRVAL(rv);
+ ZVAL_DEREF(zv);
+ SEPARATE_ARRAY(zv);
+ thash = Z_ARRVAL_P(zv);
if (thash->u.v.nApplyCount > 1) {
php_error_docref(NULL, E_WARNING, "recursion detected");
- if (!was_ref) {
- ZVAL_UNREF(zv);
- }
result = FAILURE;
break;
}
orig_array_walk_fci = BG(array_walk_fci);
orig_array_walk_fci_cache = BG(array_walk_fci_cache);
- Z_ADDREF(rv);
+ Z_ADDREF(ref);
thash->u.v.nApplyCount++;
- result = php_array_walk(&rv, userdata, recursive);
- if (Z_TYPE_P(Z_REFVAL_P(zv)) == IS_ARRAY && thash == Z_ARRVAL_P(Z_REFVAL_P(zv))) {
+ result = php_array_walk(zv, userdata, recursive);
+ if (Z_TYPE_P(Z_REFVAL(ref)) == IS_ARRAY && thash == Z_ARRVAL_P(Z_REFVAL(ref))) {
/* If the hashtable changed in the meantime, we'll "leak" this apply count
* increment -- our reference to thash is no longer valid. */
thash->u.v.nApplyCount--;
}
- zval_ptr_dtor(&rv);
+ zval_ptr_dtor(&ref);
/* restore the fcall info and cache */
BG(array_walk_fci) = orig_array_walk_fci;
zval_ptr_dtor(&args[0]);
}
+
if (Z_TYPE(args[1]) != IS_UNDEF) {
zval_ptr_dtor(&args[1]);
ZVAL_UNDEF(&args[1]);
}
- if (!was_ref && Z_ISREF_P(zv)) {
- if (Z_REFCOUNT_P(zv) == 1) {
- ZVAL_UNREF(zv);
- }
- }
+
if (result == FAILURE) {
break;
}