diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/type_declarations/union_types/anonymous_class.phpt | 30 | ||||
-rw-r--r-- | Zend/zend_compile.c | 16 |
3 files changed, 45 insertions, 3 deletions
@@ -6,6 +6,8 @@ PHP NEWS . Fixed bug #80523 (bogus parse error on >4GB source code). (Nikita) . Fixed bug #80384 (filter buffers entire read until file closed). (Adam Seitz, cmb) + . Fixed bug #80596 (Invalid union type TypeError in anonymous classes). + (Daniil Gentili) - BCMath: . Fixed bug #80545 (bcadd('a', 'a') doesn't throw an exception). diff --git a/Zend/tests/type_declarations/union_types/anonymous_class.phpt b/Zend/tests/type_declarations/union_types/anonymous_class.phpt new file mode 100644 index 0000000000..1e009f22b0 --- /dev/null +++ b/Zend/tests/type_declarations/union_types/anonymous_class.phpt @@ -0,0 +1,30 @@ +--TEST-- +Union with anonymous class type +--FILE-- +<?php + +$a = new class { + public function testParam(self|string $a) + { + } + public function test(): self|string + { + return new \stdClass; + } +}; + +try { + $a->testParam(null); +} catch (\Throwable $e) { + echo $e->getMessage()."\n"; +} + +try { + $a->test(); +} catch (\Throwable $e) { + echo $e->getMessage()."\n"; +} +?> +--EXPECTF-- +class@anonymous(): Argument #1 ($a) must be of type class@anonymous|string, null given, called in %s on line %d +class@anonymous::test(): Return value must be of type class@anonymous|string, stdClass returned diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 83942be570..e7f2b0b04a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1167,7 +1167,15 @@ static zend_string *resolve_class_name(zend_string *name, zend_class_entry *scop name = scope->parent->name; } } - return name; + + /* The resolved name for anonymous classes contains null bytes. Cut off everything after the + * null byte here, to avoid larger parts of the type being omitted by printing code later. */ + size_t len = strlen(ZSTR_VAL(name)); + if (len != ZSTR_LEN(name)) { + ZEND_ASSERT(scope && "This should only happen with resolved types"); + return zend_string_init(ZSTR_VAL(name), len, 0); + } + return zend_string_copy(name); } zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scope) { @@ -1179,11 +1187,13 @@ zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scop if (ZEND_TYPE_HAS_CE(*list_type)) { str = add_type_string(str, ZEND_TYPE_CE(*list_type)->name); } else { - str = add_type_string(str, resolve_class_name(ZEND_TYPE_NAME(*list_type), scope)); + zend_string *resolved = resolve_class_name(ZEND_TYPE_NAME(*list_type), scope); + str = add_type_string(str, resolved); + zend_string_release(resolved); } } ZEND_TYPE_LIST_FOREACH_END(); } else if (ZEND_TYPE_HAS_NAME(type)) { - str = zend_string_copy(resolve_class_name(ZEND_TYPE_NAME(type), scope)); + str = resolve_class_name(ZEND_TYPE_NAME(type), scope); } else if (ZEND_TYPE_HAS_CE(type)) { str = zend_string_copy(ZEND_TYPE_CE(type)->name); } |