]> granicus.if.org Git - php/commitdiff
Fixed bug #32674 (exception in iterator causes crash)
authorDmitry Stogov <dmitry@php.net>
Wed, 27 Apr 2005 06:47:08 +0000 (06:47 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 27 Apr 2005 06:47:08 +0000 (06:47 +0000)
Zend/tests/bug32674.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug32674.phpt b/Zend/tests/bug32674.phpt
new file mode 100644 (file)
index 0000000..547bcec
--- /dev/null
@@ -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
index cb429c7cb4c59120b07d8c38f9254343182c1bfa..58271a5d3f1d841404c8b42881f22f09171a12fc 100644 (file)
@@ -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;
index 11410483bd4046d8e41459634e570538450a7c64..dfc6b7a8661f3c0ccab12dd48c82774e9f7ed440 100644 (file)
@@ -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;