Skip to content

Inconsistent behavior when both properties and get_properties are set #19229

@danog

Description

@danog

Description

This might not be a proper bug, as it can likely be classified as a misconfiguration of the object handlers, but it still is an inconsistency.

I encountered this bug in the mongodb extension, which has a custom get_properties handler, but no custom get_property/etc handlers (and a custom gc handler which just proxies to zend_std_get_properties).

The absence of custom get_property handlers, and the custom gc handler both leads to the invocation of zend_std_get_properties when:

  • A property is set/checked for existence/etc
  • The garbage collector is invoked

zend_std_get_properties then initializes the properties hashtable, which, if empty (for example purely after invoking get_gc, or after setting and then unsetting the property) breaks foreach because of the if (zend_hash_num_elements(properties) == 0) { check in the ZEND_FE_RESET_R_SPEC_CV_HANDLER.

However, paradoxically, if the property table is not empty, that checks falls through, and during iteration i.e. in ZEND_FE_FETCH_R_SPEC_VAR_HANDLER Z_OBJPROP_P is invoked, which leads to the invocation of get_properties after all, and iteration over that instead of the properties table.

This leads to the actual inconsistency: if the properties table is empty, iteration is skipped without invoking get_properties, if it is non-empty, it is ignored anyway and get_properties is invoked for iteration.

Ref mongodb/mongo-php-driver#1850

PHP Version

8.4.10

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