diff options
author | Dmitry Stogov <dmitry@php.net> | 2005-05-27 16:18:07 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2005-05-27 16:18:07 +0000 |
commit | 743c5bb15bcbc147e2cee4afb13c87b090102e51 (patch) | |
tree | ebcbcb3f7c09222ddc628a2d83892dfc356c6cde | |
parent | b74a5eac593e046021c3b2e2e6e9b654620c0a6b (diff) | |
download | php-git-743c5bb15bcbc147e2cee4afb13c87b090102e51.tar.gz |
Fixed bug #22836 (returning reference to uninitialized variable)
-rw-r--r-- | Zend/tests/bug22836.phpt | 44 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 5 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 25 |
3 files changed, 19 insertions, 55 deletions
diff --git a/Zend/tests/bug22836.phpt b/Zend/tests/bug22836.phpt index 98e3f299e9..06a5c3242c 100644 --- a/Zend/tests/bug22836.phpt +++ b/Zend/tests/bug22836.phpt @@ -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 - - diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8f4681306c..8105d04ba1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 773e31b19b..0d195906b8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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); |