]> granicus.if.org Git - php/commitdiff
Fix #80067: Omitting the port in bindto setting errors
authorChristoph M. Becker <cmbecker69@gmx.de>
Wed, 9 Sep 2020 12:28:55 +0000 (14:28 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Fri, 11 Sep 2020 12:44:12 +0000 (14:44 +0200)
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.

NEWS
ext/standard/tests/network/bindto.phpt
ext/standard/tests/network/bug80067.phpt [new file with mode: 0644]
main/network.c
main/streams/xp_socket.c

diff --git a/NEWS b/NEWS
index a037e2f28a0ab0192131590c420a275e65f43214..67fbb361b7602cdae37d037e6601bbd064e6f1c8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
 
index 32f8a0cb812ac07e8441212003997e538eefc1e7..27ae45e5ff07829c007b954fa7d5cef20737bff5 100644 (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
diff --git a/ext/standard/tests/network/bug80067.phpt b/ext/standard/tests/network/bug80067.phpt
new file mode 100644 (file)
index 0000000..19b2c76
--- /dev/null
@@ -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)
index 3c8e81cc81e46c5bd1564d212410652e61e8ddca..8035adb195923525ea861ac57734b8f887e89530 100644 (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 {
index 4bca670b84956100a93c4758b6d72ca80b072f66..0ae0c0f77bfe68bc938dba69be870caab8c6d098 100644 (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