Skip to content

Fixed bug #48770: when call_user_func() fails to call parent from inheriting class #375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

p495
Copy link

@p495 p495 commented Jul 3, 2013

When using call_user_function() with parent::, self:: or static:: prefix we need to check current class scop, or result well be unexpected.

@weltling
Copy link
Contributor

weltling commented Jul 8, 2013

Tested and it looks good. However it's a big behavior change, despite it's bug. On that note it might have more sense this patch to go into master only.

@@ -3107,7 +3108,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
if (Z_OBJ_HANDLER_P(callable, get_closure) && Z_OBJ_HANDLER_P(callable, get_closure)(callable, &fcc->calling_scope, &fcc->function_handler, &fcc->object_ptr TSRMLS_CC) == SUCCESS) {
fcc->called_scope = fcc->calling_scope;
if (callable_name) {
zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why delete the comment?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very old comment from 2001.
All overload logic was moved to zend_is_callable_check_class() by Dmitry Stogonov in 2008, when LSB was merget.
In fact, this comment very confusing, so I decided to remove it.

@smalyshev
Copy link
Contributor

This patch introduces a BC break as and such can not be merged into 5.4 (and I'm not sure if at all). Test code:

class A {
  function foo() {
    echo "I am A\n";
  }
}

class B extends A {
  function foo() {
    echo "I am B\n";
  }
  function who() {
        var_dump(get_class($this));
        call_user_func_array(array($this, "foo"), array());
  }
}

class C extends B {
  function foo() {
    echo "I am C\n";
  }

  function who() {
        var_dump(get_class($this));
        call_user_func_array(array($this, "foo"), array());
        parent::who();
  }
}

$c = new C;
$c->who();

Without the patch:

string(1) "C"
I am C
string(1) "C"
I am C

with the patch:

string(1) "C"
I am C
string(1) "C"
I am B

BC break and I'm not sure it's even right to call B's function when given C object. Note there's no "parent" in this example for call_user_func_array.

@smalyshev
Copy link
Contributor

Also note that this would change a scope on the call even if we used not $this but any other object from the same class hierarchy, which also sounds wrong.

@weltling
Copy link
Contributor

Oh, of course, overseen that ... while expanding the limitation of 'self' it breaks $this.

@php-pulls
Copy link

Comment on behalf of stas at php.net:

Closing pull for now as it produces BC break, please reopen or submit new pull with fixed code.

@php-pulls php-pulls closed this Jul 22, 2013
@p495
Copy link
Author

p495 commented Sep 3, 2013

Guys, thank you for taking time and viewing my code.
Smalyshev, thank you for the test. I'll try to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants