[php-src] Issue #13687: Method call may leak if releasing EG(This) triggers GC

From: Date: Tue, 12 Mar 2024 18:13:43 +0000
Subject: [php-src] Issue #13687: Method call may leak if releasing EG(This) triggers GC
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-246571@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/13687 Author: arnaud-lb ### Description Method calls may cause their return value to leak if releasing EG(This) triggers GC. The following code: ```php <?php class A { public $cycle; public function __construct() { $this->cycle = $this; } } class B { public function get() { return new A(); } } $c = new B(); $objs = []; while (gc_status()['roots']+2 < gc_status()['threshold']) { $obj = new stdClass; $objs[] = $obj; } var_dump($c->get()); ``` Resulted in a memory leak: ``` Script: 'test.php' Zend/zend_objects.c(189) : Freeing 0x00007ffff7a5c840 (56 bytes), script=test.php === Total 1 memory leaks detected === ``` Here is what is happening: - After returning from get(), [$c is released](https://github.com/php/php-src/blob/94a12d5b315aa73a24b96cfebb4fd38b8e9b800e/Zend/zend_vm_def.h#L2866), which triggers GC - A is removed from buffer, and is not collected because it's referenced by the call stack - After returning from var_dump(), [zend_vm_stack_free_args()](https://github.com/php/php-src/blob/94a12d5b315aa73a24b96cfebb4fd38b8e9b800e/Zend/zend_vm_def.h#L4019) releases A with zval_ptr_dtor_nogc(), so A is not added to the GC buffer - At this point nothing references A but itself, and A is not in the GC buffer, so it leaks I'm not sure how to fix this appart from switching to zval_ptr_dtor(). ### PHP Version master ### Operating System _No response_

« previous php.bugs (#246571) next »