From: Dmitry Stogov Date: Wed, 12 Apr 2006 11:37:50 +0000 (+0000) Subject: Fixed bug #37046 (foreach breaks static scope) X-Git-Tag: php-5.1.3RC3~43 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f23d01ad4d7cbc5d1a0d382e1c896bdbfd9ad0d3;p=php Fixed bug #37046 (foreach breaks static scope) --- diff --git a/NEWS b/NEWS index b3be54834a..30ca4743e5 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? Apr 2006, PHP 5.1.3 +- Fixed bug #37046 (foreach breaks static scope). (Dmitry) - Fixed bug #37002 (Have to quote literals in INI when concatenating with - vars). (Dmitry) + vars). (Dmitry) 06 Apr 2006, PHP 5.1.3RC3 - Eliminated run-time constant fetching for TRUE, FALSE and NULL. (Dmitry) diff --git a/Zend/tests/bug37046.phpt b/Zend/tests/bug37046.phpt new file mode 100755 index 0000000000..8ade2a653c --- /dev/null +++ b/Zend/tests/bug37046.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #37046 (foreach breaks static scope) +--FILE-- + $function) { + echo "op1 $k\n"; + if ($k == 0) { + foreach (s() as $k => $function) { + echo "op2 $k\n"; + } + } +} +?> +--EXPEXT-- +op1 0 +op2 0 +op2 1 +op1 1 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 5c1ebc15c9..60851b418a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3017,7 +3017,20 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); } else { - array_ptr->refcount++; + if (OP1_TYPE == IS_VAR && + free_op1.var == NULL && + !array_ptr->is_ref && + array_ptr->refcount > 1) { + /* non-separated return value from function */ + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; + } else { + array_ptr->refcount++; + } } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4ce5c0f3be..be4a32c838 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2059,7 +2059,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - + zend_free_op free_op1; zval *array_ptr, **array_ptr_ptr; HashTable *fe_ht; zend_object_iterator *iter = NULL; @@ -2100,7 +2100,20 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); } else { - array_ptr->refcount++; + if (IS_CONST == IS_VAR && + free_op1.var == NULL && + !array_ptr->is_ref && + array_ptr->refcount > 1) { + /* non-separated return value from function */ + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; + } else { + array_ptr->refcount++; + } } } @@ -4518,7 +4531,20 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); } else { - array_ptr->refcount++; + if (IS_TMP_VAR == IS_VAR && + free_op1.var == NULL && + !array_ptr->is_ref && + array_ptr->refcount > 1) { + /* non-separated return value from function */ + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; + } else { + array_ptr->refcount++; + } } } @@ -7518,7 +7544,20 @@ static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); } else { - array_ptr->refcount++; + if (IS_VAR == IS_VAR && + free_op1.var == NULL && + !array_ptr->is_ref && + array_ptr->refcount > 1) { + /* non-separated return value from function */ + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; + } else { + array_ptr->refcount++; + } } } @@ -19576,7 +19615,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - + zend_free_op free_op1; zval *array_ptr, **array_ptr_ptr; HashTable *fe_ht; zend_object_iterator *iter = NULL; @@ -19617,7 +19656,20 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); } else { - array_ptr->refcount++; + if (IS_CV == IS_VAR && + free_op1.var == NULL && + !array_ptr->is_ref && + array_ptr->refcount > 1) { + /* non-separated return value from function */ + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; + } else { + array_ptr->refcount++; + } } }