Skip to content

Commit 4022691

Browse files
author
Ilia Alshanetsky
committed
MFB: Fixed bug #43495 (array_merge_recursive() crashes with recursive arrays)
1 parent 22bfae2 commit 4022691

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

ext/standard/array.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2391,7 +2391,9 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
23912391
utype = IS_UNICODE;
23922392
ukey:
23932393
if (recursive && zend_u_hash_find(dest, utype, string_key, string_key_len, (void **)&dest_entry) == SUCCESS) {
2394-
if (*src_entry == *dest_entry && (Z_REFCOUNT_PP(dest_entry) % 2)) {
2394+
HashTable *thash = HASH_OF(*dest_entry);
2395+
2396+
if ((thash && thash->nApplyCount > 1) || (*src_entry == *dest_entry && (Z_REFCOUNT_PP(dest_entry) % 2))) {
23952397
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
23962398
return 0;
23972399
}
@@ -2400,9 +2402,18 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
24002402

24012403
convert_to_array_ex(dest_entry);
24022404
convert_to_array_ex(src_entry);
2405+
if (thash) {
2406+
thash->nApplyCount++;
2407+
}
24032408
if (!php_array_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry), recursive TSRMLS_CC)) {
2409+
if (thash) {
2410+
thash->nApplyCount--;
2411+
}
24042412
return 0;
24052413
}
2414+
if (thash) {
2415+
thash->nApplyCount--;
2416+
}
24062417
} else {
24072418
Z_ADDREF_PP(src_entry);
24082419
zend_u_hash_update(dest, utype, string_key, string_key_len, src_entry, sizeof(zval *), NULL);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #43495 (array_merge_recursive() crashes with recursive arrays)
3+
--FILE--
4+
<?php
5+
$a=array("key1"=>array("key2"=>array()));
6+
$a["key1"]["key2"]["key3"]=&$a;
7+
8+
$b=array("key1"=>array("key2"=>array()));
9+
$b["key1"]["key2"]["key3"]=&$b;
10+
11+
array_merge_recursive($a,$b);
12+
13+
echo "Done.\n";
14+
?>
15+
--EXPECTF--
16+
Warning: array_merge_recursive(): recursion detected in %s/bug43495.php on line %d
17+
Done.

0 commit comments

Comments
 (0)