| 
        php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
  [2012-09-02 01:58 UTC] softwareelves at gmail dot com
 Description:
------------
If you create a generator-closure inside of a function and call that function 
before returning it, it'll cause memory corruption causing a segfault.
Test script:
---------------
<?php
function test( array $array )
{
	$closure = function() use ( $array ) {
		var_dump( $array );
		yield "hi";
	};
	return $closure(); // if you return the $closure and call it outside this function it works.
}
$generator = test( array( 1, 2, 3 ) );
foreach( $generator as $something ) {
	// Segmentation fault: 11
}
Expected result:
----------------
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
Actual result:
--------------
Segmentation fault: 11
Patchesbug62991.patch (last revision 2012-09-04 06:56 UTC by dmitry at zend dot com)bug62991.phpt (last revision 2012-09-02 11:50 UTC by laruence@php.net) Pull RequestsHistoryAllCommentsChangesGit/SVN commits             
             | 
    |||||||||||||||||||||||||||
            
                 
                Copyright © 2001-2025 The PHP GroupAll rights reserved.  | 
        Last updated: Tue Nov 04 03:00:01 2025 UTC | 
@laruence: The patch looks fine for me. The only thing that looks strange are these whitespace changes: -ZEND_BEGIN_ARG_INFO_EX(arginfo_closure_bindto, 0, 0, 1) + ZEND_BEGIN_ARG_INFO_EX(arginfo_closure_bindto, 0, 0, 1) ZEND_ARG_INFO(0, newthis) ZEND_ARG_INFO(0, newscope) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_closure_bind, 0, 0, 2) + ZEND_BEGIN_ARG_INFO_EX(arginfo_closure_bind, 0, 0, 2) ZEND_ARG_INFO(0, closure) ZEND_ARG_INFO(0, newthis) ZEND_ARG_INFO(0, newscope) ZEND_END_ARG_INFO() -static const zend_function_entry closure_functions[] = { - ZEND_ME(Closure, __construct, NULL, ZEND_ACC_PRIVATE) - ZEND_ME(Closure, bind, arginfo_closure_bind, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - ZEND_MALIAS(Closure, bindTo, bind, arginfo_closure_bindto, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; + static const zend_function_entry closure_functions[] = { + ZEND_ME(Closure, __construct, NULL, ZEND_ACC_PRIVATE) + ZEND_ME(Closure, bind, arginfo_closure_bind, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_MALIAS(Closure, bindTo, bind, arginfo_closure_bindto, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} + }; Looks like the indentation is slightly off there :)Oh, and also, I think it would be a little bit nicer if this: + if (execute_data->op_array->fn_flags & ZEND_ACC_CLOSURE) { + destroy_op_array(execute_data->op_array); + efree(execute_data->op_array); + } would be written as: + if (op_array->fn_flags & ZEND_ACC_CLOSURE) { + destroy_op_array(op_array); + efree(op_array); + } There already is a local op_array variable for execute_data->op_array, so it's a bit shorter to use ;)