diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-01-14 10:04:47 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-01-14 10:04:47 +0100 |
commit | ad5ae0634de0e8f069d2c28beb223cf2c878aed1 (patch) | |
tree | 8da9736372cf7615e44ea51c9d5a83f5082d8aec | |
parent | 5a5f0adb2f20f6ac4b05b882d0dc771209d76870 (diff) | |
parent | f9fbba41b66e0e9ccd40ff064d00cfe987c2c5bb (diff) | |
download | php-git-ad5ae0634de0e8f069d2c28beb223cf2c878aed1.tar.gz |
Merge branch 'PHP-8.0'
* PHP-8.0:
Fixed bug #80596: Fix anonymous class union typehint errors
-rw-r--r-- | Zend/tests/type_declarations/union_types/anonymous_class.phpt | 30 | ||||
-rw-r--r-- | Zend/zend_compile.c | 16 |
2 files changed, 43 insertions, 3 deletions
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 c82a82fc9a..861e29ce63 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); } |