From b754baff0be0110235d3989b1c3d1484977800ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Fri, 7 Feb 2025 09:03:11 +0100 Subject: [PATCH] Free the trampoline when deprecation on materializing `__callStatic()` of trait throws Fixes php/php-src#17728 --- Zend/tests/gh_17728.phpt | 24 ++++++++++++++++++++++++ Zend/zend_object_handlers.c | 16 ++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 Zend/tests/gh_17728.phpt diff --git a/Zend/tests/gh_17728.phpt b/Zend/tests/gh_17728.phpt new file mode 100644 index 0000000000000..ef458a8e8d5e1 --- /dev/null +++ b/Zend/tests/gh_17728.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-17728: Assertion failure when calling static method of trait with `__callStatic()` with throwing error handler +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Calling static trait method Foo::bar is deprecated, it should only be called on a class using the trait diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 2576fda51ec3d..d688e4b63ed69 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1541,23 +1541,27 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st if (EXPECTED(fbc)) { if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_ABSTRACT)) { zend_abstract_method_call(fbc); - if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - zend_string_release_ex(fbc->common.function_name, 0); - zend_free_trampoline(fbc); - } - fbc = NULL; + goto fail; } else if (UNEXPECTED(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT)) { zend_error(E_DEPRECATED, "Calling static trait method %s::%s is deprecated, " "it should only be called on a class using the trait", ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); if (EG(exception)) { - return NULL; + goto fail; } } } return fbc; + + fail: + if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { + zend_string_release_ex(fbc->common.function_name, 0); + zend_free_trampoline(fbc); + } + + return NULL; } /* }}} */