Skip to content

php 8.2.0-dev crashes with assertion for cloning/get_object_vars on non-empty SplFixedArray (8.1 unaffected) #8041

Closed
@TysonAndre

Description

@TysonAndre

Description

The following code:

<?php
php > $x = new SplFixedArray(/*count*/ 1);
php > var_export((array)$x);
array (
  0 => NULL,
)
php > $y = clone $x;

Resulted in this output (in a debug build - php 8.1 is unaffected), crashes in nts build for larger arrays:

php: /path/to/php-src/Zend/zend_objects.c:241: zend_objects_clone_members: Assertion `!(((__ht)->u.flags & (1<<2)) != 0)' failed.
[1]    126358 abort (core dumped)  php -a

But I expected this output instead:

Not crashing with a ZEND_ASSERT failure or invalid memory access

Similar bugs affect Zend/zend_builtin_functions.c get_object_vars()

php > $x = new SplFixedArray(1);
php > $x[0] = $x;
php > var_export(get_object_vars($x));
php: /path/to/php-src/Zend/zend_hash.c:1012: _zend_hash_index_add_or_update_i: Assertion `(zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed.
[1]    127583 abort (core dumped)  php -a

Cause: ZEND_HASH_MAP_FOREACH_KEY_VAL(old_object->properties, num_key, key, prop) { expects the properties HashTable* to always be associative, but it sometimes be packed, e.g. for SplFixedArray.

Possible solutions:

  1. Use the slower ZEND_HASH_FOREACH_KEY_VAL macro that works with both packed and associative HashTables. This seems to me like the best solution.
  2. Split up the code into two separate cases for LIST/MAP internal representations where performance sensitive, in combination with 1.
  3. Somehow force properties tables to always be associative when creating objects, including for PECL code (would waste memory)

@nikic @dstogov thoughts?

The following parts of the code are likely to be affected, I've only confirmed for zend_objects.c and zend_builtin_functions.c

» ag 'ZEND_HASH.*properties\b' ../php-src
../php-src/Zend/zend_objects.c
241:            ZEND_HASH_MAP_FOREACH_KEY_VAL(old_object->properties, num_key, key, prop) {

../php-src/Zend/zend_API.c
1291:   ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(properties, key, value) {
1549:           ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(properties, key, prop) {
1581:   ZEND_HASH_FOREACH_KEY_VAL(properties, h, key, prop) {

../php-src/Zend/zend_builtin_functions.c
764:            ZEND_HASH_MAP_FOREACH_KEY_VAL(properties, num_key, key, value) {

../php-src/ext/snmp/snmp.c
1824:   ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&php_snmp_properties, key, hnd) {

../php-src/ext/reflection/php_reflection.c
480:                    ZEND_HASH_MAP_FOREACH_STR_KEY(properties, prop_name) {
4590:           ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(properties, key, prop) {

PHP Version

PHP 8.2.0-dev (2022-Feb-05)

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions