@@ -250,6 +250,10 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
250250 zend_class_entry * ce ;
251251 zval retval , child ;
252252 zend_object_iterator * sub_iter ;
253+ zend_object * sub_object ;
254+ uint32_t prev_level ;
255+ zend_result valid_result ;
256+ bool reentered ;
253257
254258 SPL_FETCH_SUB_ITERATOR (iterator , object );
255259
@@ -269,7 +273,17 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
269273 iterator = object -> iterators [object -> level ].iterator ;
270274 ZEND_FALLTHROUGH ;
271275 case RS_START :
272- if (iterator -> funcs -> valid (iterator ) == FAILURE ) {
276+ sub_object = Z_OBJ (object -> iterators [object -> level ].zobject );
277+ prev_level = object -> level ;
278+ GC_ADDREF (sub_object );
279+ valid_result = iterator -> funcs -> valid (iterator );
280+ reentered = object -> level != prev_level
281+ || object -> iterators [object -> level ].iterator != iterator ;
282+ OBJ_RELEASE (sub_object );
283+ if (reentered ) {
284+ return ;
285+ }
286+ if (valid_result == FAILURE ) {
273287 break ;
274288 }
275289 object -> iterators [object -> level ].state = RS_TEST ;
@@ -417,7 +431,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
417431 }
418432 }
419433 }
420- if (object -> level > 0 ) {
434+ if (object -> level > 0 && object -> iterators [ object -> level ]. iterator == iterator ) {
421435 zval garbage ;
422436 ZVAL_COPY_VALUE (& garbage , & object -> iterators [object -> level ].zobject );
423437 ZVAL_UNDEF (& object -> iterators [object -> level ].zobject );
0 commit comments