summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2005-04-29 07:03:54 +0000
committerDmitry Stogov <dmitry@php.net>2005-04-29 07:03:54 +0000
commit8db238b075e708f032435fd49e9de0de4da80f0c (patch)
tree8c157ff36a456e8bde0aacb12287f7cb451ac64b
parent72b5173ac33a4f8f3ed3bebc996355f5796d8966 (diff)
downloadphp-git-8db238b075e708f032435fd49e9de0de4da80f0c.tar.gz
Fixed bug #32852 (Crash with singleton and __destruct when zend.ze1_compatibility_mode = On)
Fixed bug #31828 (Crash with zend.ze1_compatibility_mode=On) Fixed bug #32080 (segfault when assigning object to itself with zend.ze1_compatibility_mode=On)
-rw-r--r--Zend/tests/bug31828.phpt19
-rw-r--r--Zend/tests/bug32080.phpt14
-rw-r--r--Zend/tests/bug32852.phpt37
-rw-r--r--Zend/zend_execute.c26
4 files changed, 85 insertions, 11 deletions
diff --git a/Zend/tests/bug31828.phpt b/Zend/tests/bug31828.phpt
new file mode 100644
index 0000000000..a2651d3e24
--- /dev/null
+++ b/Zend/tests/bug31828.phpt
@@ -0,0 +1,19 @@
+--TSTE--
+Bug #31828 (Crash with zend.ze1_compatibility_mode=On)
+--INI--
+zend.ze1_compatibility_mode=on
+--FILE--
+<?php
+$o = new stdClass();
+$o->id = 77;
+$o->name = "Aerospace";
+$a[] = $o;
+$a = $a[0];
+print_r($a);
+?>
+--EXPECT--
+stdClass Object
+(
+ [id] => 77
+ [name] => Aerospace
+)
diff --git a/Zend/tests/bug32080.phpt b/Zend/tests/bug32080.phpt
new file mode 100644
index 0000000000..c6430235c1
--- /dev/null
+++ b/Zend/tests/bug32080.phpt
@@ -0,0 +1,14 @@
+--TSTE--
+Bug #32080 (segfault when assigning object to itself with zend.ze1_compatibility_mode=On)
+--INI--
+zend.ze1_compatibility_mode=on
+--FILE--
+<?php
+class test { }
+$t = new test;
+$t = $t; // gives segfault
+var_dump($t);
+?>
+--EXPECT--
+object(test)#2 (0) {
+}
diff --git a/Zend/tests/bug32852.phpt b/Zend/tests/bug32852.phpt
new file mode 100644
index 0000000000..7f2b14df21
--- /dev/null
+++ b/Zend/tests/bug32852.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug #32852 (Crash with singleton and __destruct when zend.ze1_compatibility_mode = On)
+--INI--
+zend.ze1_compatibility_mode=on
+--FILE--
+<?php
+class crashme {
+ private static $instance = null;
+
+ public function __construct() {
+ self::$instance = $this;
+ }
+
+ public function __destruct() {
+ echo "i'm called\n";
+ }
+
+ public static function singleton() {
+ if (!isset(self::$instance)) {
+ self::$instance = new crashme();
+ }
+ return self::$instance;
+ }
+}
+
+crashme::singleton();
+?>
+--EXPECTF--
+Strict Standards: Implicit cloning object of class 'crashme' because of 'zend.ze1_compatibility_mode' in %sbug32852.php on line 6
+i'm called
+
+Strict Standards: Implicit cloning object of class 'crashme' because of 'zend.ze1_compatibility_mode' in %sbug32852.php on line 15
+i'm called
+
+Strict Standards: Implicit cloning object of class 'crashme' because of 'zend.ze1_compatibility_mode' in %sbug32852.php on line 17
+i'm called
+i'm called
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 61cc2c459c..7d8cc74261 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -800,7 +800,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_P(value)->name);
} else if (PZVAL_IS_REF(variable_ptr)) {
- if (variable_ptr != value) {
+ if (variable_ptr != value) {
zend_uint refcount = variable_ptr->refcount;
zval garbage;
@@ -819,17 +819,21 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
zendi_zval_dtor(garbage);
}
} else {
- variable_ptr->refcount--;
- if (variable_ptr->refcount == 0) {
- zendi_zval_dtor(*variable_ptr);
- } else {
- ALLOC_ZVAL(variable_ptr);
- *variable_ptr_ptr = variable_ptr;
+ if (variable_ptr != value) {
+ value->refcount++;
+ variable_ptr->refcount--;
+ if (variable_ptr->refcount == 0) {
+ zendi_zval_dtor(*variable_ptr);
+ } else {
+ ALLOC_ZVAL(variable_ptr);
+ *variable_ptr_ptr = variable_ptr;
+ }
+ *variable_ptr = *value;
+ INIT_PZVAL(variable_ptr);
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", Z_OBJCE_P(value)->name);
+ variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
+ zval_ptr_dtor(&value);
}
- *variable_ptr = *value;
- INIT_PZVAL(variable_ptr);
- zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", Z_OBJCE_P(value)->name);
- variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
}
} else if (PZVAL_IS_REF(variable_ptr)) {
if (variable_ptr!=value) {