From: Nikita Popov Date: Thu, 10 Oct 2019 13:14:04 +0000 (+0200) Subject: Return error_zval form get_property_ptr_ptr on exception X-Git-Tag: php-7.4.0RC4~18 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a076e670a13decf76524e6f0c13abfce5532021;p=php Return error_zval form get_property_ptr_ptr on exception This goes in the reverse direction of 4463acb9513dfb62206760c49b3da1fe4d92f40a. After looking around a bit, it seems that we already check for Z_ISERROR_P() on the get_property_ptr_ptr return value in other places. So do this in zend_fetch_property_address() as well, and also make sure that EG(error_zval) is indeed returned on exception in get_property_ptr_ptr. In particular, this fixes the duplicate exceptions that we used to get because first get_property_ptr_ptr threw one and then read_property throws the same exception again. --- diff --git a/Zend/tests/closure_038.phpt b/Zend/tests/closure_038.phpt index 568db49b81..d1ec446c9d 100644 --- a/Zend/tests/closure_038.phpt +++ b/Zend/tests/closure_038.phpt @@ -58,10 +58,5 @@ int(24) Fatal error: Uncaught Error: Cannot access private property B::$x in %s:%d Stack trace: #0 %s(%d): Closure->{closure}() -#1 {main} - -Next Error: Cannot access private property B::$x in %s:%d -Stack trace: -#0 %s(%d): Closure->{closure}() #1 {main} thrown in %s on line %d diff --git a/Zend/tests/closure_039.phpt b/Zend/tests/closure_039.phpt index f72223d206..fa454c38c4 100644 --- a/Zend/tests/closure_039.phpt +++ b/Zend/tests/closure_039.phpt @@ -58,10 +58,5 @@ int(24) Fatal error: Uncaught Error: Cannot access private property B::$x in %s:%d Stack trace: #0 %s(%d): Closure->{closure}() -#1 {main} - -Next Error: Cannot access private property B::$x in %s:%d -Stack trace: -#0 %s(%d): Closure->{closure}() #1 {main} thrown in %s on line %d diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 368d6b2dcc..04aa3fee6e 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2822,6 +2822,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } return; } + } else if (UNEXPECTED(Z_ISERROR_P(ptr))) { + ZVAL_ERROR(result); + return; } ZVAL_INDIRECT(result, ptr); @@ -2858,7 +2861,7 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container variable_ptr = Z_INDIRECT_P(variable_ptr); } - if (UNEXPECTED(Z_ISERROR_P(variable_ptr) || EG(exception))) { + if (UNEXPECTED(Z_ISERROR_P(variable_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (UNEXPECTED(Z_TYPE(variable) != IS_INDIRECT)) { zend_throw_error(NULL, "Cannot assign by reference to overloaded object"); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 65aefb6aec..09984390c9 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1024,7 +1024,7 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int typ zobj = Z_OBJ_P(object); name = zval_try_get_tmp_string(member, &tmp_name); if (UNEXPECTED(!name)) { - return NULL; + return &EG(error_zval); } #if DEBUG_OBJECT_HANDLERS @@ -1072,6 +1072,8 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int typ zend_error(E_NOTICE, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name)); } } + } else if (zobj->ce->__get == NULL) { + retval = &EG(error_zval); } zend_tmp_string_release(tmp_name); diff --git a/tests/classes/static_properties_003_error4.phpt b/tests/classes/static_properties_003_error4.phpt index 7c54fc42ad..a96ffb2977 100644 --- a/tests/classes/static_properties_003_error4.phpt +++ b/tests/classes/static_properties_003_error4.phpt @@ -17,11 +17,7 @@ try { ==Done== --EXPECTF-- --> Access non-visible static prop like instance prop: -Error: Cannot access protected property C::$y in %s:9 -Stack trace: -#0 {main} - -Next Error: Cannot access protected property C::$y in %s:9 +Error: Cannot access protected property C::$y in %s:%d Stack trace: #0 {main} ==Done==