diff --git a/NEWS b/NEWS index bdcce4579ec..5cde5497839 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ PHP NEWS . Fixed bug GH-9891 (DateTime modify with unixtimestamp (@) must work like setTimestamp). (Derick) +- FPM: + . Fixed bug GH-9981 (FPM does not reset fastcgi.error_header). + (Jakub Zelenka) + - LDAP: . Fixed bug GH-10112 (LDAP\Connection::__construct() refers to ldap_create()). (cmb) diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index eb8fab8e832..5d83ee08af2 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1911,6 +1911,9 @@ consult the installation file that came with this distribution, or visit \n\ fpm_request_executing(); + /* Reset exit status from the previous execution */ + EG(exit_status) = 0; + php_execute_script(&file_handle); fastcgi_request_done: diff --git a/sapi/fpm/tests/gh9981-fastcgi-error-header-reset.phpt b/sapi/fpm/tests/gh9981-fastcgi-error-header-reset.phpt new file mode 100644 index 00000000000..5a1d65f1cb0 --- /dev/null +++ b/sapi/fpm/tests/gh9981-fastcgi-error-header-reset.phpt @@ -0,0 +1,51 @@ +--TEST-- +FPM: gh9981 - fastcgi.error_header is not reset +--SKIPIF-- + +--FILE-- +start(iniEntries: [ + 'fastcgi.error_header' => '"HTTP/1.1 500 PHP Error"', + 'output_buffering' => 4096, +]); +$tester->expectLogStartNotices(); +$tester->request()->expectStatus('500 PHP Error'); +$tester->request('q=1')->expectNoStatus(); +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->expectNoLogPattern('/Cannot modify header information/'); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- + diff --git a/sapi/fpm/tests/response.inc b/sapi/fpm/tests/response.inc index 9112da6ed77..99290e72f41 100644 --- a/sapi/fpm/tests/response.inc +++ b/sapi/fpm/tests/response.inc @@ -134,6 +134,36 @@ class Response return $this; } + /** + * Expect response status. + * + * @param string|null $status Expected status. + * + * @return Response + */ + public function expectStatus(string|null $status): Response { + $headers = $this->getHeaders(); + if (is_null($status) && !isset($headers['status'])) { + return $this; + } + if (!is_null($status) && !isset($headers['status'])) { + $this->error('Status is expected but not supplied'); + } elseif ($status !== $headers['status']) { + $statusMessage = $status === null ? "expected not to be set": "expected to be $status"; + $this->error("Status is $statusMessage but the actual value is {$headers['status']}"); + } + return $this; + } + + /** + * Expect response status not to be set. + * + * @return Response + */ + public function expectNoStatus(): Response { + return $this->expectStatus(null); + } + /** * Expect no error in the response. *