Skip to content

memory leak in zend_type_release #11883

Closed
@ju1ius

Description

@ju1ius

Description

Hi,

The zend_type_release function never frees intersection type lists inside union type lists (i.e. Iterator|(Traversable&Countable), which leads to valgrind reporting memory leaks.

The issue does not manifest itself with userland code because userland zend_types are arena-allocated, and does not show-up in most extensions because gen_stubs cannot generate proper DNF types.

Here's the current code of the function, with added comments:

ZEND_API void zend_type_release(zend_type type, bool persistent) {
  if (ZEND_TYPE_HAS_LIST(type)) {
    zend_type *list_type, *sublist_type;
    ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) {
      if (ZEND_TYPE_HAS_LIST(*list_type)) {
        ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*list_type), sublist_type) {
          if (ZEND_TYPE_HAS_NAME(*sublist_type)) {
            zend_string_release(ZEND_TYPE_NAME(*sublist_type));
          }
        } ZEND_TYPE_LIST_FOREACH_END();
        // --------------------
        // The inner list should be freed here, but it is not...
        // --------------------
      } else if (ZEND_TYPE_HAS_NAME(*list_type)) {
        zend_string_release(ZEND_TYPE_NAME(*list_type));
      }
    } ZEND_TYPE_LIST_FOREACH_END();
    if (!ZEND_TYPE_USES_ARENA(type)) {
      pefree(ZEND_TYPE_LIST(type), persistent);
    }
  } else if (ZEND_TYPE_HAS_NAME(type)) {
    zend_string_release(ZEND_TYPE_NAME(type));
  }
}

PHP Version

PHP 8.3-dev

Operating System

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions