diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-01 15:17:28 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-01 15:17:28 +0200 |
commit | 88a8ebce6a2ff572058e8cfe056d82b19b21f58f (patch) | |
tree | a17b916e006368b45e5cbd9464f3982e600a01ec | |
parent | 5c1cf7669b937dcb4589cb0c8deccd343dfd85f9 (diff) | |
parent | f92a03627a51a3e440b73795fb2a34a888f23b8d (diff) | |
download | php-git-88a8ebce6a2ff572058e8cfe056d82b19b21f58f.tar.gz |
Merge branch 'PHP-7.4'
* PHP-7.4:
Check for null EX(func) in write_property
-rw-r--r-- | Zend/tests/ex_func_null_during_property_write.phpt | 25 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 13 |
2 files changed, 35 insertions, 3 deletions
diff --git a/Zend/tests/ex_func_null_during_property_write.phpt b/Zend/tests/ex_func_null_during_property_write.phpt new file mode 100644 index 0000000000..6a253f760e --- /dev/null +++ b/Zend/tests/ex_func_null_during_property_write.phpt @@ -0,0 +1,25 @@ +--TEST-- +EX(func) can be null during write_property in an edge case +--FILE-- +<?php +class a { + public static $i = 0; + function __destruct() { + if (self::$i++ != 0) throw new Exception; + $b = new a; + echo $b; + } +} +new a; +?> +--EXPECTF-- +Fatal error: Uncaught Error: Object of class a could not be converted to string in %s:%d +Stack trace: +#0 %s(%d): a->__destruct() +#1 {main} + +Next Exception in %s:%d +Stack trace: +#0 %s(%d): a->__destruct() +#1 {main} + thrown in %s on line %d diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 063a274722..a4ee0feda8 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -691,6 +691,13 @@ exit: } /* }}} */ +static zend_always_inline zend_bool property_uses_strict_types() { + zend_execute_data *execute_data = EG(current_execute_data); + return execute_data + && execute_data->func + && ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)); +} + ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zval *value, void **cache_slot) /* {{{ */ { zval *variable_ptr, tmp; @@ -707,7 +714,7 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva if (UNEXPECTED(prop_info)) { ZVAL_COPY_VALUE(&tmp, value); - if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, EG(current_execute_data) && ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))))) { + if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, property_uses_strict_types()))) { Z_TRY_DELREF_P(value); variable_ptr = &EG(error_zval); goto exit; @@ -716,7 +723,7 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva } found: - zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EG(current_execute_data) && ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))); + zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, property_uses_strict_types()); goto exit; } if (Z_PROP_FLAG_P(variable_ptr) == IS_PROP_UNINIT) { @@ -772,7 +779,7 @@ write_std_property: if (UNEXPECTED(prop_info)) { ZVAL_COPY_VALUE(&tmp, value); - if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))))) { + if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, property_uses_strict_types()))) { zval_ptr_dtor(value); goto exit; } |