php / php-src

The PHP Interpreter
https://www.php.net
Other
38.23k stars 7.75k forks source link

Assertion failure in Zend/zend_hash.c #16053

Closed YuanchengJiang closed 1 month ago

YuanchengJiang commented 1 month ago

Description

The following code:

<?php
class test
{
}
$x = new test;
$fusion = $x;
$arrays = array (
array(1 => "hello", "string" => $fusion, $heredoc),
);
$arr2 = array( 1 => "one", 2, "string" => "hello", "array" => array("a", "b", "c"));
foreach($arrays as $arr1) {
var_dump( array_merge_recursive($arr1) );
var_dump( array_merge_recursive($arr1, $arr2) );
}

Resulted in this output:

/php-src/Zend/zend_hash.c:1091: zval *_zend_hash_index_add_or_update_i(HashTable *, zend_ulong, zval *, uint32_t): Assertion `(zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed.
Aborted (core dumped)

PHP Version

PHP 8.4.0-dev

Operating System

ubuntu 22.04

cmb69 commented 1 month ago

At least PHP-8.3 is affected by this, too.

arnaud-lb commented 1 month ago

Smaller reproducer:

<?php
class test
{
}
$x = new test;
$arr1 = array("string" => $x);
$arr2 = array("string" => "hello");
var_dump($x);
var_dump(array_merge_recursive($arr1, $arr2));

array_merge_recursive() assumes that the result of convert_to_array($x) has RC=1, which is not always the case.

arnaud-lb commented 1 month ago

Fixed by https://github.com/php/php-src/pull/16061.

Thank you @YuanchengJiang!