- Fixed bug #39700 (NUMERIC error when result precision are 7,8 or 12-14 ).
(Lars W)
- Fixed bug #39397 (invalid statement handle in Unknown on line 0). (Lars W)
+- Fixed bug #39346 (Unsetting a static variable inside a destructor causes
+ segfault later on). (Dmitry)
- Fixed bug #39056 (Interbase NUMERIC data type error). (Lars W)
- Fixed bug #38468 (Unexpected creation of cycle). (Dmitry)
- Fixed bug #37911 (preg_replace_callback() ignores named groups). (Nuno)
class test{
public $c=1;
function __destruct (){
- $GLOBALS['p']->c++; // no warning
- print $GLOBALS['p']->c."\n"; // segfault
- var_dump($GLOBALS['p']);
+ if (!isset($GLOBALS['p'])) {
+ echo "NULL\n";
+ } else {
+ $GLOBALS['p']->c++; // no warning
+ print $GLOBALS['p']->c."\n"; // segfault
+ var_dump($GLOBALS['p']);
+ }
}
}
$p=new test;
$p=null; //destroy the object by a new assignment (segfault)
?>
--EXPECT--
-2
-object(test)#1 (1) {
- ["c"]=>
- int(2)
-}
+NULL
--- /dev/null
+--TEST--
+Bug #39346 (Unsetting a static variable inside a destructor causes segfault later on)
+--FILE--
+<?php
+class test
+{
+ protected $_id;
+ static $instances;
+
+ public function __construct($id) {
+ $this->_id = $id;
+ self::$instances[$this->_id] = $this;
+ }
+
+ function __destruct() {
+ unset(self::$instances[$this->_id]);
+ }
+}
+$test = new test(2);
+$test = new test(1);
+$test = new test(2);
+$test = new test(3);
+echo "ok\n";
+?>
+--EXPECT--
+ok
static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value, int is_tmp_var TSRMLS_DC)
{
zval *variable_ptr = *variable_ptr_ptr;
+ zval garbage;
if (variable_ptr == EG(error_zval_ptr)) {
if (is_tmp_var) {
} else if (PZVAL_IS_REF(variable_ptr)) {
if (variable_ptr != value) {
zend_uint refcount = Z_REFCOUNT_P(variable_ptr);
- zval garbage;
if (!is_tmp_var) {
Z_ADDREF_P(value);
} else if (PZVAL_IS_REF(variable_ptr)) {
if (variable_ptr!=value) {
zend_uint refcount = Z_REFCOUNT_P(variable_ptr);
- zval garbage;
if (!is_tmp_var) {
Z_ADDREF_P(value);
if (variable_ptr==value) {
Z_ADDREF_P(variable_ptr);
} else if (PZVAL_IS_REF(value)) {
- zval tmp;
-
- tmp = *value;
- zval_copy_ctor(&tmp);
- Z_SET_REFCOUNT(tmp, 1);
- zendi_zval_dtor(*variable_ptr);
- *variable_ptr = tmp;
+ garbage = *variable_ptr;
+ *variable_ptr = *value;
+ INIT_PZVAL(variable_ptr);
+ zval_copy_ctor(variable_ptr);
+ zendi_zval_dtor(garbage);
+ return variable_ptr;
} else {
Z_ADDREF_P(value);
+ *variable_ptr_ptr = value;
zendi_zval_dtor(*variable_ptr);
safe_free_zval_ptr(variable_ptr);
- *variable_ptr_ptr = value;
+ return value;
}
} else {
- zendi_zval_dtor(*variable_ptr);
- Z_SET_REFCOUNT_P(value, 1);
+ garbage = *variable_ptr;
*variable_ptr = *value;
+ INIT_PZVAL(variable_ptr);
+ zendi_zval_dtor(garbage);
+ return variable_ptr;
}
} else { /* we need to split */
if (!is_tmp_var) {