Fixed bug #39944 (References broken)

This commit is contained in:
Dmitry Stogov 2006-12-25 14:16:27 +00:00
parent 5436160dc6
commit e57a60698b
5 changed files with 120 additions and 6 deletions

1
NEWS
View File

@ -16,6 +16,7 @@ PHP NEWS
__inet_pton() and inet_ntop() was named __inet_ntop(). (Hannes)
- Fixed the validate email filter so that the letter "v" can also be used in
the user part of the email address. (Derick)
- Fixed bug #39944 (References broken). (Dmitry)
- Fixed bug #39935 (Extensions tidy,mcrypt,mhash,pdo_sqlite ignores
--with-libdir). (judas dot iscariote at gmail dot com, Derick)
- Fixed bug #39903 (Notice message when executing __halt_compiler() more than

88
Zend/tests/bug39944.phpt Executable file
View File

@ -0,0 +1,88 @@
--TEST--
Bug #39944 (References broken)
--FILE--
<?php
$intTheValue = 0;
function &getValue() {
global $intTheValue;
return $intTheValue;
}
function setValue(&$int, $iNewValue) {
$int = $iNewValue;
}
setValue(getValue(), 10);
echo "intTheValue = {$intTheValue}\n";
$b = &$intTheValue;
setValue(getValue(), 10);
echo "intTheValue = {$intTheValue}\n";
/****/
$arrTheArray = array();
function &getArray() {
global $arrTheArray;
return $arrTheArray;
}
function addToArray(&$arr, $strToAdd) {
$arr[] = $strToAdd;
}
addToArray(getArray(), "xx1");
$a = getArray();
addToArray($a, "xx2");
$b = &$arrTheArray;
addToArray($b, "xx3");
addToArray(getArray(), "xx4");
$a = getArray();
addToArray($a, "xx5");
echo "arrTheArray = " . print_r($arrTheArray, 1);
/****/
class RefTest {
protected $arr;
function Add($strToAdd) {
$this->addToArray($this->getArray(), $strToAdd);
}
function &getArray() {
if (!$this->arr)
$this->arr = array();
return $this->arr;
}
private function addToArray(&$arr, $strToAdd) {
$arr[] = $strToAdd;
}
}
$objRefTest = new RefTest();
$objRefTest->Add("xx1");
$objRefTest->Add("xx2");
$objRefTest->Add("xx3");
echo "objRefTest->getArray() = " . print_r($objRefTest->getArray(), 1);
?>
--EXPECT--
intTheValue = 10
intTheValue = 10
arrTheArray = Array
(
[0] => xx1
[1] => xx3
[2] => xx4
)
objRefTest->getArray() = Array
(
[0] => xx1
[1] => xx2
[2] => xx3
)

View File

@ -64,7 +64,7 @@ static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_
#define TEMP_VAR_STACK_LIMIT 2000
static inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free)
static inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free, int unref)
{
if (!--z->refcount) {
z->refcount = 1;
@ -73,7 +73,7 @@ static inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free)
/* should_free->is_var = 1; */
} else {
should_free->var = 0;
if (z->is_ref && z->refcount == 1) {
if (unref && z->is_ref && z->refcount == 1) {
z->is_ref = 0;
}
}
@ -87,7 +87,8 @@ static inline void zend_pzval_unlock_free_func(zval *z)
}
}
#define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f)
#define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1)
#define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u)
#define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z)
#define PZVAL_LOCK(z) (z)->refcount++
#define RETURN_VALUE_UNUSED(pzn) (((pzn)->u.EA.type & EXT_TYPE_UNUSED))

View File

@ -2255,7 +2255,15 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
if (OP1_TYPE == IS_VAR &&
(opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
EX_T(opline->op1.u.var).var.fcall_returned_reference &&
EX_T(opline->op1.u.var).var.ptr) {
varptr = EX_T(opline->op1.u.var).var.ptr;
PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
} else {
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
}
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
EX_T(opline->op1.u.var).var.fcall_returned_reference) &&
varptr != &EG(uninitialized_zval) &&

View File

@ -7412,7 +7412,15 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR &&
(opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
EX_T(opline->op1.u.var).var.fcall_returned_reference &&
EX_T(opline->op1.u.var).var.ptr) {
varptr = EX_T(opline->op1.u.var).var.ptr;
PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
} else {
varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
}
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
EX_T(opline->op1.u.var).var.fcall_returned_reference) &&
varptr != &EG(uninitialized_zval) &&
@ -19465,7 +19473,15 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
varptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
if (IS_CV == IS_VAR &&
(opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
EX_T(opline->op1.u.var).var.fcall_returned_reference &&
EX_T(opline->op1.u.var).var.ptr) {
varptr = EX_T(opline->op1.u.var).var.ptr;
PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
} else {
varptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
}
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
EX_T(opline->op1.u.var).var.fcall_returned_reference) &&
varptr != &EG(uninitialized_zval) &&