From ac2832935435556dc593784cd0087b5e576bbe4d Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Wed, 29 Apr 2015 21:57:33 -0700
Subject: [PATCH] Fix bug #69545 - avoid overflow when reading list

---
 ext/ftp/ftp.c | 82 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 41 insertions(+), 41 deletions(-)

Index: php5-5.3.3.1/ext/ftp/ftp.c
===================================================================
--- php5-5.3.3.1.orig/ext/ftp/ftp.c	2015-07-27 16:08:48.000000000 +0200
+++ php5-5.3.3.1/ext/ftp/ftp.c	2015-07-27 16:08:48.000000000 +0200
@@ -183,9 +183,9 @@
 		if (ftp->ssl_active) {
 			SSL_shutdown(ftp->ssl_handle);
 		}
-#endif		
+#endif
 		closesocket(ftp->fd);
-	}	
+	}
 	ftp_gc(ftp);
 	efree(ftp);
 	return NULL;
@@ -256,7 +256,7 @@
 		if (!ftp_getresp(ftp)) {
 			return 0;
 		}
-			
+
 		if (ftp->resp != 234) {
 			if (!ftp_putcmd(ftp, "AUTH", "SSL")) {
 				return 0;
@@ -264,7 +264,7 @@
 			if (!ftp_getresp(ftp)) {
 				return 0;
 			}
-				
+
 			if (ftp->resp != 334) {
 				return 0;
 			} else {
@@ -272,7 +272,7 @@
 				ftp->use_ssl_for_data = 1;
 			}
 		}
-		
+
 		ctx = SSL_CTX_new(SSLv23_client_method());
 		if (ctx == NULL) {
 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create the SSL context");
@@ -315,8 +315,8 @@
 			if (!ftp_getresp(ftp)) {
 				return 0;
 			}
-			
-			ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);		
+
+			ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
 		}
 	}
 #endif
@@ -350,7 +350,7 @@
 {
 	if (ftp == NULL) {
 		return 0;
-	}	
+	}
 
 	ftp_gc(ftp);
 
@@ -385,7 +385,7 @@
 	if (!ftp_putcmd(ftp, "SYST", NULL)) {
 		return NULL;
 	}
