1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

uri: Fix handling of large port numbers in URI struct (#19905)

* uri: Fix handling of large port numbers in URI struct

* uri: Explain the choice of type for `php_uri.port`

* NEWS
This commit is contained in:
Tim Düsterhus
2025-09-21 23:19:54 +02:00
committed by GitHub
parent c7485a0b8f
commit 5f00673a45
7 changed files with 153 additions and 5 deletions

2
NEWS
View File

@@ -59,6 +59,8 @@ PHP NEWS
conditions. (timwolla)
. Further clean up the internal API. (timwolla)
. Fixed bug GH-19892 (Refcounting on zend_empty_array). (ilutov, timwolla)
. Fixed handling of port numbers > 65535 with the internal
`php_uri_parse_to_struct()` API. (timwolla)
- Windows:
. Fix GH-19722 (_get_osfhandle asserts in debug mode when given a socket).

View File

@@ -155,7 +155,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char
if (resource->port == 0)
resource->port = 21;
transport_len = (int)spprintf(&transport, 0, "tcp://%s:%d", ZSTR_VAL(resource->host), resource->port);
transport_len = (int)spprintf(&transport, 0, "tcp://%s:" ZEND_LONG_FMT, ZSTR_VAL(resource->host), resource->port);
stream = php_stream_xport_create(transport, transport_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, context, NULL, NULL);
efree(transport);
if (stream == NULL) {

View File

@@ -446,7 +446,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
use_proxy = 1;
transport_string = zend_string_copy(Z_STR_P(tmpzval));
} else {
transport_string = zend_strpprintf(0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", ZSTR_VAL(resource->host), resource->port);
transport_string = zend_strpprintf(0, "%s://%s:" ZEND_LONG_FMT, use_ssl ? "ssl" : "tcp", ZSTR_VAL(resource->host), resource->port);
}
}
@@ -1083,7 +1083,7 @@ finish:
header_info.location = NULL;
}
if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) {
spprintf(&new_path, 0, "%s://%s:%d%s", ZSTR_VAL(resource->scheme),
spprintf(&new_path, 0, "%s://%s:" ZEND_LONG_FMT "%s", ZSTR_VAL(resource->scheme),
ZSTR_VAL(resource->host), resource->port, loc_path);
} else {
spprintf(&new_path, 0, "%s://%s%s", ZSTR_VAL(resource->scheme),

View File

@@ -27,7 +27,9 @@ typedef struct php_uri {
zend_string *user;
zend_string *password;
zend_string *host;
unsigned short port;
/* port is a zend_long to match the userland port getter, which
* returns the port in zval. */
zend_long port;
zend_string *path;
zend_string *query;
zend_string *fragment;

View File

@@ -10,7 +10,7 @@ var_dump(zend_test_uri_parser("https://%65xample:%65xample@%65xample.com:123/%65
?>
--EXPECT--
array(2) {
array(3) {
["normalized"]=>
array(8) {
["scheme"]=>
@@ -49,4 +49,23 @@ array(2) {
["fragment"]=>
string(9) "%65xample"
}
["struct"]=>
array(8) {
["scheme"]=>
string(5) "https"
["username"]=>
string(9) "%65xample"
["password"]=>
string(9) "%65xample"
["host"]=>
string(13) "%65xample.com"
["port"]=>
int(123)
["path"]=>
string(15) "/%65xample.html"
["query"]=>
string(19) "%65xample=%65xample"
["fragment"]=>
string(9) "%65xample"
}
}

71
ext/uri/tests/102.phpt Normal file
View File

@@ -0,0 +1,71 @@
--TEST--
Test the handling large ports for the uri struct
--EXTENSIONS--
uri
zend_test
--FILE--
<?php
var_dump(zend_test_uri_parser("https://example.com:42424242", "Uri\\Rfc3986\\Uri"));
?>
--EXPECT--
array(3) {
["normalized"]=>
array(8) {
["scheme"]=>
string(5) "https"
["username"]=>
NULL
["password"]=>
NULL
["host"]=>
string(11) "example.com"
["port"]=>
int(42424242)
["path"]=>
string(0) ""
["query"]=>
NULL
["fragment"]=>
NULL
}
["raw"]=>
array(8) {
["scheme"]=>
string(5) "https"
["username"]=>
NULL
["password"]=>
NULL
["host"]=>
string(11) "example.com"
["port"]=>
int(42424242)
["path"]=>
string(0) ""
["query"]=>
NULL
["fragment"]=>
NULL
}
["struct"]=>
array(8) {
["scheme"]=>
string(5) "https"
["username"]=>
NULL
["password"]=>
NULL
["host"]=>
string(11) "example.com"
["port"]=>
int(42424242)
["path"]=>
string(0) ""
["query"]=>
NULL
["fragment"]=>
NULL
}
}

View File

@@ -746,6 +746,11 @@ static ZEND_FUNCTION(zend_test_uri_parser)
RETURN_THROWS();
}
php_uri *uri_struct = php_uri_parse_to_struct(parser, ZSTR_VAL(uri_string), ZSTR_LEN(uri_string), PHP_URI_COMPONENT_READ_MODE_RAW, false);
if (uri_struct == NULL) {
RETURN_THROWS();
}
zval value;
array_init(return_value);
@@ -787,7 +792,56 @@ static ZEND_FUNCTION(zend_test_uri_parser)
php_uri_get_fragment(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_FRAGMENT), &value);
zend_hash_str_add(Z_ARR_P(return_value), "raw", strlen("raw"), &raw);
zval from_struct;
zval dummy;
array_init(&from_struct);
if (uri_struct->scheme) {
ZVAL_STR_COPY(&dummy, uri_struct->scheme);
} else {
ZVAL_NULL(&dummy);
}
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_SCHEME), &dummy);
if (uri_struct->user) {
ZVAL_STR_COPY(&dummy, uri_struct->user);
} else {
ZVAL_NULL(&dummy);
}
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_USERNAME), &dummy);
if (uri_struct->password) {
ZVAL_STR_COPY(&dummy, uri_struct->password);
} else {
ZVAL_NULL(&dummy);
}
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_PASSWORD), &dummy);
if (uri_struct->host) {
ZVAL_STR_COPY(&dummy, uri_struct->host);
} else {
ZVAL_NULL(&dummy);
}
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_HOST), &dummy);
ZVAL_LONG(&dummy, uri_struct->port);
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_PORT), &dummy);
if (uri_struct->path) {
ZVAL_STR_COPY(&dummy, uri_struct->path);
} else {
ZVAL_NULL(&dummy);
}
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_PATH), &dummy);
if (uri_struct->query) {
ZVAL_STR_COPY(&dummy, uri_struct->query);
} else {
ZVAL_NULL(&dummy);
}
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_QUERY), &dummy);
if (uri_struct->fragment) {
ZVAL_STR_COPY(&dummy, uri_struct->fragment);
} else {
ZVAL_NULL(&dummy);
}
zend_hash_add(Z_ARR(from_struct), ZSTR_KNOWN(ZEND_STR_FRAGMENT), &dummy);
zend_hash_str_add(Z_ARR_P(return_value), "struct", strlen("struct"), &from_struct);
php_uri_struct_free(uri_struct);
php_uri_free(uri);
}