mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +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:
2
NEWS
2
NEWS
@@ -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).
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
71
ext/uri/tests/102.phpt
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user