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

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions