From be540b35d295b09e0a3f474775b13d23c8ba0243 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 9 Jun 2020 10:09:48 +0200 Subject: [PATCH] Remove some special-casing in zend_call_method() Don't treat the !fn_proxy && !obj_ce case differently. There doesn't seem to be any need for it, and it will result in subtly different behavior (e.g. it will accept "Foo::bar" syntax, but break as soon as you pass in an fn_proxy cache). --- Zend/zend_interfaces.c | 80 +++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 8fffde76ff..6ad81c0805 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -36,6 +36,7 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z { int result; zend_fcall_info fci; + zend_fcall_info_cache fcic; zval retval; zval params[2]; @@ -52,58 +53,49 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z fci.param_count = param_count; fci.params = params; fci.no_separation = 1; + ZVAL_UNDEF(&fci.function_name); /* Unused */ - if (!fn_proxy && !obj_ce) { - /* no interest in caching and no information already present that is - * needed later inside zend_call_function. */ - ZVAL_STRINGL(&fci.function_name, function_name, function_name_len); - result = zend_call_function(&fci, NULL); - zval_ptr_dtor(&fci.function_name); - } else { - zend_fcall_info_cache fcic; - ZVAL_UNDEF(&fci.function_name); /* Unused */ - - if (!obj_ce) { - obj_ce = object ? object->ce : NULL; - } - if (!fn_proxy || !*fn_proxy) { - if (EXPECTED(obj_ce)) { - fcic.function_handler = zend_hash_str_find_ptr( - &obj_ce->function_table, function_name, function_name_len); - if (UNEXPECTED(fcic.function_handler == NULL)) { - /* error at c-level */ - zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name); - } - } else { - fcic.function_handler = zend_fetch_function_str(function_name, function_name_len); - if (UNEXPECTED(fcic.function_handler == NULL)) { - /* error at c-level */ - zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name); - } - } - if (fn_proxy) { - *fn_proxy = fcic.function_handler; + if (!obj_ce) { + obj_ce = object ? object->ce : NULL; + } + if (!fn_proxy || !*fn_proxy) { + if (EXPECTED(obj_ce)) { + fcic.function_handler = zend_hash_str_find_ptr( + &obj_ce->function_table, function_name, function_name_len); + if (UNEXPECTED(fcic.function_handler == NULL)) { + /* error at c-level */ + zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name); } } else { - fcic.function_handler = *fn_proxy; + fcic.function_handler = zend_fetch_function_str(function_name, function_name_len); + if (UNEXPECTED(fcic.function_handler == NULL)) { + /* error at c-level */ + zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name); + } } + if (fn_proxy) { + *fn_proxy = fcic.function_handler; + } + } else { + fcic.function_handler = *fn_proxy; + } - if (object) { - fcic.called_scope = object->ce; + if (object) { + fcic.called_scope = object->ce; + } else { + zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data)); + + if (obj_ce && + (!called_scope || + !instanceof_function(called_scope, obj_ce))) { + fcic.called_scope = obj_ce; } else { - zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data)); - - if (obj_ce && - (!called_scope || - !instanceof_function(called_scope, obj_ce))) { - fcic.called_scope = obj_ce; - } else { - fcic.called_scope = called_scope; - } + fcic.called_scope = called_scope; } - fcic.object = object; - result = zend_call_function(&fci, &fcic); } + fcic.object = object; + result = zend_call_function(&fci, &fcic); + if (result == FAILURE) { /* error at c-level */ if (!obj_ce) { -- 2.50.1