]> granicus.if.org Git - php/commitdiff
Fixed bug #72439 (Stream socket with remote address leads to a segmentation fault)
authorXinchen Hui <laruence@gmail.com>
Sun, 19 Jun 2016 04:29:47 +0000 (21:29 -0700)
committerXinchen Hui <laruence@gmail.com>
Sun, 19 Jun 2016 04:29:47 +0000 (21:29 -0700)
NEWS
main/streams/xp_socket.c

diff --git a/NEWS b/NEWS
index c7df8a03c8ff0fe805e469940933c24a1a38f29a..eef96e1cf79ac998ad2210609ef786b5562a9ef5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,10 @@ PHP                                                                        NEWS
   . Fixed bug #72336 (openssl_pkey_new does not fail for invalid DSA params).
     (Jakub Zelenka)
 
+- Streams:
+  . Fixed bug #72439 (Stream socket with remote address leads to a segmentation
+    fault). (Laruence)
+
 23 Jun 2016, PHP 5.6.23
 
 - GD:
index 995e90f98d7654dcaaa909b9bb7df5c3570fe4c5..90c5df0b8aa9f80c98197783f258e3473404a471 100644 (file)
@@ -247,16 +247,27 @@ static inline int sock_recvfrom(php_netstream_data_t *sock, char *buf, size_t bu
                struct sockaddr **addr, socklen_t *addrlen
                TSRMLS_DC)
 {
-       php_sockaddr_storage sa;
-       socklen_t sl = sizeof(sa);
        int ret;
        int want_addr = textaddr || addr;
 
        if (want_addr) {
+               php_sockaddr_storage sa;
+               socklen_t sl = sizeof(sa);
                ret = recvfrom(sock->socket, buf, buflen, flags, (struct sockaddr*)&sa, &sl);
                ret = (ret == SOCK_CONN_ERR) ? -1 : ret;
-               php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl,
-                       textaddr, textaddrlen, addr, addrlen TSRMLS_CC);
+               if (sl) {
+                       php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl,
+                                       textaddr, textaddrlen, addr, addrlen TSRMLS_CC);
+               } else {
+                       if (textaddr) {
+                               *textaddr = estrndup("", 0);
+                               *textaddrlen = 0;
+                       }
+                       if (addr) {
+                               *addr = NULL;
+                               *addrlen = 0;
+                       }
+               }
        } else {
                ret = recv(sock->socket, buf, buflen, flags);
                ret = (ret == SOCK_CONN_ERR) ? -1 : ret;
@@ -303,7 +314,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void
                                        ret = recv(sock->socket, &buf, sizeof(buf), MSG_PEEK);
                                        err = php_socket_errno();
                                        if (0 == ret || /* the counterpart did properly shutdown*/
-                                               0 > ret && err != EWOULDBLOCK && err != EAGAIN) { /* there was an unrecoverable error */
+                                               (0 > ret && err != EWOULDBLOCK && err != EAGAIN)) { /* there was an unrecoverable error */
                                                alive = 0;
                                        }
                                }