-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
Changes from all commits
3f29ce5
4c07103
8a0b169
2aaf0d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--TEST-- | ||
Testing call_user_func with self call in same class (not parent) | ||
--FILE-- | ||
<?php | ||
|
||
class A { | ||
public static function func($str) { | ||
var_dump(__METHOD__ .': '. $str); | ||
} | ||
public function run($str) { | ||
call_user_func(array($this, 'self::func'), $str); | ||
call_user_func('self::func', $str); | ||
} | ||
} | ||
|
||
class B extends A { | ||
public static function func($str) { | ||
print "This method shouldn't be called when using self::func!\n"; | ||
} | ||
} | ||
|
||
$c = new B; | ||
$c->run('This should work!'); | ||
|
||
?> | ||
--EXPECTF-- | ||
%unicode|string%(26) "A::func: This should work!" | ||
%unicode|string%(26) "A::func: This should work!" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3049,9 +3049,10 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch | |
return 0; | ||
} | ||
|
||
fcc->calling_scope = Z_OBJCE_PP(obj); /* TBFixed: what if it's overloaded? */ | ||
|
||
fcc->object_ptr = *obj; | ||
fcc->calling_scope = instanceof_function(Z_OBJCE_PP(obj), EG(scope) TSRMLS_CC) | ||
? EG(scope) | ||
: Z_OBJCE_PP(obj); | ||
|
||
if (callable_name) { | ||
char *ptr; | ||
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why delete the comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is very old comment from 2001. |
||
zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */ | ||
zend_class_entry *ce = Z_OBJCE_P(callable); | ||
|
||
*callable_name_len = ce->name_length + sizeof("::__invoke") - 1; | ||
*callable_name = emalloc(*callable_name_len + 1); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EG(scope) could be empty here. Shouldn't we check for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not find any case where EG(scope) was empty.
Should I check it anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EG(scope) is going to be NULL in plain functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not completely sure in the patch. Currently the following script prints "C", but with your patch it prints "B".
test(); }