]> granicus.if.org Git - php/commitdiff
Fixed bug #22836 (returning reference to uninitialized variable)
authorDmitry Stogov <dmitry@php.net>
Fri, 27 May 2005 16:18:07 +0000 (16:18 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 27 May 2005 16:18:07 +0000 (16:18 +0000)
Zend/tests/bug22836.phpt
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 98e3f299e97254824fd4d26a60eb7a0d479220a2..06a5c3242c10e31f3ddf007791abc6529b5eaece 100644 (file)
@@ -2,8 +2,6 @@
 Bug #22836 (returning references to NULL)
 --SKIPIF--
 <?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
---INI--
-error_reporting=4095
 --FILE--
 <?php
 function &f()
@@ -11,7 +9,7 @@ function &f()
        $x = "foo";
        var_dump($x);
        print "'$x'\n";
-       return $a;
+       return ($a);
 }
 for ($i = 0; $i < 8; $i++) {
        $h =& f();
@@ -20,57 +18,17 @@ for ($i = 0; $i < 8; $i++) {
 --EXPECTF--
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
 string(3) "foo"
 'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
-string(3) "foo"
-'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
-
-
index 8f4681306ce6c857bd98cd7fe68e24ddccaa3812..8105d04ba1556e1654ec08eae25303938ef9a773 100644 (file)
@@ -1978,7 +1978,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
                        zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
                }
 
-               if (!(*retval_ptr_ptr)->is_ref) {
+               if (OP1_TYPE == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
@@ -2010,7 +2010,8 @@ ZEND_VM_C_LABEL(return_by_value):
                        ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
                        *EG(return_value_ptr_ptr) = ret;
                } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
-                       if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+                       if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+                           (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
                                zval *ret;
 
                                ALLOC_ZVAL(ret);
index 773e31b19b539bb6e8bee8025ef0405b64d56783..0d195906b846fffc839a61568465d7eb6bd6b186 100644 (file)
@@ -1565,7 +1565,7 @@ static int ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
                }
 
-               if (!(*retval_ptr_ptr)->is_ref) {
+               if (IS_CONST == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
@@ -1597,7 +1597,8 @@ return_by_value:
                        ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
                        *EG(return_value_ptr_ptr) = ret;
                } else if (!0) { /* Not a temp var */
-                       if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+                       if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+                           (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
                                zval *ret;
 
                                ALLOC_ZVAL(ret);
@@ -4000,7 +4001,7 @@ static int ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
                }
 
-               if (!(*retval_ptr_ptr)->is_ref) {
+               if (IS_TMP_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
@@ -4032,7 +4033,8 @@ return_by_value:
                        ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
                        *EG(return_value_ptr_ptr) = ret;
                } else if (!1) { /* Not a temp var */
-                       if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+                       if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+                           (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
                                zval *ret;
 
                                ALLOC_ZVAL(ret);
@@ -6989,7 +6991,7 @@ static int ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
                }
 
-               if (!(*retval_ptr_ptr)->is_ref) {
+               if (IS_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
@@ -7021,7 +7023,8 @@ return_by_value:
                        ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
                        *EG(return_value_ptr_ptr) = ret;
                } else if (!0) { /* Not a temp var */
-                       if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+                       if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+                           (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
                                zval *ret;
 
                                ALLOC_ZVAL(ret);
@@ -18602,7 +18605,7 @@ static int ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
                }
 
-               if (!(*retval_ptr_ptr)->is_ref) {
+               if (IS_CV == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
@@ -18634,7 +18637,8 @@ return_by_value:
                        ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
                        *EG(return_value_ptr_ptr) = ret;
                } else if (!0) { /* Not a temp var */
-                       if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+                       if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+                           (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
                                zval *ret;
 
                                ALLOC_ZVAL(ret);
@@ -30968,7 +30972,7 @@ static int ZEND_RETURN_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
                }
 
-               if (!(*retval_ptr_ptr)->is_ref) {
+               if (opline->op1.op_type == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
@@ -31000,7 +31004,8 @@ return_by_value:
                        ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
                        *EG(return_value_ptr_ptr) = ret;
                } else if (!IS_TMP_FREE(free_op1)) { /* Not a temp var */
-                       if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+                       if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+                           (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
                                zval *ret;
 
                                ALLOC_ZVAL(ret);