]> granicus.if.org Git - php/commitdiff
Fixed bug #79852
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 14 Jul 2020 10:30:50 +0000 (12:30 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 14 Jul 2020 10:31:06 +0000 (12:31 +0200)
NEWS
Zend/zend_interfaces.c
ext/dom/tests/bug79852.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 222789cf0128f15c7be5bedd3baebc791ed47b8a..8f349d1a999dbf6adbb07cb2e589327dbd9378fb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP                                                                        NEWS
     (Nikita)
   . Fixed bug #79828 (Segfault when trying to access non-existing variable).
     (Nikita)
+  . Fixed bug #79852 (count(DOMNodeList) doesn't match
+    count(IteratorIterator(DOMNodeList))). (Nikita)
 
 09 Jul 2020, PHP 8.0.0alpha2
 
index 68d0077795367aa1e5282df4cf087f574c3c7410..37c72ef5547c6d9a3e7b527c5cf7340b2400acb7 100644 (file)
@@ -469,6 +469,7 @@ ZEND_API int zend_create_internal_iterator_zval(zval *return_value, zval *obj) {
        zend_internal_iterator *intern =
                (zend_internal_iterator *) zend_internal_iterator_create(zend_ce_internal_iterator);
        intern->iter = iter;
+       intern->iter->index = 0;
        ZVAL_OBJ(return_value, &intern->std);
        return SUCCESS;
 }
@@ -559,8 +560,9 @@ ZEND_METHOD(InternalIterator, next) {
                RETURN_THROWS();
        }
 
-       intern->iter->funcs->move_forward(intern->iter);
+       /* Advance index first to match foreach behavior. */
        intern->iter->index++;
+       intern->iter->funcs->move_forward(intern->iter);
 }
 
 ZEND_METHOD(InternalIterator, valid) {
diff --git a/ext/dom/tests/bug79852.phpt b/ext/dom/tests/bug79852.phpt
new file mode 100644 (file)
index 0000000..67d5ede
--- /dev/null
@@ -0,0 +1,36 @@
+--TEST--
+Bug #79852: count(DOMNodeList) doesn't match count(IteratorIterator(DOMNodeList))
+--FILE--
+<?php
+
+$XML = <<< XML
+<root>
+  <item>1</item>
+  <item>2</item>
+  <item>3</item>
+</root>
+XML;
+
+$dom = new DomDocument();
+$dom->loadXml($XML);
+$items = $dom->getElementsByTagName('item');
+
+echo "Count: ".count($items)."\n";
+echo "Count: ".iterator_count($items->getIterator())."\n";
+$it = new IteratorIterator($items);
+echo "Count: ".iterator_count($it)."\n";
+echo "Count: ".iterator_count($it)."\n";
+
+?>
+--EXPECTF--
+Count: 3
+Count: 3
+Count: 3
+
+Fatal error: Uncaught Error: Iterator does not support rewinding in %s:%d
+Stack trace:
+#0 [internal function]: InternalIterator->rewind()
+#1 [internal function]: IteratorIterator->rewind()
+#2 %s(%d): iterator_count(Object(IteratorIterator))
+#3 {main}
+  thrown in %s on line %d