From: Dmitry Stogov Date: Mon, 17 Aug 2009 07:40:18 +0000 (+0000) Subject: Fixed bug #49269 (Ternary operator fails on Iterator object when used inside foreach... X-Git-Tag: php-5.2.11RC2~53 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2a6b53de4b8ad11d7c148a8126691bd30245d788;p=php Fixed bug #49269 (Ternary operator fails on Iterator object when used inside foreach declaration). (Etienne, Dmitry) --- diff --git a/NEWS b/NEWS index 6aa13422a8..2b81839b10 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2009, PHP 5.2.11 +- Fixed bug #49269 (Ternary operator fails on Iterator object when used inside + foreach declaration). (Etienne, Dmitry) + - Added missing sanity checks around exif processing (Ilia) 13 Aug 2009, PHP 5.2.11RC1 diff --git a/Zend/tests/bug49269.phpt b/Zend/tests/bug49269.phpt new file mode 100644 index 0000000000..2de29d8b93 --- /dev/null +++ b/Zend/tests/bug49269.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #49269 (Ternary operator fails on Iterator object when used inside foreach declaration). +--FILE-- +n < 3); + } + function current() {return $this->n;} + function next() {$this->n++;} + function key() { } + function rewind() {$this->n = 0;} +} + + +$array_object = new TestObject(); + +foreach ((true ? $array_object : $array_object) as $item) echo "$item\n"; +?> +--EXPECT-- +0 +1 +2 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 205724dbc5..bc38c31447 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3196,15 +3196,22 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + array_ptr->refcount--; + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { array_ptr->refcount++; } } else { - if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && + if (OP1_TYPE == IS_CONST || + ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && !array_ptr->is_ref && - array_ptr->refcount > 1) { + array_ptr->refcount > 1)) { zval *tmp; ALLOC_ZVAL(tmp); @@ -3217,7 +3224,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) } } - if (OP1_TYPE != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 37b493bb83..5d431eadb1 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2230,15 +2230,22 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + array_ptr->refcount--; + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { array_ptr->refcount++; } } else { - if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && + if (IS_CONST == IS_CONST || + ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && !array_ptr->is_ref && - array_ptr->refcount > 1) { + array_ptr->refcount > 1)) { zval *tmp; ALLOC_ZVAL(tmp); @@ -2251,7 +2258,7 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } - if (IS_CONST != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { @@ -4805,15 +4812,22 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + array_ptr->refcount--; + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { array_ptr->refcount++; } } else { - if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && + if (IS_TMP_VAR == IS_CONST || + ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && !array_ptr->is_ref && - array_ptr->refcount > 1) { + array_ptr->refcount > 1)) { zval *tmp; ALLOC_ZVAL(tmp); @@ -4826,7 +4840,7 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } - if (IS_TMP_VAR != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { @@ -7954,15 +7968,22 @@ static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + array_ptr->refcount--; + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { array_ptr->refcount++; } } else { - if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && + if (IS_VAR == IS_CONST || + ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && !array_ptr->is_ref && - array_ptr->refcount > 1) { + array_ptr->refcount > 1)) { zval *tmp; ALLOC_ZVAL(tmp); @@ -7975,7 +7996,7 @@ static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } - if (IS_VAR != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { @@ -20364,15 +20385,22 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + array_ptr->refcount--; + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { array_ptr->refcount++; } } else { - if ((IS_CV == IS_CV || IS_CV == IS_VAR) && + if (IS_CV == IS_CONST || + ((IS_CV == IS_CV || IS_CV == IS_VAR) && !array_ptr->is_ref && - array_ptr->refcount > 1) { + array_ptr->refcount > 1)) { zval *tmp; ALLOC_ZVAL(tmp); @@ -20385,7 +20413,7 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } - if (IS_CV != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) {