Merge branch 'PHP-7.4' into PHP-8.0

* PHP-7.4:
  Fix #73630: Built-in Weberver - overwrite $_SERVER['request_uri']
This commit is contained in:
Christoph M. Becker 2021-06-30 16:14:51 +02:00
commit 70b0330e53
No known key found for this signature in database
GPG Key ID: D66C9593118BCCB6
4 changed files with 97 additions and 5 deletions

2
NEWS
View File

@ -11,6 +11,8 @@ PHP NEWS
offset). (girgias)
. Fixed bug #80728 (PHP built-in web server resets timeout when it can kill
the process). (Calvin Buckley)
. Fixed bug #73630 (Built-in Weberver - overwrite $_SERVER['request_uri']).
(cmb)
- Intl:
. Fixed bug #72809 (Locale::lookup() wrong result with canonicalize option).

View File

@ -1569,6 +1569,9 @@ static int php_cli_server_client_read_request_on_path(php_http_parser *parser, c
{
char *vpath;
size_t vpath_len;
if (UNEXPECTED(client->request.vpath != NULL)) {
return 1;
}
normalize_vpath(&vpath, &vpath_len, at, length, 1);
client->request.vpath = vpath;
client->request.vpath_len = vpath_len;
@ -1579,17 +1582,34 @@ static int php_cli_server_client_read_request_on_path(php_http_parser *parser, c
static int php_cli_server_client_read_request_on_query_string(php_http_parser *parser, const char *at, size_t length)
{
php_cli_server_client *client = parser->data;
client->request.query_string = pestrndup(at, length, 1);
client->request.query_string_len = length;
if (EXPECTED(client->request.query_string == NULL)) {
client->request.query_string = pestrndup(at, length, 1);
client->request.query_string_len = length;
} else {
ZEND_ASSERT(length <= PHP_HTTP_MAX_HEADER_SIZE && PHP_HTTP_MAX_HEADER_SIZE - length >= client->request.query_string_len);
client->request.query_string = perealloc(client->request.query_string, client->request.query_string_len + length + 1, 1);
memcpy(client->request.query_string + client->request.query_string_len, at, length);
client->request.query_string_len += length;
client->request.query_string[client->request.query_string_len] = '\0';
}
return 0;
}
static int php_cli_server_client_read_request_on_url(php_http_parser *parser, const char *at, size_t length)
{
php_cli_server_client *client = parser->data;
client->request.request_method = parser->method;
client->request.request_uri = pestrndup(at, length, 1);
client->request.request_uri_len = length;
if (EXPECTED(client->request.request_uri == NULL)) {
client->request.request_method = parser->method;
client->request.request_uri = pestrndup(at, length, 1);
client->request.request_uri_len = length;
} else {
ZEND_ASSERT(client->request.request_method == parser->method);
ZEND_ASSERT(length <= PHP_HTTP_MAX_HEADER_SIZE && PHP_HTTP_MAX_HEADER_SIZE - length >= client->request.query_string_len);
client->request.request_uri = perealloc(client->request.request_uri, client->request.request_uri_len + length + 1, 1);
memcpy(client->request.request_uri + client->request.request_uri_len, at, length);
client->request.request_uri_len += length;
client->request.request_uri[client->request.request_uri_len] = '\0';
}
return 0;
}

View File

@ -0,0 +1,45 @@
--TEST--
Bug #73630 (Built-in Weberver - overwrite $_SERVER['request_uri'])
--SKIPIF--
<?php
include "skipif.inc";
?>
--FILE--
<?php
$code = <<<'EOF'
var_dump(strncmp($_SERVER['REQUEST_URI'], "/overflow.php", strlen("/overflow.php")));
var_dump(strlen($_SERVER['QUERY_STRING']));
EOF;
include "php_cli_server.inc";
php_cli_server_start($code);
$host = PHP_CLI_SERVER_HOSTNAME;
$fp = php_cli_server_connect();
$path = "/overflow.php?" . str_repeat("x", 16400) . "//example.com";
if (fwrite($fp, <<<HEADER
GET $path HTTP/1.1
Host: {$host}
HEADER
)) {
while (!feof($fp)) {
echo fgets($fp);
}
}
?>
--EXPECTF--
HTTP/1.1 200 OK
Host: %s
Date: %s
Connection: close
X-Powered-By: PHP/%s
Content-type: text/html; charset=UTF-8
int(0)
int(16413)

View File

@ -0,0 +1,25 @@
--TEST--
Bug #73630 (Built-in Weberver - overwrite $_SERVER['request_uri'])
--DESCRIPTION--
Check that too long paths result in invalid request
--SKIPIF--
<?php
include "skipif.inc";
?>
--FILE--
<?php
$code = <<<'EOF'
echo "won't happen\n";
EOF;
include "php_cli_server.inc";
php_cli_server_start($code);
$host = PHP_CLI_SERVER_HOSTNAME;
$fp = php_cli_server_connect();
$path = "/" . str_repeat("x", 16400) . "//example.com";
var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS . "$path"));
?>
--EXPECTF--
Warning: file_get_contents(http://%s//example.com): failed to open stream: HTTP request failed! in %s on line %d
bool(false)