diff options
author | Dmitry Stogov <dmitry@zend.com> | 2021-01-26 18:44:56 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2021-01-26 18:44:56 +0300 |
commit | 9948142e50a45b2c4505bb629de1a4b9a3198a62 (patch) | |
tree | 52e565e4977e075ad4fc4c15126af9e3ee320073 | |
parent | b3189e7dad933934ffe10b8d2129d613f8822dcd (diff) | |
parent | 094e1a8b2def767b41d2defaf7cb86681126f9da (diff) | |
download | php-git-9948142e50a45b2c4505bb629de1a4b9a3198a62.tar.gz |
Merge branch 'PHP-8.0'
* PHP-8.0:
Skip dummy frames allocated on CPU stack of zend_call_function(). (Usage of "current_observed_frame" varible looks unsafe to me).
-rw-r--r-- | Zend/zend_observer.c | 8 | ||||
-rw-r--r-- | ext/zend_test/tests/observer_error_05.phpt | 35 |
2 files changed, 41 insertions, 2 deletions
diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index a8ce1eb5c0..a60428ee04 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -220,7 +220,11 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end( first_observed_frame = NULL; current_observed_frame = NULL; } else { - current_observed_frame = execute_data->prev_execute_data; + zend_execute_data *ex = execute_data->prev_execute_data; + while (ex && !ex->func) { + ex = ex->prev_execute_data; + } + current_observed_frame = ex; } } @@ -228,7 +232,7 @@ ZEND_API void zend_observer_fcall_end_all(void) { zend_execute_data *ex = current_observed_frame; while (ex != NULL) { - if (ex->func->type != ZEND_INTERNAL_FUNCTION) { + if (ex->func && ex->func->type != ZEND_INTERNAL_FUNCTION) { zend_observer_fcall_end(ex, NULL); } ex = ex->prev_execute_data; diff --git a/ext/zend_test/tests/observer_error_05.phpt b/ext/zend_test/tests/observer_error_05.phpt new file mode 100644 index 0000000000..d3e5f67a4e --- /dev/null +++ b/ext/zend_test/tests/observer_error_05.phpt @@ -0,0 +1,35 @@ +--TEST-- +Observer: End handlers fire after a userland fatal error +--SKIPIF-- +<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?> +--INI-- +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +zend_test.observer.show_return_value=1 +--FILE-- +<?php +set_error_handler(function ($errno, $errstr, $errfile, $errline) { + trigger_error('Foo error', E_USER_ERROR); +}); + +function foo() +{ + return $x; // warning +} + +foo(); + +echo 'You should not see this.'; +?> +--EXPECTF-- +<!-- init '%s%eobserver_error_%d.php' --> +<file '%s%eobserver_error_%d.php'> + <!-- init foo() --> + <foo> + <!-- init {closure}() --> + <{closure}> + +Fatal error: Foo error in %s on line %d + </{closure}:NULL> + </foo:NULL> +</file '%s%eobserver_error_%d.php'> |