From: Nikita Popov Date: Tue, 14 Jul 2020 10:30:50 +0000 (+0200) Subject: Fixed bug #79852 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=70501b81a75c7c4cd0ec3a121e290e561829deb9;p=php Fixed bug #79852 --- diff --git a/NEWS b/NEWS index 222789cf01..8f349d1a99 100644 --- 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 diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 68d0077795..37c72ef554 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -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 index 0000000000..67d5edeca3 --- /dev/null +++ b/ext/dom/tests/bug79852.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #79852: count(DOMNodeList) doesn't match count(IteratorIterator(DOMNodeList)) +--FILE-- + + 1 + 2 + 3 + +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