mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Merge branch 'PHP-8.1'
This commit is contained in:
commit
f3c357c446
12
main/SAPI.c
12
main/SAPI.c
@ -489,7 +489,7 @@ static void sapi_send_headers_free(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SAPI_API void sapi_deactivate(void)
|
SAPI_API void sapi_deactivate_module(void)
|
||||||
{
|
{
|
||||||
zend_llist_destroy(&SG(sapi_headers).headers);
|
zend_llist_destroy(&SG(sapi_headers).headers);
|
||||||
if (SG(request_info).request_body) {
|
if (SG(request_info).request_body) {
|
||||||
@ -523,6 +523,10 @@ SAPI_API void sapi_deactivate(void)
|
|||||||
if (sapi_module.deactivate) {
|
if (sapi_module.deactivate) {
|
||||||
sapi_module.deactivate();
|
sapi_module.deactivate();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPI_API void sapi_deactivate_destroy(void)
|
||||||
|
{
|
||||||
if (SG(rfc1867_uploaded_files)) {
|
if (SG(rfc1867_uploaded_files)) {
|
||||||
destroy_uploaded_files_hash();
|
destroy_uploaded_files_hash();
|
||||||
}
|
}
|
||||||
@ -537,6 +541,12 @@ SAPI_API void sapi_deactivate(void)
|
|||||||
SG(global_request_time) = 0;
|
SG(global_request_time) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SAPI_API void sapi_deactivate(void)
|
||||||
|
{
|
||||||
|
sapi_deactivate_module();
|
||||||
|
sapi_deactivate_destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SAPI_API void sapi_initialize_empty_request(void)
|
SAPI_API void sapi_initialize_empty_request(void)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +143,8 @@ extern SAPI_API sapi_globals_struct sapi_globals;
|
|||||||
SAPI_API void sapi_startup(sapi_module_struct *sf);
|
SAPI_API void sapi_startup(sapi_module_struct *sf);
|
||||||
SAPI_API void sapi_shutdown(void);
|
SAPI_API void sapi_shutdown(void);
|
||||||
SAPI_API void sapi_activate(void);
|
SAPI_API void sapi_activate(void);
|
||||||
|
SAPI_API void sapi_deactivate_module(void);
|
||||||
|
SAPI_API void sapi_deactivate_destroy(void);
|
||||||
SAPI_API void sapi_deactivate(void);
|
SAPI_API void sapi_deactivate(void);
|
||||||
SAPI_API void sapi_initialize_empty_request(void);
|
SAPI_API void sapi_initialize_empty_request(void);
|
||||||
SAPI_API void sapi_add_request_header(const char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg);
|
SAPI_API void sapi_add_request_header(const char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg);
|
||||||
|
@ -1865,10 +1865,12 @@ void php_request_shutdown(void *dummy)
|
|||||||
zend_post_deactivate_modules();
|
zend_post_deactivate_modules();
|
||||||
} zend_end_try();
|
} zend_end_try();
|
||||||
|
|
||||||
/* 12. SAPI related shutdown (free stuff) */
|
/* 12. SAPI related shutdown*/
|
||||||
zend_try {
|
zend_try {
|
||||||
sapi_deactivate();
|
sapi_deactivate_module();
|
||||||
} zend_end_try();
|
} zend_end_try();
|
||||||
|
/* free SAPI stuff */
|
||||||
|
sapi_deactivate_destroy();
|
||||||
|
|
||||||
/* 13. free virtual CWD memory */
|
/* 13. free virtual CWD memory */
|
||||||
virtual_cwd_deactivate();
|
virtual_cwd_deactivate();
|
||||||
|
54
sapi/fpm/tests/bug77780-header-sent-error.phpt
Normal file
54
sapi/fpm/tests/bug77780-header-sent-error.phpt
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
--TEST--
|
||||||
|
FPM: bug77780 - Headers already sent error incorrectly emitted
|
||||||
|
--SKIPIF--
|
||||||
|
<?php include "skipif.inc"; ?>
|
||||||
|
--EXTENSIONS--
|
||||||
|
session
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "tester.inc";
|
||||||
|
|
||||||
|
$cfg = <<<EOT
|
||||||
|
[global]
|
||||||
|
error_log = {{FILE:LOG}}
|
||||||
|
[unconfined]
|
||||||
|
listen = {{ADDR}}
|
||||||
|
pm = static
|
||||||
|
pm.max_children = 1
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$code = <<<EOT
|
||||||
|
<?php
|
||||||
|
echo str_repeat('asdfghjkl', 150000) . "\n";
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$tester = new FPM\Tester($cfg, $code);
|
||||||
|
$tester->start();
|
||||||
|
$tester->expectLogStartNotices();
|
||||||
|
$tester
|
||||||
|
->request(
|
||||||
|
headers: [
|
||||||
|
'PHP_VALUE' => "session.cookie_secure=1",
|
||||||
|
],
|
||||||
|
readLimit: 10,
|
||||||
|
expectError: true
|
||||||
|
);
|
||||||
|
$tester->request(
|
||||||
|
headers: [
|
||||||
|
'PHP_VALUE' => "session.cookie_secure=1",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
->expectNoError();
|
||||||
|
$tester->terminate();
|
||||||
|
$tester->close();
|
||||||
|
|
||||||
|
?>
|
||||||
|
Done
|
||||||
|
--EXPECT--
|
||||||
|
Done
|
||||||
|
--CLEAN--
|
||||||
|
<?php
|
||||||
|
require_once "tester.inc";
|
||||||
|
FPM\Tester::clean();
|
||||||
|
?>
|
@ -26,6 +26,7 @@ namespace Adoy\FastCGI;
|
|||||||
|
|
||||||
class TimedOutException extends \Exception {}
|
class TimedOutException extends \Exception {}
|
||||||
class ForbiddenException extends \Exception {}
|
class ForbiddenException extends \Exception {}
|
||||||
|
class ReadLimitExceeded extends \Exception {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles communication with a FastCGI application
|
* Handles communication with a FastCGI application
|
||||||
@ -404,16 +405,24 @@ class Client
|
|||||||
/**
|
/**
|
||||||
* Read a FastCGI Packet
|
* Read a FastCGI Packet
|
||||||
*
|
*
|
||||||
|
* @param int $readLimit max content size
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws ReadLimitExceeded
|
||||||
*/
|
*/
|
||||||
private function readPacket()
|
private function readPacket($readLimit = -1)
|
||||||
{
|
{
|
||||||
if ($packet = fread($this->_sock, self::HEADER_LEN)) {
|
if ($packet = fread($this->_sock, self::HEADER_LEN)) {
|
||||||
$resp = $this->decodePacketHeader($packet);
|
$resp = $this->decodePacketHeader($packet);
|
||||||
$resp['content'] = '';
|
$resp['content'] = '';
|
||||||
if ($resp['contentLength']) {
|
if ($resp['contentLength']) {
|
||||||
$len = $resp['contentLength'];
|
$len = $resp['contentLength'];
|
||||||
while ($len && $buf=fread($this->_sock, $len)) {
|
if ($readLimit >= 0 && $len > $readLimit) {
|
||||||
|
// close connection so it can be re-set reset and throw an error
|
||||||
|
fclose($this->_sock);
|
||||||
|
$this->_sock = null;
|
||||||
|
throw new ReadLimitExceeded("Content has $len bytes but the limit is $readLimit bytes");
|
||||||
|
}
|
||||||
|
while ($len && $buf = fread($this->_sock, $len)) {
|
||||||
$len -= strlen($buf);
|
$len -= strlen($buf);
|
||||||
$resp['content'] .= $buf;
|
$resp['content'] .= $buf;
|
||||||
}
|
}
|
||||||
@ -473,15 +482,16 @@ class Client
|
|||||||
*
|
*
|
||||||
* @param array $params Array of parameters
|
* @param array $params Array of parameters
|
||||||
* @param string $stdin Content
|
* @param string $stdin Content
|
||||||
|
* @param int $readLimit [optional] the number of bytes to accept in a single packet or -1 if unlimited
|
||||||
* @return array
|
* @return array
|
||||||
* @throws ForbiddenException
|
* @throws ForbiddenException
|
||||||
* @throws TimedOutException
|
* @throws TimedOutException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function request_data(array $params, $stdin)
|
public function request_data(array $params, $stdin, $readLimit = -1)
|
||||||
{
|
{
|
||||||
$id = $this->async_request($params, $stdin);
|
$id = $this->async_request($params, $stdin);
|
||||||
return $this->wait_for_response_data($id);
|
return $this->wait_for_response_data($id, 0, $readLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -579,12 +589,13 @@ class Client
|
|||||||
*
|
*
|
||||||
* @param int $requestId
|
* @param int $requestId
|
||||||
* @param int $timeoutMs [optional] the number of milliseconds to wait.
|
* @param int $timeoutMs [optional] the number of milliseconds to wait.
|
||||||
|
* @param int $readLimit [optional] the number of bytes to accept in a single packet or -1 if unlimited
|
||||||
* @return array response data
|
* @return array response data
|
||||||
* @throws ForbiddenException
|
* @throws ForbiddenException
|
||||||
* @throws TimedOutException
|
* @throws TimedOutException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function wait_for_response_data($requestId, $timeoutMs = 0)
|
public function wait_for_response_data($requestId, $timeoutMs = 0, $readLimit = -1)
|
||||||
{
|
{
|
||||||
if (!isset($this->_requests[$requestId])) {
|
if (!isset($this->_requests[$requestId])) {
|
||||||
throw new \Exception('Invalid request id given');
|
throw new \Exception('Invalid request id given');
|
||||||
@ -608,7 +619,7 @@ class Client
|
|||||||
// but still not get the response requested
|
// but still not get the response requested
|
||||||
$startTime = microtime(true);
|
$startTime = microtime(true);
|
||||||
|
|
||||||
while ($resp = $this->readPacket()) {
|
while ($resp = $this->readPacket($readLimit)) {
|
||||||
if ($resp['type'] == self::STDOUT || $resp['type'] == self::STDERR) {
|
if ($resp['type'] == self::STDOUT || $resp['type'] == self::STDERR) {
|
||||||
if ($resp['type'] == self::STDERR) {
|
if ($resp['type'] == self::STDERR) {
|
||||||
$this->_requests[$resp['requestId']]['state'] = self::REQ_STATE_ERR;
|
$this->_requests[$resp['requestId']]['state'] = self::REQ_STATE_ERR;
|
||||||
|
@ -111,21 +111,31 @@ class Response
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $errorMessage
|
* @param string|null $errorMessage
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public function expectError($errorMessage)
|
public function expectError($errorMessage)
|
||||||
{
|
{
|
||||||
$errorData = $this->getErrorData();
|
$errorData = $this->getErrorData();
|
||||||
if ($errorData !== $errorMessage) {
|
if ($errorData !== $errorMessage) {
|
||||||
$this->error(
|
$expectedErrorMessage = $errorMessage !== null
|
||||||
"The expected error message '$errorMessage' is not equal to returned error '$errorData'"
|
? "The expected error message '$errorMessage' is not equal to returned error '$errorData'"
|
||||||
);
|
: "No error message expected but received '$errorData'";
|
||||||
|
$this->error($expectedErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $errorMessage
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function expectNoError()
|
||||||
|
{
|
||||||
|
return $this->expectError(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $contentType
|
* @param string $contentType
|
||||||
* @return string|null
|
* @return string|null
|
||||||
|
@ -606,6 +606,8 @@ class Tester
|
|||||||
* @param string|null $errorMessage
|
* @param string|null $errorMessage
|
||||||
* @param bool $connKeepAlive
|
* @param bool $connKeepAlive
|
||||||
* @param string|null $scriptFilename = null
|
* @param string|null $scriptFilename = null
|
||||||
|
* @param bool $expectError
|
||||||
|
* @param int $readLimit
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public function request(
|
public function request(
|
||||||
@ -617,7 +619,12 @@ class Tester
|
|||||||
string $errorMessage = null,
|
string $errorMessage = null,
|
||||||
bool $connKeepAlive = false,
|
bool $connKeepAlive = false,
|
||||||
string $scriptFilename = null,
|
string $scriptFilename = null,
|
||||||
|
<<<<<<< HEAD
|
||||||
string $stdin = null
|
string $stdin = null
|
||||||
|
=======
|
||||||
|
bool $expectError = false,
|
||||||
|
int $readLimit = -1,
|
||||||
|
>>>>>>> PHP-8.1
|
||||||
) {
|
) {
|
||||||
if ($this->hasError()) {
|
if ($this->hasError()) {
|
||||||
return new Response(null, true);
|
return new Response(null, true);
|
||||||
@ -627,11 +634,21 @@ class Tester
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$this->response = new Response(
|
$this->response = new Response(
|
||||||
|
<<<<<<< HEAD
|
||||||
$this->getClient($address, $connKeepAlive)->request_data($params, $stdin)
|
$this->getClient($address, $connKeepAlive)->request_data($params, $stdin)
|
||||||
|
=======
|
||||||
|
$this->getClient($address, $connKeepAlive)->request_data($params, false, $readLimit)
|
||||||
|
>>>>>>> PHP-8.1
|
||||||
);
|
);
|
||||||
$this->message($successMessage);
|
if ($expectError) {
|
||||||
|
$this->error('Expected request error but the request was successful');
|
||||||
|
} else {
|
||||||
|
$this->message($successMessage);
|
||||||
|
}
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
if ($errorMessage === null) {
|
if ($expectError) {
|
||||||
|
$this->message($successMessage);
|
||||||
|
} elseif ($errorMessage === null) {
|
||||||
$this->error("Request failed", $exception);
|
$this->error("Request failed", $exception);
|
||||||
} else {
|
} else {
|
||||||
$this->message($errorMessage);
|
$this->message($errorMessage);
|
||||||
|
Loading…
Reference in New Issue
Block a user