]> granicus.if.org Git - php/commitdiff
MFB: Fixed bug #43495 (array_merge_recursive() crashes with recursive
authorIlia Alshanetsky <iliaa@php.net>
Wed, 5 Dec 2007 19:57:09 +0000 (19:57 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Wed, 5 Dec 2007 19:57:09 +0000 (19:57 +0000)
arrays)

ext/standard/array.c
ext/standard/tests/array/bug43495.phpt [new file with mode: 0644]

index 48be4e84e1755216445fa2b29ce660ee2643e3a3..475104b942e518f194da7972b3187d5fe28c1e86 100644 (file)
@@ -2391,7 +2391,9 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
                                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;
                                        }
@@ -2400,9 +2402,18 @@ ukey:
 
                                        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);
diff --git a/ext/standard/tests/array/bug43495.phpt b/ext/standard/tests/array/bug43495.phpt
new file mode 100644 (file)
index 0000000..2bdbf96
--- /dev/null
@@ -0,0 +1,17 @@
+--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.