Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3a1786c

Browse files
committed
Fix GH-16137: "Deduplicate" http headers values but Set-Cookie.
Those are meant to have 1 or plus values separated by a comma even if the client set them separately.
1 parent f8b925b commit 3a1786c

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

‎sapi/cli/php_cli_server.c‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,14 +1680,34 @@ static void php_cli_server_client_save_header(php_cli_server_client *client)
16801680
{
16811681
/* Wrap header value in a zval to add is to the HashTable which acts as an array */
16821682
zval tmp;
1683-
ZVAL_STR(&tmp, client->current_header_value);
16841683
/* strip off the colon */
16851684
zend_string *lc_header_name = zend_string_tolower_ex(client->current_header_name, /* persistent */ true);
16861685
GC_MAKE_PERSISTENT_LOCAL(lc_header_name);
16871686

1688-
/* Add the wrapped zend_string to the HashTable */
1689-
zend_hash_add(&client->request.headers, lc_header_name, &tmp);
1690-
zend_hash_add(&client->request.headers_original_case, client->current_header_name, &tmp);
1687+
zval *entry = zend_hash_find(&client->request.headers, lc_header_name);
1688+
bool with_comma = !zend_string_equals_literal(lc_header_name, "set-cookie");
1689+
1690+
/**
1691+
* `Set-Cookie` HTTP header being the exception, they can have 1 or more values separated
1692+
* by a comma while still possibly be set separately by the client.
1693+
**/
1694+
if ((entry == NULL && with_comma) || !with_comma) {
1695+
ZVAL_STR(&tmp, client->current_header_value);
1696+
1697+
} else {
1698+
zend_string *curval = Z_STR_P(entry);
1699+
zend_string *newval = zend_string_safe_alloc(1, ZSTR_LEN(curval), ZSTR_LEN(client->current_header_value) + 2, /* persistent */true);
1700+
1701+
memcpy(ZSTR_VAL(newval), ZSTR_VAL(curval), ZSTR_LEN(curval));
1702+
memcpy(ZSTR_VAL(newval) + ZSTR_LEN(curval), ", ", 2);
1703+
memcpy(ZSTR_VAL(newval) + ZSTR_LEN(curval) + 2, ZSTR_VAL(client->current_header_value), ZSTR_LEN(client->current_header_value) + 1);
1704+
1705+
ZVAL_STR(&tmp, newval);
1706+
}
1707+
1708+
/* Add/Update the wrapped zend_string to the HashTable */
1709+
zend_hash_update(&client->request.headers, lc_header_name, &tmp);
1710+
zend_hash_update(&client->request.headers_original_case, client->current_header_name, &tmp);
16911711

16921712
zend_string_release_ex(lc_header_name, /* persistent */ true);
16931713
zend_string_release_ex(client->current_header_name, /* persistent */ true);

‎sapi/cli/tests/gh16137.phpt‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug GH-16137 duplicate *Forwarded* HTTP headers values.
3+
--INI--
4+
allow_url_fopen=1
5+
--SKIPIF--
6+
<?php
7+
include "skipif.inc";
8+
?>
9+
--FILE--
10+
<?php
11+
include "php_cli_server.inc";
12+
php_cli_server_start("echo \$_SERVER['HTTP_X_FORWARDED_FOR'];");
13+
$ctx = stream_context_create(array('http' => array (
14+
'method' => 'POST',
15+
'header' => array('x-forwarded-for: 127.0.0.1', 'x-forwarded-for: 192.168.1.254')
16+
)));
17+
var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS, true, $ctx));
18+
?>
19+
--EXPECT--
20+
string(24) "127.0.0.1, 192.168.1.254"

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /