Uploaded image for project: 'PHP Driver: Extension'
  1. PHP Driver: Extension
  2. PHPC-1006

Do not modify memory of Persistable::bsonSerialize() return value

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.2.10, 1.3.0-RC1, 1.3.0
    • Affects Version/s: 1.2.9, 1.3.0-beta1
    • Component/s: None
    • None

      Attempting to delete the __pclass key from the HashTable returned by Persistable::bsonSerialize() triggers an assert failure in PHP 7.2:

      php: /tmp/build_php-7.2.0RC1.ocF/php-7.2.0RC1/Zend/zend_hash.c:1162: zend_hash_str_del: Assertion `((ht)->gc.refcount == 1) || ((ht)->u.flags & (1<<6))' failed.
      Aborted (core dumped)
      
      Termsig=6
      

      This is traced back to the zend_hash_str_del() call in php_phongo_zval_to_bson(). Assert failures show up for the following tests:

      MongoDB\BSON\fromPHP(): Null type map values imply default behavior [tests/bson/bson-toPHP-002.phpt]
      PHPC-334: Injected __pclass should override a __pclass key in bsonSerialize() return value [tests/bson/bug0334-001.phpt]
      PHPC-334: Encoded BSON should never have multiple __pclass keys [tests/bson/bug0334-002.phpt]
      PHPC-924: Cursor::setTypeMap() may unnecessarily convert first BSON document (__pclass) [tests/cursor/bug0924-002.phpt]
      PHPC-545: Update does not serialize embedded Persistable's __pclass field [tests/standalone/bug0545.phpt]
      

      In all of these tests, the reference count on the HashTable returned by Persistable::bsonSerialize() is 2 instead of 1. The returned array may be generated in various ways:

      Some recent upstream commits in PHP relevant to this assertion are:

      The assertion logic dates back to PHP 7.0.0. My local PHP build environments all have ZEND_DEBUG defined, so I can confirm that this assertion only started failing in PHP 7.2.


      After further investigation, this uncovered a long-outstanding bug where the memory of the Persistable::bsonSerialize() return value might be modified if we actually unset an existing __pclass field.

            Assignee:
            jmikola@mongodb.com Jeremy Mikola
            Reporter:
            jmikola@mongodb.com Jeremy Mikola
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: