]> granicus.if.org Git - php/commitdiff
- MFH Fixed Bug #37457 (Crash when an exception is thrown in accept() method of Filte...
authorMarcus Boerger <helly@php.net>
Tue, 16 May 2006 08:21:08 +0000 (08:21 +0000)
committerMarcus Boerger <helly@php.net>
Tue, 16 May 2006 08:21:08 +0000 (08:21 +0000)
NEWS
ext/spl/spl_iterators.c
ext/spl/tests/bug37457.phpt [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index 9d16f9ab62d54ffdd8fd602edf3f7de0bf30dc39..dcbfe0d1815ac3542a2ed4feb94660529cd230df 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,8 @@ PHP                                                                        NEWS
 - Added pg_field_table() function. (Edin)
 - Added implementation of curl_multi_info_read(). (Brian)
 - Added RFC2397 (data: stream) support. (Marcus)
+- Fixed Bug #37457 (Crash when an exception is thrown in accept() method of 
+  FilterIterator). (Marcus)
 - Fixed bug #37416 (iterator_to_array() hides exceptions thrown in rewind()
   method). (Tony)
 - Fixed bug #37413 (Rejected versions of flex that don't work). (Ilia)
index 1a40ad4db1cb7a8486a9cf509b52667bc29c665e..070c2f92765e8dfe1f26524230b1ff8ba5672fc9 100755 (executable)
@@ -1173,7 +1173,9 @@ static inline void spl_filter_it_fetch(zval *zthis, spl_dual_it_object *intern T
                        }
                        zval_ptr_dtor(&retval);
                }
-
+               if (EG(exception)) {
+                       return;
+               }
                intern->inner.iterator->funcs->move_forward(intern->inner.iterator TSRMLS_CC);
        }
        spl_dual_it_free(intern TSRMLS_CC);
@@ -1653,11 +1655,14 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC)
                        zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval);
                        if (zend_is_true(retval)) {
                                zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren);
-                               if (EG(exception) && intern->u.caching.flags & CIT_CATCH_GET_CHILD) {
-                                       zend_clear_exception(TSRMLS_C);
+                               if (EG(exception)) {
                                        if (zchildren) {
                                                zval_ptr_dtor(&zchildren);
                                        }
+                                       if (intern->u.caching.flags & CIT_CATCH_GET_CHILD) {
+                                               zend_clear_exception(TSRMLS_C);
+                                       }
+                                       return;
                                } else {
                                        INIT_PZVAL(&zflags);
                                        ZVAL_LONG(&zflags, intern->u.caching.flags & CIT_PUBLIC);
diff --git a/ext/spl/tests/bug37457.phpt b/ext/spl/tests/bug37457.phpt
new file mode 100755 (executable)
index 0000000..e66fa4d
--- /dev/null
@@ -0,0 +1,80 @@
+--TEST--
+Bug #37457 (Crash when an exception is thrown in accept() method of FilterIterator)
+--FILE--
+<?php
+
+class Collection implements Iterator
+{
+       protected $array, $valid = false;
+       
+       public function __construct(array $a)
+       {
+               echo __METHOD__ . "\n";
+               $this->array = $a;
+       }
+       
+       public function current()
+       {
+               echo __METHOD__ . "\n";
+               return current($this->array);
+       }
+
+       public function key()
+       {
+               echo __METHOD__ . "\n";
+               return key($this->array);
+       }
+
+       public function next()
+       {
+               echo __METHOD__ . "\n";
+               $this->valid = (false !== next($this->array));
+       }
+
+       public function valid()
+       {
+               echo __METHOD__ . "\n";
+               return $this->valid;
+       }
+
+       public function rewind()
+       {
+               echo __METHOD__ . "\n";
+               $this->valid = (false !== reset($this->array));
+       }
+}
+
+class TestFilter extends FilterIterator
+{
+    public function accept()
+    {
+               echo __METHOD__ . "\n";
+       throw new Exception("Failure in Accept");
+    }
+}
+
+$test = new TestFilter(new Collection(array(0)));
+
+try
+{
+       foreach ($test as $item)
+       {
+               echo $item;
+       }
+}
+catch (Exception $e)
+{
+       var_dump($e->getMessage());
+}
+
+?>
+===DONE===
+--EXPECTF--
+Collection::__construct
+Collection::rewind
+Collection::valid
+Collection::current
+Collection::key
+TestFilter::accept
+string(17) "Failure in Accept"
+===DONE===