Edit report at http://bugs.php.net/bug.php?id=54367&edit=1
ID: 54367 Updated by: tony2...@php.net Reported by: jpa...@php.net Summary: Use of closure causes problem in ArrayAccess -Status: Closed +Status: Re-Opened Type: Bug Package: Scripting Engine problem Operating System: *nix PHP Version: 5.3.6 Assigned To: dmitry Block user comment: N Private report: N New Comment: The test for this bug causes invalid read and subsequent segfault in 5_3 (but works fine in trunk): ==17645== Invalid read of size 8 ==17645== at 0x93625F: _zval_ptr_dtor (zend_execute_API.c:446) ==17645== by 0x97BAD6: zend_leave_helper_SPEC (zend_vm_execute.h:167) ==17645== by 0x980ACE: ZEND_RETURN_SPEC_CONST_HANDLER (zend_vm_execute.h:1714) ==17645== by 0x97B8E6: execute (zend_vm_execute.h:107) ==17645== by 0x947FBE: zend_execute_scripts (zend.c:1194) ==17645== by 0x8D2E56: php_execute_script (main.c:2275) ==17645== by 0xA2C0A5: main (php_cli.c:1193) ==17645== Address 0xa74fb98 is 56 bytes inside a block of size 264 free'd ==17645== at 0x4C2599C: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==17645== by 0x922C77: _efree (zend_alloc.c:2358) ==17645== by 0x96F0A9: zend_closure_free_storage (zend_closures.c:190) ==17645== by 0x975C47: zend_objects_store_del_ref_by_handle_ex (zend_objects_API.c:220) ==17645== by 0x9759AE: zend_objects_store_del_ref (zend_objects_API.c:172) ==17645== by 0x945591: _zval_dtor_func (zend_variables.c:52) ==17645== by 0x93528B: _zval_dtor (zend_variables.h:35) ==17645== by 0x93625A: _zval_ptr_dtor (zend_execute_API.c:445) ==17645== by 0x97BAD6: zend_leave_helper_SPEC (zend_vm_execute.h:167) ==17645== by 0x980ACE: ZEND_RETURN_SPEC_CONST_HANDLER (zend_vm_execute.h:1714) ==17645== by 0x97B8E6: execute (zend_vm_execute.h:107) ==17645== by 0x947FBE: zend_execute_scripts (zend.c:1194) Previous Comments: ------------------------------------------------------------------------ [2011-04-20 15:00:11] dmi...@php.net This bug has been fixed in SVN. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. Thank you for the report, and for helping us make PHP better. ------------------------------------------------------------------------ [2011-04-20 14:59:21] dmi...@php.net Automatic comment from SVN on behalf of dmitry Revision: http://svn.php.net/viewvc/?view=revision&revision=310389 Log: Fixed bug #54367 (Use of closure causes problem in ArrayAccess). ------------------------------------------------------------------------ [2011-03-25 09:55:25] jpa...@php.net Felipe: strange, I got no crash with your code (5.3.6,Linux, self-compiled) ------------------------------------------------------------------------ [2011-03-24 22:49:49] fel...@php.net I can reproduce a crash with: <?php class MyObjet implements ArrayAccess { public function __construct() { } public function offsetSet($offset, $value) { } public function offsetExists($offset) { } public function offsetUnset($offset) { } public function offsetGet ($offset) { return function () { }; } } $a = new MyObjet(); echo $a['p']('foo'); ?> Breakpoint 1, 0x085368b3 in ZEND_SEND_VAL_SPEC_CONST_HANDLER (execute_data=0x8ade614, tsrm_ls=0x89022a0) at /home/felipe/dev/php5/Zend/zend_vm_execute.h:1719 1719 && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { (gdb) p execute_data->fbc->common $7 = {type = 90 'Z', function_name = 0x5a5a5a5a <Address 0x5a5a5a5a out of bounds>, scope = 0x5a5a5a5a, fn_flags = 1515870810, prototype = 0x5a5a5a5a, num_args = 1515870810, required_num_args = 1515870810, arg_info = 0x5a5a5a5a, pass_rest_by_reference = 90 'Z', return_reference = 90 'Z'} ------------------------------------------------------------------------ [2011-03-24 13:52:23] jpa...@php.net Description: ------------ Closures cant use variables from external context when the context is in ArrayAccess method Test script: --------------- <?php class MyObjet implements ArrayAccess { // All the stuff for ArrayAccess public function offsetGet ($offset) { return function ($var) use ($offset) { // here is the problem return sprintf('<%s>%s</%$1s>', $offset, $var); }; } } $a = new MyObjet(); echo $a['p']('foo'); Expected result: ---------------- <p>foo</p> Actual result: -------------- PHP Notice: Undefined variable: offset in {file.php} on line 11 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=54367&edit=1