Merge branch 'PHP-8.0' into PHP-8.1

This commit is contained in:
Jakub Zelenka 2022-05-10 21:39:31 +01:00
commit 82eea0efc9
5 changed files with 80 additions and 8 deletions

2
NEWS
View file

@ -4,6 +4,8 @@ PHP NEWS
- FPM:
. Fixed ACL build check on MacOS. (David Carlier)
. Fixed bug #72185: php-fpm writes empty fcgi record causing nginx 502.
(Jakub Zelenka, loveharmful)
- SPL:
. Fixed bug GH-8235 (iterator_count() may run indefinitely). (cmb)

View file

@ -1590,10 +1590,10 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l
memcpy(req->out_pos, str, len);
req->out_pos += len;
} else if (len - limit < (int)(sizeof(req->out_buf) - sizeof(fcgi_header))) {
if (!req->out_hdr) {
open_packet(req, type);
}
if (limit > 0) {
if (!req->out_hdr) {
open_packet(req, type);
}
memcpy(req->out_pos, str, limit);
req->out_pos += limit;
}

View file

@ -0,0 +1,52 @@
--TEST--
FPM: bug72185 - FastCGI empty frame incorrectly created
--SKIPIF--
<?php include "skipif.inc"; ?>
--FILE--
<?php
require_once "tester.inc";
$cfg = <<<EOT
[global]
error_log = {{FILE:LOG}}
[unconfined]
listen = {{ADDR}}
pm = dynamic
pm.max_children = 2
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
catch_workers_output = yes
decorate_workers_output = no
php_value[html_errors] = false
EOT;
$code = <<<'EOT'
<?php
for ($i=0; $i < 167; $i++) {
error_log('PHP is the best programming language');
}
echo 'end';
EOT;
$tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$tester->request()->expectBody('end');
for ($i=0; $i < 167; $i++) {
$tester->expectLogNotice("PHP message: PHP is the best programming language");
}
$tester->terminate();
$tester->expectLogTerminatingNotices();
$tester->close();
?>
Done
--EXPECT--
Done
--CLEAN--
<?php
require_once "tester.inc";
FPM\Tester::clean();
?>

View file

@ -555,6 +555,25 @@ class Client
return $id;
}
/**
* Append response data.
*
* @param $resp Response
* @param $type Either err or our
*
* @throws \Exception
*/
private function fcgi_stream_append($resp, $type) {
if (isset($this->_requests[$resp['requestId']][$type . '_finished'])) {
throw new \Exception('FCGI_STD' . strtoupper($type) . ' stream already finished by empty record');
}
if ($resp['content'] === '') {
$this->_requests[$resp['requestId']][$type . '_finished'] = true;
} else {
$this->_requests[$resp['requestId']][$type . '_response'] .= $resp['content'];
}
}
/**
* Blocking call that waits for response data of the specific request
*
@ -593,13 +612,12 @@ class Client
if ($resp['type'] == self::STDOUT || $resp['type'] == self::STDERR) {
if ($resp['type'] == self::STDERR) {
$this->_requests[$resp['requestId']]['state'] = self::REQ_STATE_ERR;
$this->_requests[$resp['requestId']]['err_response'] .= $resp['content'];
$this->fcgi_stream_append($resp, 'err');
} else {
$this->_requests[$resp['requestId']]['out_response'] .= $resp['content'];
$this->fcgi_stream_append($resp, 'out');
}
$this->_requests[$resp['requestId']]['response'] .= $resp['content'];
}
if ($resp['type'] == self::END_REQUEST) {
} elseif ($resp['type'] == self::END_REQUEST) {
$this->_requests[$resp['requestId']]['state'] = self::REQ_STATE_OK;
if ($resp['requestId'] == $requestId) {
break;

View file

@ -364,7 +364,7 @@ class LogTool
}
$line = rtrim($line);
$pattern = sprintf('/^%s %s: %s$/', self::P_TIME, $type, $expectedMessage);
$pattern = sprintf('/^(%s )?%s: %s$/', self::P_TIME, $type, $expectedMessage);
if (preg_match($pattern, $line, $matches) === 0) {
return $this->error(