mirror of
https://github.com/php/php-src.git
synced 2024-11-25 10:54:15 +08:00
Merge branch 'PHP-7.1' into PHP-7.2
This commit is contained in:
commit
9fbd8620fb
4
NEWS
4
NEWS
@ -6,6 +6,10 @@ PHP NEWS
|
|||||||
. Fixed Bug #75142 (buildcheck.sh check for autoconf version needs to be updated
|
. Fixed Bug #75142 (buildcheck.sh check for autoconf version needs to be updated
|
||||||
for v2.64). (zizzy at zizzy dot net, Remi)
|
for v2.64). (zizzy at zizzy dot net, Remi)
|
||||||
|
|
||||||
|
- CLI server:
|
||||||
|
. Fixed bug #70470 (Built-in server truncates headers spanning over TCP
|
||||||
|
packets). (bouk)
|
||||||
|
|
||||||
- Date:
|
- Date:
|
||||||
. Fixed bug #75149 (redefinition of typedefs ttinfo and t1info). (Remi)
|
. Fixed bug #75149 (redefinition of typedefs ttinfo and t1info). (Remi)
|
||||||
|
|
||||||
|
@ -172,6 +172,9 @@ typedef struct php_cli_server_client {
|
|||||||
char *current_header_name;
|
char *current_header_name;
|
||||||
size_t current_header_name_len;
|
size_t current_header_name_len;
|
||||||
unsigned int current_header_name_allocated:1;
|
unsigned int current_header_name_allocated:1;
|
||||||
|
char *current_header_value;
|
||||||
|
size_t current_header_value_len;
|
||||||
|
enum { HEADER_NONE=0, HEADER_FIELD, HEADER_VALUE } last_header_element;
|
||||||
size_t post_read_offset;
|
size_t post_read_offset;
|
||||||
php_cli_server_request request;
|
php_cli_server_request request;
|
||||||
unsigned int content_sender_initialized:1;
|
unsigned int content_sender_initialized:1;
|
||||||
@ -1567,50 +1570,100 @@ static int php_cli_server_client_read_request_on_fragment(php_http_parser *parse
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int php_cli_server_client_read_request_on_header_field(php_http_parser *parser, const char *at, size_t length)
|
static void php_cli_server_client_save_header(php_cli_server_client *client)
|
||||||
{
|
{
|
||||||
php_cli_server_client *client = parser->data;
|
/* strip off the colon */
|
||||||
|
zend_string *orig_header_name = zend_string_init(client->current_header_name, client->current_header_name_len, 1);
|
||||||
|
char *lc_header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len);
|
||||||
|
zend_hash_str_add_ptr(&client->request.headers, lc_header_name, client->current_header_name_len, client->current_header_value);
|
||||||
|
zend_hash_add_ptr(&client->request.headers_original_case, orig_header_name, client->current_header_value);
|
||||||
|
efree(lc_header_name);
|
||||||
|
zend_string_release(orig_header_name);
|
||||||
|
|
||||||
if (client->current_header_name_allocated) {
|
if (client->current_header_name_allocated) {
|
||||||
pefree(client->current_header_name, 1);
|
pefree(client->current_header_name, 1);
|
||||||
client->current_header_name_allocated = 0;
|
client->current_header_name_allocated = 0;
|
||||||
}
|
}
|
||||||
client->current_header_name = (char *)at;
|
client->current_header_name = NULL;
|
||||||
client->current_header_name_len = length;
|
client->current_header_name_len = 0;
|
||||||
|
client->current_header_value = NULL;
|
||||||
|
client->current_header_value_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int php_cli_server_client_read_request_on_header_field(php_http_parser *parser, const char *at, size_t length)
|
||||||
|
{
|
||||||
|
php_cli_server_client *client = parser->data;
|
||||||
|
switch (client->last_header_element) {
|
||||||
|
case HEADER_VALUE:
|
||||||
|
php_cli_server_client_save_header(client);
|
||||||
|
/* break missing intentionally */
|
||||||
|
case HEADER_NONE:
|
||||||
|
client->current_header_name = (char *)at;
|
||||||
|
client->current_header_name_len = length;
|
||||||
|
break;
|
||||||
|
case HEADER_FIELD:
|
||||||
|
if (client->current_header_name_allocated) {
|
||||||
|
size_t new_length = client->current_header_name_len + length;
|
||||||
|
client->current_header_name = perealloc(client->current_header_name, new_length + 1, 1);
|
||||||
|
memcpy(client->current_header_name + client->current_header_name_len, at, length);
|
||||||
|
client->current_header_name_len = new_length;
|
||||||
|
} else {
|
||||||
|
size_t new_length = client->current_header_name_len + length;
|
||||||
|
char* field = pemalloc(new_length + 1, 1);
|
||||||
|
memcpy(field, client->current_header_name, client->current_header_name_len);
|
||||||
|
memcpy(field + client->current_header_name_len, at, length);
|
||||||
|
client->current_header_name = field;
|
||||||
|
client->current_header_name_len = new_length;
|
||||||
|
client->current_header_name_allocated = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->last_header_element = HEADER_FIELD;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int php_cli_server_client_read_request_on_header_value(php_http_parser *parser, const char *at, size_t length)
|
static int php_cli_server_client_read_request_on_header_value(php_http_parser *parser, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
php_cli_server_client *client = parser->data;
|
php_cli_server_client *client = parser->data;
|
||||||
char *value = pestrndup(at, length, 1);
|
switch (client->last_header_element) {
|
||||||
if (!value) {
|
case HEADER_FIELD:
|
||||||
return 1;
|
client->current_header_value = pestrndup(at, length, 1);
|
||||||
}
|
client->current_header_value_len = length;
|
||||||
{
|
break;
|
||||||
/* strip off the colon */
|
case HEADER_VALUE:
|
||||||
zend_string *orig_header_name = zend_string_init(client->current_header_name, client->current_header_name_len, 1);
|
{
|
||||||
char *lc_header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len);
|
size_t new_length = client->current_header_value_len + length;
|
||||||
zend_hash_str_add_ptr(&client->request.headers, lc_header_name, client->current_header_name_len, value);
|
client->current_header_value = perealloc(client->current_header_value, new_length + 1, 1);
|
||||||
zend_hash_add_ptr(&client->request.headers_original_case, orig_header_name, value);
|
memcpy(client->current_header_value + client->current_header_value_len, at, length);
|
||||||
efree(lc_header_name);
|
client->current_header_value_len = new_length;
|
||||||
zend_string_release(orig_header_name);
|
}
|
||||||
}
|
break;
|
||||||
|
case HEADER_NONE:
|
||||||
if (client->current_header_name_allocated) {
|
// can't happen
|
||||||
pefree(client->current_header_name, 1);
|
assert(0);
|
||||||
client->current_header_name_allocated = 0;
|
break;
|
||||||
}
|
}
|
||||||
|
client->last_header_element = HEADER_VALUE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int php_cli_server_client_read_request_on_headers_complete(php_http_parser *parser)
|
static int php_cli_server_client_read_request_on_headers_complete(php_http_parser *parser)
|
||||||
{
|
{
|
||||||
php_cli_server_client *client = parser->data;
|
php_cli_server_client *client = parser->data;
|
||||||
if (client->current_header_name_allocated) {
|
switch (client->last_header_element) {
|
||||||
pefree(client->current_header_name, 1);
|
case HEADER_NONE:
|
||||||
client->current_header_name_allocated = 0;
|
break;
|
||||||
|
case HEADER_FIELD:
|
||||||
|
client->current_header_value = pemalloc(1, 1);
|
||||||
|
*client->current_header_value = '\0';
|
||||||
|
client->current_header_value_len = 0;
|
||||||
|
/* break missing intentionally */
|
||||||
|
case HEADER_VALUE:
|
||||||
|
php_cli_server_client_save_header(client);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
client->current_header_name = NULL;
|
client->last_header_element = HEADER_NONE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1780,9 +1833,14 @@ static int php_cli_server_client_ctor(php_cli_server_client *client, php_cli_ser
|
|||||||
}
|
}
|
||||||
php_http_parser_init(&client->parser, PHP_HTTP_REQUEST);
|
php_http_parser_init(&client->parser, PHP_HTTP_REQUEST);
|
||||||
client->request_read = 0;
|
client->request_read = 0;
|
||||||
|
|
||||||
|
client->last_header_element = HEADER_NONE;
|
||||||
client->current_header_name = NULL;
|
client->current_header_name = NULL;
|
||||||
client->current_header_name_len = 0;
|
client->current_header_name_len = 0;
|
||||||
client->current_header_name_allocated = 0;
|
client->current_header_name_allocated = 0;
|
||||||
|
client->current_header_value = NULL;
|
||||||
|
client->current_header_value_len = 0;
|
||||||
|
|
||||||
client->post_read_offset = 0;
|
client->post_read_offset = 0;
|
||||||
if (FAILURE == php_cli_server_request_ctor(&client->request)) {
|
if (FAILURE == php_cli_server_request_ctor(&client->request)) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
|
@ -4,8 +4,6 @@ Bug #70470 (Built-in server truncates headers spanning over TCP packets)
|
|||||||
<?php
|
<?php
|
||||||
include "skipif.inc";
|
include "skipif.inc";
|
||||||
?>
|
?>
|
||||||
--XFAIL--
|
|
||||||
bug is not fixed yet
|
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
include "php_cli_server.inc";
|
include "php_cli_server.inc";
|
||||||
|
35
sapi/cli/tests/emptyheader.phpt
Normal file
35
sapi/cli/tests/emptyheader.phpt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
--TEST--
|
||||||
|
Correctly handle split and empty header
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
include "skipif.inc";
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include "php_cli_server.inc";
|
||||||
|
php_cli_server_start("var_dump(getAllheaders());");
|
||||||
|
|
||||||
|
$fp = fsockopen(PHP_CLI_SERVER_HOSTNAME, PHP_CLI_SERVER_PORT, $errno, $errmsg, 0.5);
|
||||||
|
|
||||||
|
if (!$fp) {
|
||||||
|
die("connect failed: " . $errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite($fp, "GET / HTTP/1.1\r\nUser-Agent\r\nAccept: */*\r\nReferer:\r\nHi\r\n\r\n");
|
||||||
|
fflush($fp);
|
||||||
|
while (!feof($fp)) {
|
||||||
|
echo fgets($fp);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
%a
|
||||||
|
array(3) {
|
||||||
|
["User-AgentAccept"]=>
|
||||||
|
string(3) "*/*"
|
||||||
|
["Referer"]=>
|
||||||
|
string(0) ""
|
||||||
|
["Hi"]=>
|
||||||
|
string(0) ""
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user