diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-01-23 12:48:45 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-01-23 12:54:14 +0100 |
commit | 2eb33818b60f0e089833937605f07fe2dc0a3237 (patch) | |
tree | 3bf2b6a0c28d5fccab89eed4aeb291918240e507 | |
parent | ea3afcbae36c3f1f9003a506c6936a4681f1181d (diff) | |
download | php-git-2eb33818b60f0e089833937605f07fe2dc0a3237.tar.gz |
Fixed bug #79155
Make sure we only unset the NULLABLE flag temporarily for class
resolution, as the same type may be compiled multiple types.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | Zend/tests/bug79155.phpt | 36 | ||||
-rw-r--r-- | Zend/zend_compile.c | 13 |
3 files changed, 48 insertions, 5 deletions
@@ -3,7 +3,9 @@ PHP NEWS ?? ??? ????, PHP 7.4.3 - Core: - . Fixed bug ##79146 (cscript can fail to run on some systems). (clarodeus) + . Fixed bug #79146 (cscript can fail to run on some systems). (clarodeus) + . Fixed bug #79155 (Property nullability lost when using multiple property + definition). (Nikita) - CURL: . Fixed bug #79078 (Hypothetical use-after-free in curl_multi_add_handle()). diff --git a/Zend/tests/bug79155.phpt b/Zend/tests/bug79155.phpt new file mode 100644 index 0000000000..be9488da86 --- /dev/null +++ b/Zend/tests/bug79155.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #79155: Property nullability lost when using multiple property definition +--FILE-- +<?php + +class Foo { + public ?string $a, $b; + public ?stdClass $c, $d; +} + +$t = new Foo; +$t->a = "str"; +$t->b = "str"; +$t->c = new stdClass; +$t->d = new stdClass; + +var_dump($t->a, $t->b, $t->c, $t->d); + +$t->a = null; +$t->b = null; +$t->c = null; +$t->d = null; +var_dump($t->a, $t->b, $t->c, $t->d); + +?> +--EXPECT-- +string(3) "str" +string(3) "str" +object(stdClass)#2 (0) { +} +object(stdClass)#3 (0) { +} +NULL +NULL +NULL +NULL diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ea24457394..5661f26439 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5282,6 +5282,8 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null) /* {{{ */ { zend_bool allow_null = force_allow_null; + zend_ast_attr orig_ast_attr = ast->attr; + zend_type type; if (ast->attr & ZEND_TYPE_NULLABLE) { allow_null = 1; ast->attr &= ~ZEND_TYPE_NULLABLE; @@ -5291,15 +5293,15 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null return ZEND_TYPE_ENCODE(ast->attr, allow_null); } else { zend_string *class_name = zend_ast_get_str(ast); - zend_uchar type = zend_lookup_builtin_type_by_name(class_name); + zend_uchar type_code = zend_lookup_builtin_type_by_name(class_name); - if (type != 0) { + if (type_code != 0) { if ((ast->attr & ZEND_NAME_NOT_FQ) != ZEND_NAME_NOT_FQ) { zend_error_noreturn(E_COMPILE_ERROR, "Type declaration '%s' must be unqualified", ZSTR_VAL(zend_string_tolower(class_name))); } - return ZEND_TYPE_ENCODE(type, allow_null); + type = ZEND_TYPE_ENCODE(type_code, allow_null); } else { uint32_t fetch_type = zend_get_class_fetch_type_ast(ast); if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) { @@ -5310,9 +5312,12 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null zend_string_addref(class_name); } - return ZEND_TYPE_ENCODE_CLASS(class_name, allow_null); + type = ZEND_TYPE_ENCODE_CLASS(class_name, allow_null); } } + + ast->attr = orig_ast_attr; + return type; } /* }}} */ |