php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68774 Calling a member variable as a function in a closure causes a crash
Submitted: 2015-01-09 09:11 UTC Modified: 2015-01-09 15:54 UTC
From: beerend dot lauwers at capgemini dot com Assigned:
Status: Wont fix Package: Class/Object related
PHP Version: 5.5.20 OS: Windows 7
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: beerend dot lauwers at capgemini dot com
New email:
PHP Version: OS:

 

 [2015-01-09 09:11 UTC] beerend dot lauwers at capgemini dot com
Description:
------------
Let's say we have a member variable $foo, which will hold something callable. 

We then assign to $foo a closure, say, function($x){ return $x; }:

$this->foo = function($x) { return $x; };

Then, we assign to $foo a new closure, which brings into a scope another closure:

$another_f = function($x) { return $x; };
$this->foo = function() use ($another_f) {
  $args = func_get_args();
  call_user_func_array( $this->foo, $args ); // Crash occurs here
  call_user_func_array( $another_f, $args );
};

The PHP process will crash on the line where it calls $this->foo as a function. Probably recurses into an infinite loop.

Test script:
---------------
https://gist.github.com/BeerendLauwers/c28585ce4868ab42d2f9

Expected result:
----------------
The value returned from $t->apply() should return TRUE.

Actual result:
--------------
PHP process crashes. As a workaround, you can assign $this->foo to a placeholder variable and bring it into scope into the closure via use, which will bind it correctly:

$placeholder = $this->foo;
$another_f = function($x) { return $x; };
$this->foo = function() use ($another_f,$placeholder) {
  $args = func_get_args();
  call_user_func_array( $placeholder, $args );
  call_user_func_array( $another_f, $args );
};

Perhaps make it illegal to call a member variable as a function while assigning it to itself, because the value of $this->foo is not captured correctly by the closure.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-01-09 15:54 UTC] ab@php.net
-Status: Open +Status: Wont fix
 [2015-01-09 15:54 UTC] ab@php.net
The issue in the first place is that the function happens to be recursive. This can be shown by this snippet:

function a() {call_user_func('a');} a();

This leads to the stack overflow. You should ensure the function would terminate, or avoid passing the function to itself.

Thanks.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Jul 01 12:01:36 2025 UTC