]> granicus.if.org Git - php/commitdiff
Fix Bug #69402: Reading empty SSL stream hangs until timeout
authorDaniel Lowrey <rdlowrey@php.net>
Tue, 14 Apr 2015 15:12:28 +0000 (09:12 -0600)
committerDaniel Lowrey <rdlowrey@php.net>
Tue, 14 Apr 2015 15:25:11 +0000 (09:25 -0600)
ext/openssl/xp_ssl.c

index adef9120d614985d9593dc1411fab262f1a05cbc..e24d32cd45a8ff429e852eb6f1a8f4e7b437ac8f 100644 (file)
@@ -1826,7 +1826,7 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
 {
        php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
        int nr_bytes = 0;
-       
+
        /* Only do this if SSL is active. */
        if (sslsock->ssl_active) {
                int retry = 1;
@@ -1910,13 +1910,18 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
 
                                /* Also, on reads, we may get this condition on an EOF. We should check properly. */
                                if (read) {
-                               stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle));
+                                       stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle));
                                }
-                               
+
+                               /* Don't loop indefinitely in non-blocking mode if no data is available */
+                               if (began_blocked == 0) {
+                                       break;
+                               }
+
                                /* Now, if we have to wait some time, and we're supposed to be blocking, wait for the socket to become
                                 * available. Now, php_pollfd_for uses select to wait up to our time_left value only...
                                 */
-                               if (retry && began_blocked) {
+                               if (retry) {
                                        if (read) {
                                                php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_WRITE) ?
                                                        (POLLOUT|POLLPRI) : (POLLIN|POLLPRI), has_timeout ? &left_time : NULL);