|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-01-23 22:43 UTC] matej21 at matej21 dot cz
Description: ------------ AppendIterator produces a segfault when it iterates over an empty generator. https://3v4l.org/q3I67 Test script: --------------- <?php function foo() { foreach ([] as $foo) { yield $foo; } } $iterator = new AppendIterator(); $iterator->append(foo()); var_dump(iterator_to_array($iterator)); Expected result: ---------------- array(0) { } Actual result: -------------- Program received signal SIGSEGV, Segmentation fault. #0 spl_dual_it_rewind (intern=0x7fffed2783c0) at /usr/local/src/php/ext/spl/spl_iterators.c:1682 #1 spl_append_it_next_iterator (intern=intern@entry=0x7fffed2783c0) at /usr/local/src/php/ext/spl/spl_iterators.c:3332 #2 0x000000000071fff4 in zim_spl_AppendIterator_rewind (execute_data=<optimized out>, return_value=<optimized out>) at /usr/local/src/php/ext/spl/spl_iterators.c:3403 #3 0x00000000008157df in zend_call_function (fci=fci@entry=0x7fffffffa410, fci_cache=fci_cache@entry=0x7fffffffa3e0) at /usr/local/src/php/Zend/zend_execute_API.c:879 #4 0x000000000083ec54 in zend_call_method (object=object@entry=0x7fffed2691f8, obj_ce=<optimized out>, fn_proxy=0x1287000, function_name=function_name@entry=0x989d4c "rewind", function_name_len=function_name_len@entry=6, retval_ptr=retval_ptr@entry=0x0, param_count=param_count@entry=0, arg1=arg1@entry=0x0, arg2=arg2@entry=0x0) at /usr/local/src/php/Zend/zend_interfaces.c:104 #5 0x000000000083f25a in zend_user_it_rewind (_iter=0x7fffed2691c0) at /usr/local/src/php/Zend/zend_interfaces.c:245 #6 0x0000000000720212 in spl_iterator_apply (obj=<optimized out>, apply_func=0x719ae0 <spl_iterator_to_array_apply>, puser=puser@entry=0x7fffed2130f0) at /usr/local/src/php/ext/spl/spl_iterators.c:3503 #7 0x00000000007202e5 in zif_iterator_to_array (execute_data=<optimized out>, return_value=0x7fffed2130f0) at /usr/local/src/php/ext/spl/spl_iterators.c:3590 #8 0x000000000089c12b in ZEND_DO_FCALL_SPEC_HANDLER () at /usr/local/src/php/Zend/zend_vm_execute.h:842 #9 0x000000000085ed3b in execute_ex (ex=<optimized out>) at /usr/local/src/php/Zend/zend_vm_execute.h:414 #10 0x00000000008a7c27 in zend_execute (op_array=0x7fffed283000, op_array@entry=0x7fffed288180, return_value=return_value@entry=0x7fffed213030) at /usr/local/src/php/Zend/zend_vm_execute.h:458 #11 0x0000000000823494 in zend_execute_scripts (type=type@entry=8, retval=0x7fffed213030, retval@entry=0x0, file_count=file_count@entry=3) at /usr/local/src/php/Zend/zend.c:1427 #12 0x00000000007c7698 in php_execute_script (primary_file=primary_file@entry=0x7fffffffc9c0) at /usr/local/src/php/main/main.c:2484 #13 0x00000000008a97f3 in do_cli (argc=2, argv=0x119cc10) at /usr/local/src/php/sapi/cli/php_cli.c:974 #14 0x000000000044d9e0 in main (argc=2, argv=0x119cc10) at /usr/local/src/php/sapi/cli/php_cli.c:1345 PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 22:00:02 2025 UTC |
with a quick fix (check null pointer) : diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index c6181d9..bb86e76 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1682,7 +1682,7 @@ static inline void spl_dual_it_rewind(spl_dual_it_object *intern TSRMLS_DC) { spl_dual_it_free(intern TSRMLS_CC); intern->current.pos = 0; - if (intern->inner.iterator->funcs->rewind) { + if (intern->inner.iterator && intern->inner.iterator->funcs->rewind) { intern->inner.iterator->funcs->rewind(intern->inner.iterator TSRMLS_CC); } } will get: Fatal error: Uncaught exception 'Exception' with message 'Cannot traverse an already closed generator' in /tmp/1.php:9 Stack trace: #0 [internal function]: AppendIterator->rewind() #1 /tmp/1.php(9): iterator_to_array(Object(AppendIterator)) #2 {main} thrown in /tmp/1.php on line 9 which seems not quite reasonable error message. @nikic, what do you think?Possibly related: ------------------------------------------------------- #0 zend_mm_alloc_small (size=56, bin_num=6, heap=0x7f8c9de00040) at /src/php-7.1.2/Zend/zend_alloc.c:1261 #1 _emalloc_56 () at /src/php-7.1.2/Zend/zend_alloc.c:2336 #2 0x000000000080d7a0 in _array_init (arg=arg@entry=0x7ffffdaf06f0, size=size@entry=0) at /src/php-7.1.2/Zend/zend_API.c:1060 #3 0x0000000000824f31 in zend_fetch_debug_backtrace (return_value=return_value@entry=0x7ffffdaf0780, skip_last=skip_last@entry=0, options=options@entry=0, limit=limit@entry=0) at /src/php-7.1.2/Zend/zend_builtin_functions.c:2612 #4 0x000000000082bb0f in zend_default_exception_new_ex (class_type=0x2015d80, skip_top_traces=0) at /src/php-7.1.2/Zend/zend_exceptions.c:216 #5 0x000000000080df3b in _object_and_properties_init (arg=arg@entry=0x7ffffdaf07f0, class_type=class_type@entry=0x2015d80, properties=properties@entry=0x0) at /src/php-7.1.2/Zend/zend_API.c:1302 #6 0x000000000080e047 in _object_init_ex (arg=arg@entry=0x7ffffdaf07f0, class_type=class_type@entry=0x2015d80) at /src/php-7.1.2/Zend/zend_API.c:1310 #7 0x0000000000438429 in zend_throw_exception (exception_ce=0x2015d80, exception_ce@entry=0x0, message=message@entry=0xdf6b78 "Cannot traverse an already closed generator", code=code@entry=0) at /src/php-7.1.2/Zend/zend_exceptions.c:922 #8 0x00000000008365ee in zend_generator_get_iterator (ce=<optimized out>, object=0x7f8c9de13980, by_ref=<optimized out>) at /src/php-7.1.2/Zend/zend_generators.c:1186 #9 0x00000000006e59c5 in spl_iterator_apply (obj=<optimized out>, apply_func=0x6df320 <spl_iterator_to_values_apply>, puser=puser@entry=0x7f8c9de13920) at /src/php-7.1.2/ext/spl/spl_iterators.c:3495 #10 0x00000000006e5af5 in zif_iterator_to_array (execute_data=<optimized out>, return_value=0x7f8c9de13920) at /src/php-7.1.2/ext/spl/spl_iterators.c:3590 #11 0x00000000008aa572 in ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER () at /src/php-7.1.2/Zend/zend_vm_execute.h:876 #12 0x000000000085215b in execute_ex (ex=<optimized out>) at /src/php-7.1.2/Zend/zend_vm_execute.h:429 #13 0x0000000000836c32 in zend_generator_resume (orig_generator=0x7f8c9de00040) at /src/php-7.1.2/Zend/zend_generators.c:817 #14 0x00000000008696b9 in ZEND_FE_FETCH_R_SPEC_VAR_HANDLER () at /src/php-7.1.2/Zend/zend_vm_execute.h:16816 #15 0x000000000085215b in execute_ex (ex=<optimized out>) at /src/php-7.1.2/Zend/zend_vm_execute.h:429 #16 0x0000000000836c32 in zend_generator_resume (orig_generator=0x7f8c9de00040) at /src/php-7.1.2/Zend/zend_generators.c:817 #17 0x00000000008696b9 in ZEND_FE_FETCH_R_SPEC_VAR_HANDLER () at /src/php-7.1.2/Zend/zend_vm_execute.h:16816 #18 0x000000000085215b in execute_ex (ex=<optimized out>) at /src/php-7.1.2/Zend/zend_vm_execute.h:429 #19 0x00000000008ad410 in zend_execute (op_array=0x7f8c9de7d000, op_array@entry=0x7f8c9d089d00, return_value=return_value@entry=0x7f8c9de13500) at /src/php-7.1.2/Zend/zend_vm_execute.h:474 #20 0x000000000080b834 in zend_execute_scripts (type=type@entry=8, retval=0x7f8c9de13500, retval@entry=0x0, file_count=file_count@entry=3) at /src/php-7.1.2/Zend/zend.c:1475 #21 0x00000000007abfb0 in php_execute_script (primary_file=0x7ffffdaf3060) at /src/php-7.1.2/main/main.c:2537 #22 0x00000000008af59a in do_cli (argc=-1646264256, argv=0x0) at /src/php-7.1.2/sapi/cli/php_cli.c:993 #23 0x000000000043a36c in main (argc=-1646264256, argv=0x0) at /src/php-7.1.2/sapi/cli/php_cli.c:1381You just need to use NoRewindIterator: <?php function foo() { foreach ([] as $foo) { yield $foo; } } $append = new AppendIterator(); $append->append(new NoRewindIterator(foo())); var_dump(iterator_to_array($append));