|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-09-10 14:03 UTC] tandre@php.net
Description: ------------ offsetSet does not account for the fact that the array may no longer exist after the field is overwritten. This can be fixed by ZVAL_COPY_VALUE to copy the old value to a temporary location, then overwriting the old address, then destructing the copy of the old value. (I used this approach in a PECL I wrote when considering proposing data structures such as Vector in core in the future - https://github.com/TysonAndre/pecl-teds/blob/0.1.0a1/teds_vector.c#L809-L820 ) Related to https://bugs.php.net/bug.php?id=80663 Test script: --------------- <?php echo __LINE__,"\n"; $values = new SplFixedArray(1); echo __LINE__,"\n"; $values->offsetSet(0, new HasDestructor()); echo __LINE__,"\n"; $values->offsetSet(0, null); class HasDestructor { public function __destruct() { echo __LINE__,"\n"; $GLOBALS['values']->setSize(0); } } Expected result: ---------------- The size is set to 0 and there are no memory leaks Actual result: -------------- 2 4 6 11 ==8024== Invalid write of size 8 ==8024== at 0x79B888: spl_fixedarray_object_write_dimension_helper (spl_fixedarray.c:419) ==8024== by 0x79CD70: zim_SplFixedArray_offsetSet (spl_fixedarray.c:762) ==8024== by 0xA16344: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1761) ==8024== by 0xA87C89: execute_ex (zend_vm_execute.h:54512) ==8024== by 0xA8D429: zend_execute (zend_vm_execute.h:58843) ==8024== by 0x9D96B8: zend_execute_scripts (zend.c:1755) ==8024== by 0x936E36: php_execute_script (main.c:2519) ==8024== by 0xB4947B: do_cli (php_cli.c:965) ==8024== by 0xB4A583: main (php_cli.c:1367) ==8024== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==8024== ==8024== ==8024== Process terminating with default action of signal 11 (SIGSEGV) ==8024== Access not within mapped region at address 0x0 ==8024== at 0x79B888: spl_fixedarray_object_write_dimension_helper (spl_fixedarray.c:419) ==8024== by 0x79CD70: zim_SplFixedArray_offsetSet (spl_fixedarray.c:762) ==8024== by 0xA16344: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1761) ==8024== by 0xA87C89: execute_ex (zend_vm_execute.h:54512) ==8024== by 0xA8D429: zend_execute (zend_vm_execute.h:58843) ==8024== by 0x9D96B8: zend_execute_scripts (zend.c:1755) ==8024== by 0x936E36: php_execute_script (main.c:2519) ==8024== by 0xB4947B: do_cli (php_cli.c:965) ==8024== by 0xB4A583: main (php_cli.c:1367) ==8024== If you believe this happened as a result of a stack ==8024== overflow in your program's main thread (unlikely but ==8024== possible), you can try to increase the size of the ==8024== main thread stack using the --main-stacksize= flag. ==8024== The main thread stack size used in this run was 8388608. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 21:00:01 2025 UTC |
<?php echo __LINE__,"\n"; $values = new SplFixedArray(1); echo __LINE__,"\n"; $values->offsetSet(0, new HasDestructor()); global $values; /*echo __LINE__,"\n"; $values->offsetSet(0, null);*/ class HasDestructor { public function __destruct() { global $values; if(isset($GLOBALS['values'])) { echo __LINE__,"\n"; $values->setSize(0); var_dump('local second object scope ', $values); } } }