Merge branch 'PHP-8.3' into PHP-8.4

* PHP-8.3:
  Disallow calls to abstract `__call()` / `__callStatic()` (#17719)
This commit is contained in:
Tim Düsterhus 2025-02-07 09:37:28 +01:00
commit e13d25eb84
No known key found for this signature in database
4 changed files with 41 additions and 1 deletions

2
NEWS
View file

@ -13,6 +13,8 @@ PHP NEWS
. Fix fallback paths in fast_long_{add,sub}_function. (nielsdos) . Fix fallback paths in fast_long_{add,sub}_function. (nielsdos)
. Fixed bug OSS-Fuzz #391975641 (Crash when accessing property backing value . Fixed bug OSS-Fuzz #391975641 (Crash when accessing property backing value
by reference). (ilutov) by reference). (ilutov)
. Fixed bug GH-17718 (Calling static methods on an interface that has
`__callStatic` is allowed). (timwolla)
- DOM: - DOM:
. Fixed bug GH-17609 (Typo in error message: Dom\NO_DEFAULT_NS instead of . Fixed bug GH-17609 (Typo in error message: Dom\NO_DEFAULT_NS instead of

View file

@ -0,0 +1,17 @@
--TEST--
GH-17718: Disallow calling abstract `__callStatic()` trampoline on an interface
--FILE--
<?php
interface Foo {
public static function __callStatic($method, $args);
}
Foo::bar();
?>
--EXPECTF--
Fatal error: Uncaught Error: Cannot call abstract method Foo::bar() in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d

View file

@ -0,0 +1,17 @@
--TEST--
GH-17718: Disallow calling abstract `__callStatic()` trampoline on an abstract class
--FILE--
<?php
abstract class Foo {
abstract public static function __callStatic($method, $args);
}
Foo::bar();
?>
--EXPECTF--
Fatal error: Uncaught Error: Cannot call abstract method Foo::bar() in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d

View file

@ -1617,7 +1617,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce
func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE
| ZEND_ACC_PUBLIC | ZEND_ACC_PUBLIC
| ZEND_ACC_VARIADIC | ZEND_ACC_VARIADIC
| (fbc->common.fn_flags & (ZEND_ACC_RETURN_REFERENCE|ZEND_ACC_DEPRECATED)); | (fbc->common.fn_flags & (ZEND_ACC_RETURN_REFERENCE|ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED));
if (fbc->common.attributes) { if (fbc->common.attributes) {
func->attributes = fbc->common.attributes; func->attributes = fbc->common.attributes;
GC_TRY_ADDREF(func->attributes); GC_TRY_ADDREF(func->attributes);
@ -1898,6 +1898,10 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
if (EXPECTED(fbc)) { if (EXPECTED(fbc)) {
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_ABSTRACT)) { if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_ABSTRACT)) {
zend_abstract_method_call(fbc); 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; fbc = NULL;
} else if (UNEXPECTED(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT)) { } else if (UNEXPECTED(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT)) {
zend_error(E_DEPRECATED, zend_error(E_DEPRECATED,