From: Dmitry Stogov Date: Mon, 12 Nov 2007 09:12:20 +0000 (+0000) Subject: Fixed bug #42937 (__call() method not invoked when methods are called on parent from... X-Git-Tag: RELEASE_2_0_0a1~1392 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0dd6af6afd186e515e40a8cef6fa7ea9591b7086;p=php Fixed bug #42937 (__call() method not invoked when methods are called on parent from child class). --- diff --git a/Zend/tests/bug42937.phpt b/Zend/tests/bug42937.phpt new file mode 100755 index 0000000000..537c567927 --- /dev/null +++ b/Zend/tests/bug42937.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #42937 (__call() method not invoked when methods are called on parent from child class) +--FILE-- +test(); + +$b = new B(); +$b->test(); +?> +--EXPECTF-- +test +test1 +test2 +test3 +test4 +test5 + +Fatal error: Call to undefined method C::test6() in %sbug42937.php on line 21 diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 4a76c2e2f9..8957542788 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -908,7 +908,29 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_uc zend_function *fbc; if (zend_u_hash_find(&ce->function_table, type, function_name_strval, function_name_strlen + 1, (void **) &fbc)==FAILURE) { - if (ce->__callstatic) { + if (ce->__call && + EG(This) && + Z_OBJ_HT_P(EG(This))->get_class_entry && + instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) { + zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function)); + + call_user_call->type = ZEND_INTERNAL_FUNCTION; + call_user_call->module = ce->module; + call_user_call->handler = zend_std_call_user_call; + call_user_call->arg_info = NULL; + call_user_call->num_args = 0; + call_user_call->scope = ce; + call_user_call->fn_flags = 0; + if (UG(unicode)) { + call_user_call->function_name.u = eustrndup(function_name_strval.u, function_name_strlen); + } else { + call_user_call->function_name.s = estrndup(function_name_strval.s, function_name_strlen); + } + call_user_call->pass_rest_by_reference = 0; + call_user_call->return_reference = ZEND_RETURN_VALUE; + + return (union _zend_function *)call_user_call; + } else if (ce->__callstatic) { zend_internal_function *callstatic_user_call = emalloc(sizeof(zend_internal_function)); callstatic_user_call->type = ZEND_INTERNAL_FUNCTION; callstatic_user_call->module = ce->module;