mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
Fixed bug #32674 (exception in iterator causes crash)
This commit is contained in:
parent
d30a9ee96d
commit
28e68301dc
62
Zend/tests/bug32674.phpt
Normal file
62
Zend/tests/bug32674.phpt
Normal file
@ -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
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user