php / php-src

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

Assertion failure in ext/reflection/php_reflection.c:487 #16187

Open YuanchengJiang opened 1 day ago

YuanchengJiang commented 1 day ago

Description

The following code:

<?php
$xml = <<<XML
<form name="test"></form>
XML;
$simplexml = simplexml_load_string($xml);
$reflector = new ReflectionObject($simplexml['name']);
$fusion = $reflector;
$file_path = __DIR__;
$filename = "/dev/null";
$octal_formats = array( "%o",);
$file_handle = fopen($filename, "r");
foreach($octal_formats as $octal_format) {
while( !feof($file_handle) ) {
try {
var_dump(fscanf($file_handle,$fusion));
} catch (ValueError $exception) {
}
}
}

Resulted in this output:

/php-src/ext/reflection/php_reflection.c:487: void _class_string(smart_str *, zend_class_entry *, zval *, const char *): Assertion `!(((__ht)->u.flags & (1<<2)) != 0)' failed.
Aborted (core dumped)

PHP Version

PHP 8.4.0-dev

Operating System

ubuntu 22.04

DanielEScherzer commented 1 day ago

Minimal reproduction:

<?php
$xml = '<form name="test"></form>';
$simplexml = simplexml_load_string($xml);
$reflector = new ReflectionObject($simplexml['name']);
$reflector->__toString();

produces

root@3acd01cef279:/usr/src/php# php /var/www/html/test.php 
php: /usr/src/php/ext/reflection/php_reflection.c:487: _class_string: Assertion `!(((__ht)->u.flags & (1<<2)) != 0)' failed.
Aborted
DanielEScherzer commented 1 day ago

The assertion comes from a series of macros, ZEND_HASH_MAP_FOREACH_STR_KEY -> ZEND_HASH_MAP_FOREACH -> ZEND_HASH_MAP_FOREACH_FROM -> ZEND_ASSERT(!HT_IS_PACKED(__ht)); Use ZEND_HASH_FOREACH_STR_KEY instead of the map version is enough to fix this

DanielEScherzer commented 1 day ago

PR is at #16192, I confirmed that it also fixes the reported code (now results in the output bool(false))