Fix #80067: Omitting the port in bindto setting errors

A recent commit[1] which fixed a memory leak introduced a regression
regarding the formerly liberal handling of IP addresses to bind to.  We
fix this by reverting that commit, and fix the memory leak where it
actually occurs.  In other words, this fix is less intrusive than the
former fix.

[1] <http://git.php.net/?p=php-src.git;a=commit;h=0b8c83f5936581942715d14883cdebddc18bad30>

Closes GH-6104.
This commit is contained in:
Christoph M. Becker 2020-09-09 14:28:55 +02:00
parent 2d4aa1ef3d
commit dfb3a79914
5 changed files with 29 additions and 5 deletions

1
NEWS
View file

@ -30,6 +30,7 @@ PHP NEWS
. Fixed bug #80077 (getmxrr test bug). (Rainer Jung)
. Fixed bug #72941 (Modifying bucket->data by-ref has no effect any longer).
(cmb)
. Fixed bug #80067 (Omitting the port in bindto setting errors). (cmb)
03 Sep 2020, PHP 7.3.22

View file

@ -13,4 +13,6 @@ $fp = stream_socket_client(
);
?>
--EXPECTF--
Warning: stream_socket_client(): unable to connect to tcp://%s:80 (Failed to parse address "invalid") in %s on line %d
Warning: stream_socket_client(): php_network_getaddresses: getaddrinfo failed: %s in %s on line %d
Warning: stream_socket_client(): unable to connect to tcp://www.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com:80 (php_network_getaddresses: getaddrinfo failed: %s) in %s on line %d

View file

@ -0,0 +1,13 @@
--TEST--
Bug #80067 (Omitting the port in bindto setting errors)
--SKIPIF--
<?php
if (getenv("SKIP_ONLINE_TESTS")) die('skip online test');
?>
--FILE--
<?php
$context = stream_context_create(['socket' => ['bindto' => '0']]);
var_dump(file_get_contents('https://httpbin.org/get', false, $context) !== false);
?>
--EXPECT--
bool(true)

View file

@ -200,6 +200,10 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka
if ((n = getaddrinfo(host, NULL, &hints, &res))) {
if (error_string) {
/* free error string received during previous iteration (if any) */
if (*error_string) {
zend_string_release_ex(*error_string, 0);
}
*error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n));
php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string));
} else {
@ -208,6 +212,10 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka
return 0;
} else if (res == NULL) {
if (error_string) {
/* free error string received during previous iteration (if any) */
if (*error_string) {
zend_string_release_ex(*error_string, 0);
}
*error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo failed (null result pointer) errno=%d", errno);
php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string));
} else {
@ -241,6 +249,10 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka
}
if (host_info == NULL) {
if (error_string) {
/* free error string received during previous iteration (if any) */
if (*error_string) {
zend_string_release_ex(*error_string, 0);
}
*error_string = strpprintf(0, "php_network_getaddresses: gethostbyname failed. errno=%d", errno);
php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string));
} else {

View file

@ -744,10 +744,6 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_
return -1;
}
bindto = parse_ip_address_ex(Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval), &bindport, xparam->want_errortext, &xparam->outputs.error_text);
if (bindto == NULL) {
efree(host);
return -1;
}
}
#ifdef SO_BROADCAST