diff options
author | Dmitry Stogov <dmitry@php.net> | 2009-08-17 07:40:43 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2009-08-17 07:40:43 +0000 |
commit | f694c09a359e48f0d2c1440f55af4b5ec5303f03 (patch) | |
tree | 366b79ae602464e412265b20fe85f626a790f951 /Zend | |
parent | 4687f6e0ba47b083cd838af5d1b1812d11564b22 (diff) | |
download | php-git-f694c09a359e48f0d2c1440f55af4b5ec5303f03.tar.gz |
Fixed bug #49269 (Ternary operator fails on Iterator object when used inside foreach declaration). (Etienne, Dmitry)
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/tests/bug49269.phpt | 26 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 31 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 124 |
3 files changed, 116 insertions, 65 deletions
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-- +<?php +class TestObject implements Iterator +{ + public $n = 0; + function valid() + { + return ($this->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 dbf5e3af69..96b4d7f1a1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3573,28 +3573,33 @@ 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) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (OP1_TYPE == IS_CONST || + ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - 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 43bc3abde5..f809f4e740 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2108,28 +2108,33 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A 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) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_CONST == IS_CONST || + ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - 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)) { @@ -5370,28 +5375,33 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG 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) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_TMP_VAR == IS_CONST || + ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - 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)) { @@ -8717,28 +8727,33 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG 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) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_VAR == IS_CONST || + ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - 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)) { @@ -22559,28 +22574,33 @@ static int ZEND_FASTCALL 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) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_CV == IS_CONST || + ((IS_CV == IS_CV || IS_CV == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_CV == IS_CV || IS_CV == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - 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)) { |