Hi, today, I stumbled on this piece of code in zend_persist.c:
zend_ast_ref *old_ref = Z_AST_P(z); Z_AST_P(z) = zend_shared_memdup_put(Z_AST_P(z), sizeof(zend_ast_ref)); This is the definition of `zend_ast_ref` from zend_types.h: struct _zend_ast_ref { zend_refcounted_h gc; /*zend_ast ast; zend_ast follows the zend_ast_ref structure */ }; The memdup() call confuses me. It looks broken. It appears that code which allocates `zend_ast_ref` reserves some space after that for one or more `zend_ast` instances, see zend_ast_copy() and create_enum_case_ast(). But what happens if I memdup() only the raw `zend_ast_ref`, which consists of only the `zend_refcounted_h`? What confuses me even more is that zend_persist.c then calls zend_persist_ast() to copy one `zend_ast` that follows after the `zend_ast_ref` object, but discards the newly allocated value. Not only does this look like a memory leak, but also the `zend_ast_ref` is incomplete, and dereferencing the following `zend_ast` should be an out-of-bounds access. Does this piece of code rely on the next zend_shared_memdup() call to place the next allocation right after the `zend_ast_ref`? (This sounds pretty fragile. What happens if padding happens to get inserted by the allocator?) Max -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php