utype = IS_UNICODE;
ukey:
if (recursive && zend_u_hash_find(dest, utype, string_key, string_key_len, (void **)&dest_entry) == SUCCESS) {
- if (*src_entry == *dest_entry && (Z_REFCOUNT_PP(dest_entry) % 2)) {
+ HashTable *thash = HASH_OF(*dest_entry);
+
+ if ((thash && thash->nApplyCount > 1) || (*src_entry == *dest_entry && (Z_REFCOUNT_PP(dest_entry) % 2))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
return 0;
}
convert_to_array_ex(dest_entry);
convert_to_array_ex(src_entry);
+ if (thash) {
+ thash->nApplyCount++;
+ }
if (!php_array_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry), recursive TSRMLS_CC)) {
+ if (thash) {
+ thash->nApplyCount--;
+ }
return 0;
}
+ if (thash) {
+ thash->nApplyCount--;
+ }
} else {
Z_ADDREF_PP(src_entry);
zend_u_hash_update(dest, utype, string_key, string_key_len, src_entry, sizeof(zval *), NULL);
--- /dev/null
+--TEST--
+Bug #43495 (array_merge_recursive() crashes with recursive arrays)
+--FILE--
+<?php
+$a=array("key1"=>array("key2"=>array()));
+$a["key1"]["key2"]["key3"]=&$a;
+
+$b=array("key1"=>array("key2"=>array()));
+$b["key1"]["key2"]["key3"]=&$b;
+
+array_merge_recursive($a,$b);
+
+echo "Done.\n";
+?>
+--EXPECTF--
+Warning: array_merge_recursive(): recursion detected in %s/bug43495.php on line %d
+Done.