summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2021-01-26 18:44:56 +0300
committerDmitry Stogov <dmitry@zend.com>2021-01-26 18:44:56 +0300
commit9948142e50a45b2c4505bb629de1a4b9a3198a62 (patch)
tree52e565e4977e075ad4fc4c15126af9e3ee320073
parentb3189e7dad933934ffe10b8d2129d613f8822dcd (diff)
parent094e1a8b2def767b41d2defaf7cb86681126f9da (diff)
downloadphp-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.c8
-rw-r--r--ext/zend_test/tests/observer_error_05.phpt35
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'>