Use of closure causes problem in ArrayAccess

Bug #54367 Use of closure causes problem in ArrayAccess
Submitted: 2011-03-24 13:52 UTC Modified: 2011-05-11 08:58 UTC
From: jpauli@php.net Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3.6 OS: *nix
Private report: No CVE-ID: None

 [2011-03-24 13:52 UTC] jpauli@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

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

 [2011-03-24 22:49 UTC] felipe@php.net

-Status: Open +Status: Assigned -Assigned To: +Assigned To: dmitry

 [2011-03-24 22:49 UTC] felipe@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-25 09:55 UTC] jpauli@php.net

Felipe: strange, I got no crash with your code (5.3.6,Linux, self-compiled)

 [2011-04-20 15:00 UTC] dmitry@php.net

-Status: Assigned +Status: Closed

 [2011-04-20 15:00 UTC] dmitry@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-05-10 18:36 UTC] tony2001@php.net

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)

 [2011-05-11 08:58 UTC] dmitry@php.net

-Status: Re-Opened +Status: Closed

 [2011-05-11 08:58 UTC] dmitry@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.