-	if (!ftp_getresp(ftp) || ftp->resp != 215) { 
+	if (!ftp_getresp(ftp) || ftp->resp != 215) {
 		return NULL;
 	}
 	syst = ftp->inbuf;
@@ -421,14 +421,14 @@
 	if (!ftp_putcmd(ftp, "PWD", NULL)) {
 		return NULL;
 	}
-	if (!ftp_getresp(ftp) || ftp->resp != 257) { 
+	if (!ftp_getresp(ftp) || ftp->resp != 257) {
 		return NULL;
 	}
 	/* copy out the pwd from response */
-	if ((pwd = strchr(ftp->inbuf, '"')) == NULL) { 
+	if ((pwd = strchr(ftp->inbuf, '"')) == NULL) {
 		return NULL;
 	}
-	if ((end = strrchr(++pwd, '"')) == NULL) { 
+	if ((end = strrchr(++pwd, '"')) == NULL) {
 		return NULL;
 	}
 	ftp->pwd = estrndup(pwd, end - pwd);
@@ -598,7 +598,7 @@
 	if (!ftp_getresp(ftp) || ftp->resp != 200) {
 		return 0;
 	}
-	
+
 	return 1;
 }
 /* }}} */
@@ -632,7 +632,7 @@
 		return 0;
 	}
 
-	return 1;	
+	return 1;
 }
 /* }}} */
 
@@ -664,7 +664,7 @@
 	if (ftp == NULL) {
 		return 0;
 	}
-	if (type == ftp->type) { 
+	if (type == ftp->type) {
 		return 1;
 	}
 	if (type == FTPTYPE_ASCII) {
@@ -755,7 +755,7 @@
 	if (!ftp_putcmd(ftp, "PASV", NULL)) {
 		return 0;
 	}
-	if (!ftp_getresp(ftp) || ftp->resp != 227) { 
+	if (!ftp_getresp(ftp) || ftp->resp != 227) {
 		return 0;
 	}
 	/* parse out the IP and port */
@@ -798,7 +798,7 @@
 	if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
 		goto bail;
 	}
-	
+
 	ftp->data = data;
 
 	if (resumepos > 0) {
@@ -896,7 +896,7 @@
 	if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
 		goto bail;
 	}
-	ftp->data = data;	
+	ftp->data = data;
 
 	if (startpos > 0) {
 		if (startpos > 2147483647) {
@@ -1101,7 +1101,7 @@
 
 	if (strpbrk(cmd, "\r\n")) {
 		return 0;
-	} 
+	}
 	/* build the output buffer */
 	if (args && args[0]) {
 		/* "cmd args\r\n\0" */
@@ -1246,7 +1246,7 @@
 #if HAVE_OPENSSL_EXT
 		if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) {
 			sent = SSL_write(ftp->ssl_handle, buf, size);
-		} else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {	
+		} else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
 			sent = SSL_write(ftp->data->ssl_handle, buf, size);
 		} else {
 #endif
@@ -1286,14 +1286,14 @@
 #if HAVE_OPENSSL_EXT
 	if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) {
 		nr_bytes = SSL_read(ftp->ssl_handle, buf, len);
-	} else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {	
+	} else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
 		nr_bytes = SSL_read(ftp->data->ssl_handle, buf, len);
 	} else {
 #endif
 		nr_bytes = recv(s, buf, len, 0);
 #if HAVE_OPENSSL_EXT
 	}
-#endif	
+#endif
 	return (nr_bytes);
 }
 /* }}} */
@@ -1509,7 +1509,7 @@
 
 data_accepted:
 #if HAVE_OPENSSL_EXT
-	
+
 	/* now enable ssl if we need to */
 	if (ftp->use_ssl && ftp->use_ssl_for_data) {
 		ctx = SSL_CTX_new(SSLv23_client_method());
@@ -1563,18 +1563,18 @@
 			SSL_shutdown(data->ssl_handle);
 			data->ssl_active = 0;
 		}
-#endif				
+#endif
 		closesocket(data->listener);
-	}	
+	}
 	if (data->fd != -1) {
 #if HAVE_OPENSSL_EXT
 		if (data->ssl_active) {
 			SSL_shutdown(data->ssl_handle);
 			data->ssl_active = 0;
 		}
-#endif				
+#endif
 		closesocket(data->fd);
-	}	
+	}
 	if (ftp) {
 		ftp->data = NULL;
 	}
@@ -1592,8 +1592,8 @@
 	databuf_t	*data = NULL;
 	char		*ptr;
 	int		ch, lastch;
-	int		size, rcvd;
-	int		lines;
+	size_t		size, rcvd;
+	size_t		lines;
 	char		**ret = NULL;
 	char		**entry;
 	char		*text;
@@ -1611,7 +1611,7 @@
 	if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
 		goto bail;
 	}
-	ftp->data = data;	
+	ftp->data = data;
 
 	if (!ftp_putcmd(ftp, cmd, path)) {
 		goto bail;
@@ -1635,7 +1635,7 @@
 	lines = 0;
 	lastch = 0;
 	while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {
-		if (rcvd == -1) {
+		if (rcvd == -1 || rcvd > ((size_t)(-1))-size) {
 			goto bail;
 		}
 
@@ -1849,7 +1849,7 @@
 	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {
 		goto bail;
 	}
-	if ((data = data_accept(data, ftp TSRMLS_CC)) == NULL) { 
+	if ((data = data_accept(data, ftp TSRMLS_CC)) == NULL) {
 		goto bail;
 	}
 	ftp->data = data;
@@ -1905,7 +1905,7 @@
 		goto bail;
 	}
 	ftp->data = data_close(ftp, ftp->data);
- 
+
 	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) {
 		goto bail;
 	}
