Commit:    ce9169e360701ea3b1ab2366171c24d4de5e78e3
Author:    Xinchen Hui <larue...@php.net>         Fri, 2 Aug 2013 18:37:15 +0800
Parents:   cb13f8318b39f72798c3756dcfe55daae4c932e2
Branches:  PHP-5.4 PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=ce9169e360701ea3b1ab2366171c24d4de5e78e3

Log:
Fixed bug Bug #65372 (Segfault in gc_zval_possible_root when return reference 
fails)

Bugs:
https://bugs.php.net/65372

Changed paths:
  M  NEWS
  A  Zend/tests/bug65372.phpt
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h


Diff:
diff --git a/NEWS b/NEWS
index d480e3d..0218615 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP                                                             
           NEWS
 ?? ??? 2013, PHP 5.4.19
 
 - Core.
+  . Fixed bug #65372 (Segfault in gc_zval_possible_root when return reference
+    fails). (Laruence)
   . Fixed bug #65304 (Use of max int in array_sum). (Laruence)
   . Fixed bug #65291 (get_defined_constants() causes PHP to crash in a very
     limited case). (Arpad)
diff --git a/Zend/tests/bug65372.phpt b/Zend/tests/bug65372.phpt
new file mode 100644
index 0000000..50fc2db
--- /dev/null
+++ b/Zend/tests/bug65372.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #65372 (Segfault in gc_zval_possible_root when return reference fails)
+--FILE--
+<?php
+
+class ParentClass
+{
+    private static $_OBJECTS;
+
+    public static function Get()
+    {
+        self::$_OBJECTS[1] = new ChildClass();
+        return self::$_OBJECTS[1];    
+    }
+}
+
+class ChildClass extends ParentClass
+{
+    public $Manager;
+
+    function __construct()
+    {
+        $this->Manager = $this;
+    }
+
+    public static function &GetCurrent()
+    {
+        return ChildClass::Get();
+    }
+
+    public static function &Get()
+    {
+        return parent::Get();
+    }
+}
+
+$staff = ChildClass::GetCurrent();
+?>
+--EXPECTF--
+Notice: Only variable references should be returned by reference in 
%sbug65372.php on line 30
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 7346078..83e40b5 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2910,9 +2910,11 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, 
CONST|TMP|VAR|CV, ANY)
                        } else if (EX_T(opline->op1.var).var.ptr_ptr == 
&EX_T(opline->op1.var).var.ptr) {
                                zend_error(E_NOTICE, "Only variable references 
should be returned by reference");
                                if (EG(return_value_ptr_ptr)) {
-                                       retval_ptr = *retval_ptr_ptr;
-                                       *EG(return_value_ptr_ptr) = retval_ptr;
-                                       Z_ADDREF_P(retval_ptr);
+                                       zval *ret;
+
+                                       ALLOC_ZVAL(ret);
+                                       INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
+                                       *EG(return_value_ptr_ptr) = ret;
                                }
                                break;
                        }
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 6e466e4..339e34b 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -2324,9 +2324,11 @@ static int ZEND_FASTCALL  
ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
                        } else if (EX_T(opline->op1.var).var.ptr_ptr == 
&EX_T(opline->op1.var).var.ptr) {
                                zend_error(E_NOTICE, "Only variable references 
should be returned by reference");
                                if (EG(return_value_ptr_ptr)) {
-                                       retval_ptr = *retval_ptr_ptr;
-                                       *EG(return_value_ptr_ptr) = retval_ptr;
-                                       Z_ADDREF_P(retval_ptr);
+                                       zval *ret;
+
+                                       ALLOC_ZVAL(ret);
+                                       INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
+                                       *EG(return_value_ptr_ptr) = ret;
                                }
                                break;
                        }
@@ -6743,9 +6745,11 @@ static int ZEND_FASTCALL  
ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
                        } else if (EX_T(opline->op1.var).var.ptr_ptr == 
&EX_T(opline->op1.var).var.ptr) {
                                zend_error(E_NOTICE, "Only variable references 
should be returned by reference");
                                if (EG(return_value_ptr_ptr)) {
-                                       retval_ptr = *retval_ptr_ptr;
-                                       *EG(return_value_ptr_ptr) = retval_ptr;
-                                       Z_ADDREF_P(retval_ptr);
+                                       zval *ret;
+
+                                       ALLOC_ZVAL(ret);
+                                       INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
+                                       *EG(return_value_ptr_ptr) = ret;
                                }
                                break;
                        }
@@ -11055,9 +11059,11 @@ static int ZEND_FASTCALL  
ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
                        } else if (EX_T(opline->op1.var).var.ptr_ptr == 
&EX_T(opline->op1.var).var.ptr) {
                                zend_error(E_NOTICE, "Only variable references 
should be returned by reference");
                                if (EG(return_value_ptr_ptr)) {
-                                       retval_ptr = *retval_ptr_ptr;
-                                       *EG(return_value_ptr_ptr) = retval_ptr;
-                                       Z_ADDREF_P(retval_ptr);
+                                       zval *ret;
+
+                                       ALLOC_ZVAL(ret);
+                                       INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
+                                       *EG(return_value_ptr_ptr) = ret;
                                }
                                break;
                        }
@@ -27030,9 +27036,11 @@ static int ZEND_FASTCALL  
ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
                        } else if (EX_T(opline->op1.var).var.ptr_ptr == 
&EX_T(opline->op1.var).var.ptr) {
                                zend_error(E_NOTICE, "Only variable references 
should be returned by reference");
                                if (EG(return_value_ptr_ptr)) {
-                                       retval_ptr = *retval_ptr_ptr;
-                                       *EG(return_value_ptr_ptr) = retval_ptr;
-                                       Z_ADDREF_P(retval_ptr);
+                                       zval *ret;
+
+                                       ALLOC_ZVAL(ret);
+                                       INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
+                                       *EG(return_value_ptr_ptr) = ret;
                                }
                                break;
                        }


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to