From 7cd4054709e77da153c2ebbf8acf2ac88cfbd7b7 Mon Sep 17 00:00:00 2001
From: Remi Collet <fedora@famillecollet.com>
Date: Sat, 20 Sep 2014 17:14:21 +0200
Subject: PHP 5.5.17, openssl: fix regression introduce in changes for upstream
 bug #65137 and #41631, revert to 5.5.16 behavior

---
 php-5.5.17-openssl.patch | 199 +++++++++++++++++++++++++++++++++++++++++++++++
 php55.spec               |   9 ++-
 2 files changed, 207 insertions(+), 1 deletion(-)
 create mode 100644 php-5.5.17-openssl.patch

diff --git a/php-5.5.17-openssl.patch b/php-5.5.17-openssl.patch
new file mode 100644
index 0000000..790f72c
--- /dev/null
+++ b/php-5.5.17-openssl.patch
@@ -0,0 +1,199 @@
+From 32be79dcfa1bc5af8682d9f512da68c5b3e2cbf3 Mon Sep 17 00:00:00 2001
+From: Chris Wright <github@daverandom.com>
+Date: Sat, 23 Aug 2014 01:40:19 +0100
+Subject: [PATCH] Fix stream_select() issue with OpenSSL buffer
+
+Ensure data from OpenSSL internal buffer has been
+transfered to PHP stream buffer before a select()
+emulation operation is performed
+
+Addresses bug #65137
+https://bugs.php.net/bug.php?id=65137
+
+Conflicts:
+	ext/openssl/xp_ssl.c
+---
+ ext/openssl/xp_ssl.c   | 13 +++++++++++++
+ main/php_streams.h     |  3 +++
+ main/streams/streams.c |  8 ++++----
+ 3 files changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
+index b7b8690..956ffd0 100644
+--- a/ext/openssl/xp_ssl.c
++++ b/ext/openssl/xp_ssl.c
+@@ -835,6 +881,19 @@
+
+ 		case PHP_STREAM_AS_FD_FOR_SELECT:
+ 			if (ret) {
++				if (sslsock->ssl_active) {
++					/* OpenSSL has an internal buffer which select() cannot see. If we don't
++					   fetch it into the stream's buffer, no activity will be reported on the
++					   stream even though there is data waiting to be read - but we only fetch
++					   the number of bytes OpenSSL has ready to give us since we weren't asked
++					   for any data at this stage. This is only likely to cause issues with
++					   non-blocking streams, but it's harmless to always do it. */
++					int bytes;
++					while ((bytes = SSL_pending(sslsock->ssl_handle)) > 0) {
++						php_stream_fill_read_buffer(stream, (size_t)bytes);
++					}
++				}
++
+ 				*(php_socket_t *)ret = sslsock->s.socket;
+ 			}
+ 			return SUCCESS;
+diff --git a/main/php_streams.h b/main/php_streams.h
+index 2e4a3a2..89b877f 100644
+--- a/main/php_streams.h
++++ b/main/php_streams.h
+@@ -297,6 +297,9 @@ PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t coun
+ #define php_stream_write_string(stream, str)	_php_stream_write(stream, str, strlen(str) TSRMLS_CC)
+ #define php_stream_write(stream, buf, count)	_php_stream_write(stream, (buf), (count) TSRMLS_CC)
+ 
++PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC);
++#define php_stream_fill_read_buffer(stream, size)	_php_stream_fill_read_buffer((stream), (size) TSRMLS_CC)
++
+ #ifdef ZTS
+ PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
+ #else
+diff --git a/main/streams/streams.c b/main/streams/streams.c
+index 3fd4ab3..fbcc1ca 100644
+--- a/main/streams/streams.c
++++ b/main/streams/streams.c
+@@ -568,7 +568,7 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov
+ 
+ /* {{{ generic stream operations */
+ 
+-static void php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC)
++PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC)
+ {
+ 	/* allocate/fill the buffer */
+ 
+@@ -736,7 +736,7 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS
+ 				break;
+ 			}
+ 		} else {
+-			php_stream_fill_read_buffer(stream, size TSRMLS_CC);
++			php_stream_fill_read_buffer(stream, size);
+ 
+ 			toread = stream->writepos - stream->readpos;
+ 			if (toread > size) {
+@@ -972,7 +972,7 @@ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen,
+ 				}
+ 			}
+ 
+-			php_stream_fill_read_buffer(stream, toread TSRMLS_CC);
++			php_stream_fill_read_buffer(stream, toread);
+ 
+ 			if (stream->writepos - stream->readpos == 0) {
+ 				break;
+@@ -1047,7 +1047,7 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re
+ 
+ 		to_read_now = MIN(maxlen - buffered_len, stream->chunk_size);
+ 
+-		php_stream_fill_read_buffer(stream, buffered_len + to_read_now TSRMLS_CC);
++		php_stream_fill_read_buffer(stream, buffered_len + to_read_now);
+ 
+ 		just_read = STREAM_BUFFERED_AMOUNT(stream) - buffered_len;
+ 
+-- 
+1.9.2
+
+From 84a4041ba47e92e7a0ba03938d0ebf88b5fcf6cf Mon Sep 17 00:00:00 2001
+From: Anatol Belski <ab@php.net>
+Date: Thu, 7 Aug 2014 19:49:59 +0200
+Subject: [PATCH] fix TS build
+
+---
+ ext/openssl/xp_ssl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
+index 672070e..b7b8690 100644
+--- a/ext/openssl/xp_ssl.c
++++ b/ext/openssl/xp_ssl.c
+@@ -204,7 +204,7 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
+ 	return didwrite;
+ }
+ 
+-static void php_openssl_stream_wait_for_data(php_netstream_data_t *sock TSRMLS_DC)
++static void php_openssl_stream_wait_for_data(php_netstream_data_t *sock)
+ {
+ 	int retval;
+ 	struct timeval *ptimeout;
+From 6569db88081562f68a4f79e52cba83482bdf05fc Mon Sep 17 00:00:00 2001
+From: Daniel Lowrey <rdlowrey@php.net>
+Date: Thu, 7 Aug 2014 11:47:42 -0400
+Subject: [PATCH] Bug #41631: Observe socket read timeouts in SSL streams
+
+---
+ ext/openssl/xp_ssl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
+index 3082c83..672070e 100644
+--- a/ext/openssl/xp_ssl.c
++++ b/ext/openssl/xp_ssl.c
+@@ -204,13 +204,59 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
+ 	return didwrite;
+ }
+ 
++static void php_openssl_stream_wait_for_data(php_netstream_data_t *sock TSRMLS_DC)
++{
++	int retval;
++	struct timeval *ptimeout;
++
++	if (sock->socket == -1) {
++		return;
++	}
++	
++	sock->timeout_event = 0;
++
++	if (sock->timeout.tv_sec == -1)
++		ptimeout = NULL;
++	else
++		ptimeout = &sock->timeout;
++
++	while(1) {
++		retval = php_pollfd_for(sock->socket, PHP_POLLREADABLE, ptimeout);
++
++		if (retval == 0)
++			sock->timeout_event = 1;
++
++		if (retval >= 0)
++			break;
++
++		if (php_socket_errno() != EINTR)
++			break;
++	}
++}
++
+ static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
+ {
+ 	php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
++	php_netstream_data_t *sock;
+ 	int nr_bytes = 0;
+ 
+ 	if (sslsock->ssl_active) {
+ 		int retry = 1;
++		sock = (php_netstream_data_t*)stream->abstract;
++
++		/* The SSL_read() function will block indefinitely waiting for data on a blocking
++		   socket. If we don't poll for readability first this operation has the potential
++		   to hang forever. To avoid this scenario we poll with a timeout before performing
++		   the actual read. If it times out we're finished.
++		*/
++		if (sock->is_blocked) {
++			php_openssl_stream_wait_for_data(sock);
++			if (sock->timeout_event) {
++				stream->eof = 1;
++				php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL read operation timed out");
++				return nr_bytes;
++			}
++		}
+ 
+ 		do {
+ 			nr_bytes = SSL_read(sslsock->ssl_handle, buf, count);
+-- 
+1.9.2
+
diff --git a/php55.spec b/php55.spec
index 7eaf69d..f3c9570 100644
--- a/php55.spec
+++ b/php55.spec
@@ -129,7 +129,7 @@ Version: 5.5.17
 %if 0%{?snapdate:1}%{?rcver:1}
 Release: 0.1.%{?snapdate}%{?rcver}%{?dist}
 %else
-Release: 1%{?dist}
+Release: 2%{?dist}
 %endif
 # All files licensed under PHP version 3.01, except
 # Zend is licensed under Zend
@@ -191,6 +191,8 @@ Patch91: php-5.3.7-oci8conf.patch
 
 # Upstream fixes (100+)
 Patch100: php-bug65641.patch
+# Revert to fix regression
+Patch101: php-5.5.17-openssl.patch
 
 # Security fixes (200+)
 
@@ -943,6 +945,7 @@ rm -rf ext/json
 
 # upstream patches
 %patch100 -p1 -b .bug65641
+%patch101 -p1 -R -b .revert
 
 # security patches
 
@@ -1946,6 +1949,10 @@ fi
 
 
 %changelog
+* Sat Sep 20 2014 Remi Collet <remi@fedoraproject.org> 5.5.17-2
+- openssl: fix regression introduce in changes for upstream
+  bug #65137 and #41631, revert to 5.5.16 behavior
+
 * Wed Sep 17 2014 Remi Collet <remi@fedoraproject.org> 5.5.17-1
 - Update to 5.5.17
   http://www.php.net/releases/5_5_17.php
-- 
cgit