diff options
author | Dmitry Stogov <dmitry@php.net> | 2005-04-27 06:47:08 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2005-04-27 06:47:08 +0000 |
commit | 28e68301dc63d0f61c226ca5c917a41ef2829247 (patch) | |
tree | 8c5d292a51c24d90733b7998533b1d95ca32a0e2 | |
parent | d30a9ee96d8bc129cf3370b8ecd0a8d76a2eec1a (diff) | |
download | php-git-28e68301dc63d0f61c226ca5c917a41ef2829247.tar.gz |
Fixed bug #32674 (exception in iterator causes crash)
-rw-r--r-- | Zend/tests/bug32674.phpt | 62 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 30 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 90 |
3 files changed, 182 insertions, 0 deletions
diff --git a/Zend/tests/bug32674.phpt b/Zend/tests/bug32674.phpt new file mode 100644 index 0000000000..547bcec096 --- /dev/null +++ b/Zend/tests/bug32674.phpt @@ -0,0 +1,62 @@ +--TEST-- +Bug #32674 exception in iterator causes crash +--FILE-- +<?php +class collection implements Iterator { + + private $_elements = array(); + + public function __construct() { + } + + public function rewind() { + reset($this->_elements); + } + + public function count() { + return count($this->_elements); + } + + public function current() { + $element = current($this->_elements); + return $element; + } + + public function next() { + $element = next($this->_elements); + return $element; + } + + public function key() { + $this->_fillCollection(); + $element = key($this->_elements); + return $element; + } + + public function valid() { + throw new Exception('shit happend'); + + return ($this->current() !== false); + } +} + +class class2 { + public $dummy; +} + +$obj = new class2(); +$col = new collection(); + +try { + foreach($col as $co) { + //irrelevant + } + echo 'shouldn`t get here'; + //$dummy = 'this will not crash'; + $obj->dummy = 'this will crash'; +} catch (Exception $e) { + echo "ok\n"; +} +?> +--EXPECT-- +ok diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index cb429c7cb4..58271a5d3f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2917,8 +2917,18 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) iter->index = 0; if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { zend_hash_internal_pointer_reset(fe_ht); if (ce) { @@ -3019,21 +3029,41 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) /* This could cause an endless loop if index becomes zero again. * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter TSRMLS_CC); + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } } if (!iter || (iter->index > 1 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) { /* reached end of iteration */ + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } ZEND_VM_SET_OPCODE(EX(op_array)->opcodes+opline->op2.u.opline_num); ZEND_VM_CONTINUE_JMP(); } iter->funcs->get_current_data(iter, &value TSRMLS_CC); if (!value) { /* failure in get_current_data */ + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } ZEND_VM_SET_OPCODE(EX(op_array)->opcodes+opline->op2.u.opline_num); ZEND_VM_CONTINUE_JMP(); } if (use_key) { if (iter->funcs->get_current_key) { key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC); + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } } else { key_type = HASH_KEY_IS_LONG; int_key = iter->index; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 11410483bd..dfc6b7a866 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1986,8 +1986,18 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) iter->index = 0; if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { zend_hash_internal_pointer_reset(fe_ht); if (ce) { @@ -4417,8 +4427,18 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) iter->index = 0; if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { zend_hash_internal_pointer_reset(fe_ht); if (ce) { @@ -7506,8 +7526,18 @@ static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) iter->index = 0; if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { zend_hash_internal_pointer_reset(fe_ht); if (ce) { @@ -7608,21 +7638,41 @@ static int ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) /* This could cause an endless loop if index becomes zero again. * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter TSRMLS_CC); + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } } if (!iter || (iter->index > 1 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) { /* reached end of iteration */ + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } ZEND_VM_SET_OPCODE(EX(op_array)->opcodes+opline->op2.u.opline_num); ZEND_VM_CONTINUE_JMP(); } iter->funcs->get_current_data(iter, &value TSRMLS_CC); if (!value) { /* failure in get_current_data */ + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } ZEND_VM_SET_OPCODE(EX(op_array)->opcodes+opline->op2.u.opline_num); ZEND_VM_CONTINUE_JMP(); } if (use_key) { if (iter->funcs->get_current_key) { key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC); + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } } else { key_type = HASH_KEY_IS_LONG; int_key = iter->index; @@ -18529,8 +18579,18 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) iter->index = 0; if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { zend_hash_internal_pointer_reset(fe_ht); if (ce) { @@ -30995,8 +31055,18 @@ static int ZEND_FE_RESET_HANDLER(ZEND_OPCODE_HANDLER_ARGS) iter->index = 0; if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; + if (EG(exception)) { + array_ptr->refcount--; + zval_ptr_dtor(&array_ptr); + ZEND_VM_NEXT_OPCODE(); + } } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { zend_hash_internal_pointer_reset(fe_ht); if (ce) { @@ -31097,21 +31167,41 @@ static int ZEND_FE_FETCH_HANDLER(ZEND_OPCODE_HANDLER_ARGS) /* This could cause an endless loop if index becomes zero again. * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter TSRMLS_CC); + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } } if (!iter || (iter->index > 1 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) { /* reached end of iteration */ + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } ZEND_VM_SET_OPCODE(EX(op_array)->opcodes+opline->op2.u.opline_num); ZEND_VM_CONTINUE_JMP(); } iter->funcs->get_current_data(iter, &value TSRMLS_CC); if (!value) { /* failure in get_current_data */ + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } ZEND_VM_SET_OPCODE(EX(op_array)->opcodes+opline->op2.u.opline_num); ZEND_VM_CONTINUE_JMP(); } if (use_key) { if (iter->funcs->get_current_key) { key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC); + if (EG(exception)) { + array->refcount--; + zval_ptr_dtor(&array); + ZEND_VM_NEXT_OPCODE(); + } } else { key_type = HASH_KEY_IS_LONG; int_key = iter->index; |