Bug #81429 [Com]: SplFixedArray::setSize(0) called during offsetSet() causes segmentation fault
Edit report at https://bugs.php.net/bug.php?id=81429&edit=1
ID: 81429
Comment by: antonino dot spampinato86 at gmail dot com
Reported by: tandre@php.net
Summary: SplFixedArray::setSize(0) called during offsetSet()
causes segmentation fault
Status: Open
Type: Bug
Package: SPL related
Operating System: Any
PHP Version: 8.1.0RC1
Block user comment: N
Private report: N
New Comment:
<?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);
}
}
}
Previous Comments:
------------------------------------------------------------------------
[2021-09-10 14:03:10] 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.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81429&edit=1
Thread (3 messages)