--- /dev/null
+--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
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) {
/* 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;
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) {
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) {
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) {
/* 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;
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) {
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) {
/* 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;