Skip to content

Commit 70777ec

Browse files
committed
Merge branch 'PHP-8.1' into PHP-8.2
2 parents 0e7a132 + 5a4520b commit 70777ec

File tree

5 files changed

+309
-68
lines changed

5 files changed

+309
-68
lines changed

sapi/fpm/fpm/fpm_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1901,7 +1901,7 @@ consult the installation file that came with this distribution, or visit \n\
19011901
request_body_fd = -2;
19021902

19031903
if (UNEXPECTED(EG(exit_status) == 255)) {
1904-
if (CGIG(error_header) && *CGIG(error_header)) {
1904+
if (CGIG(error_header) && *CGIG(error_header) && !SG(headers_sent)) {
19051905
sapi_header_line ctr = {0};
19061906

19071907
ctr.line = CGIG(error_header);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
FPM: bug68207 - fastcgi.error_header setting headers after sent
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc"; ?>
6+
--FILE--
7+
<?php
8+
9+
require_once "tester.inc";
10+
11+
$cfg = <<<EOT
12+
[global]
13+
error_log = {{FILE:LOG}}
14+
[unconfined]
15+
listen = {{ADDR}}
16+
pm = static
17+
pm.max_children = 1
18+
catch_workers_output = yes
19+
EOT;
20+
21+
$code = <<<EOT
22+
<?php
23+
echo 1;
24+
fastcgi_finish_request();
25+
d();
26+
EOT;
27+
28+
$tester = new FPM\Tester($cfg, $code);
29+
$tester->start(iniEntries: ['fastcgi.error_header' => '"HTTP/1.1 550 PHP Error"']);
30+
$tester->expectLogStartNotices();
31+
$tester->request()->expectBody('1');
32+
$tester->terminate();
33+
$tester->expectLogTerminatingNotices();
34+
$tester->expectNoLogPattern('/Cannot modify header information/');
35+
$tester->close();
36+
37+
?>
38+
Done
39+
--EXPECT--
40+
Done
41+
--CLEAN--
42+
<?php
43+
require_once "tester.inc";
44+
FPM\Tester::clean();
45+
?>

sapi/fpm/tests/logreader.inc

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class LogReader
137137
*
138138
* @return false
139139
*/
140-
private function printError(?string $errorMessage): bool
140+
public function printError(?string $errorMessage): bool
141141
{
142142
if (is_null($errorMessage)) {
143143
return false;
@@ -155,8 +155,8 @@ class LogReader
155155
* @param callable $matcher Callback to identify a match
156156
* @param string|null $notFoundMessage Error message if matcher does not succeed.
157157
* @param bool $checkAllLogs Whether to also check past logs.
158-
* @param int $timeoutSeconds Timeout in seconds for reading of all messages.
159-
* @param int $timeoutMicroseconds Additional timeout in microseconds for reading of all messages.
158+
* @param int|null $timeoutSeconds Timeout in seconds for reading of all messages.
159+
* @param int|null $timeoutMicroseconds Additional timeout in microseconds for reading of all messages.
160160
*
161161
* @return bool
162162
* @throws \Exception
@@ -165,9 +165,18 @@ class LogReader
165165
callable $matcher,
166166
string $notFoundMessage = null,
167167
bool $checkAllLogs = false,
168-
int $timeoutSeconds = 3,
169-
int $timeoutMicroseconds = 0
168+
int $timeoutSeconds = null,
169+
int $timeoutMicroseconds = null
170170
): bool {
171+
if (is_null($timeoutSeconds) && is_null($timeoutMicroseconds)) {
172+
$timeoutSeconds = 3;
173+
$timeoutMicroseconds = 0;
174+
} elseif (is_null($timeoutSeconds)) {
175+
$timeoutSeconds = 0;
176+
} elseif (is_null($timeoutMicroseconds)) {
177+
$timeoutMicroseconds = 0;
178+
}
179+
171180
$startTime = microtime(true);
172181
$endTime = $startTime + $timeoutSeconds + ($timeoutMicroseconds / 1_000_000);
173182
if ($checkAllLogs) {

sapi/fpm/tests/logtool.inc

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,33 @@ class LogTool
127127
/**
128128
* Match the matcher checking the log lines using the callback.
129129
*
130-
* @param callable $matcher Callback checking whether the log line matches the expected message.
131-
* @param string $notFoundMessage Error message to show if the message is not found.
132-
* @param bool $checkAllLogs Whether to also check past logs.
130+
* @param callable $matcher Callback checking whether the log line matches the expected message.
131+
* @param string|null $notFoundMessage Error message to show if the message is not found.
132+
* @param bool $checkAllLogs Whether to also check past logs.
133+
* @param int|null $timeoutSeconds Timeout in seconds for reading of all messages.
134+
* @param int|null $timeoutMicroseconds Additional timeout in microseconds for reading of all messages.
133135
*
134136
* @return bool
135137
* @throws \Exception
136138
*/
137-
private function match(callable $matcher, string $notFoundMessage, bool $checkAllLogs = false): bool
138-
{
139+
private function match(
140+
callable $matcher,
141+
string $notFoundMessage = null,
142+
bool $checkAllLogs = false,
143+
int $timeoutSeconds = null,
144+
int $timeoutMicroseconds = null
145+
): bool {
139146
if ($this->getError()) {
140147
return false;
141148
}
142149

143-
if ($this->logReader->readUntil($matcher, $notFoundMessage, $checkAllLogs)) {
150+
if ($this->logReader->readUntil(
151+
$matcher,
152+
$notFoundMessage,
153+
$checkAllLogs,
154+
$timeoutSeconds,
155+
$timeoutMicroseconds
156+
)) {
144157
$this->popError();
145158

146159
return true;
@@ -576,11 +589,14 @@ class LogTool
576589
/**
577590
* Expect log entry.
578591
*
579-
* @param string $type Entry type like NOTICE, WARNING, DEBUG and so on.
580-
* @param string $expectedMessage Message to search for
581-
* @param string|null $pool Pool that is used and prefixes the message.
582-
* @param string $ignoreErrorFor Ignore error for supplied string in the message.
583-
* @param bool $checkAllLogs Whether to also check past logs.
592+
* @param string $type Entry type like NOTICE, WARNING, DEBUG and so on.
593+
* @param string $expectedMessage Message to search for
594+
* @param string|null $pool Pool that is used and prefixes the message.
595+
* @param string $ignoreErrorFor Ignore error for supplied string in the message.
596+
* @param bool $checkAllLogs Whether to also check past logs.
597+
* @param bool $invert Whether the log entry is not expected rather than expected.
598+
* @param int|null $timeoutSeconds Timeout in seconds for reading of all messages.
599+
* @param int|null $timeoutMicroseconds Additional timeout in microseconds for reading of all messages.
584600
*
585601
* @return bool
586602
* @throws \Exception
@@ -590,17 +606,28 @@ class LogTool
590606
string $expectedMessage,
591607
string $pool = null,
592608
string $ignoreErrorFor = self::DEBUG,
593-
bool $checkAllLogs = false
609+
bool $checkAllLogs = false,
610+
bool $invert = false,
611+
int $timeoutSeconds = null,
612+
int $timeoutMicroseconds = null
594613
): bool {
595614
if ($this->getError()) {
596615
return false;
597616
}
598617

599-
return $this->match(
618+
$matchResult = $this->match(
600619
$this->getEntryMatcher($type, $expectedMessage, $pool, $ignoreErrorFor),
601-
"The $type does not match expected message",
602-
$checkAllLogs
620+
$invert ? null : "The $type does not match expected message",
621+
$checkAllLogs,
622+
$timeoutSeconds,
623+
$timeoutMicroseconds
603624
);
625+
626+
if ($matchResult && $invert) {
627+
return $this->error("The $type matches unexpected message");
628+
}
629+
630+
return $matchResult;
604631
}
605632

606633
/**
@@ -676,14 +703,23 @@ class LogTool
676703
/**
677704
* Expect pattern in the log line.
678705
*
679-
* @param string $pattern
706+
* @param string $pattern Pattern to use.
707+
* @param bool $invert Whether to expect pattern not to match.
708+
* @param bool $checkAllLogs Whether to also check past logs.
709+
* @param int|null $timeoutSeconds Timeout in seconds for reading of all messages.
710+
* @param int|null $timeoutMicroseconds Additional timeout in microseconds for reading of all messages.
680711
*
681712
* @return bool
682713
* @throws \Exception
683714
*/
684-
public function expectPattern(string $pattern): bool
685-
{
686-
return $this->match(
715+
public function expectPattern(
716+
string $pattern,
717+
bool $invert = false,
718+
bool $checkAllLogs = false,
719+
int $timeoutSeconds = null,
720+
int $timeoutMicroseconds = null,
721+
): bool {
722+
$matchResult = $this->match(
687723
function ($line) use ($pattern) {
688724
if (preg_match($pattern, $line) === 1) {
689725
$this->traceMatch("Pattern expectation", $pattern, $line);
@@ -693,8 +729,17 @@ class LogTool
693729

694730
return false;
695731
},
696-
'The search pattern not found'
732+
$invert ? null : 'The search pattern not found',
733+
$checkAllLogs,
734+
$timeoutSeconds,
735+
$timeoutMicroseconds
697736
);
737+
738+
if ($invert && $matchResult) {
739+
return $this->logReader->printError('The search pattern found - PATTERN: ' . $pattern);
740+
}
741+
742+
return $matchResult;
698743
}
699744

700745
/**

0 commit comments

Comments
 (0)