a4f3a1
diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
a4f3a1
index 680be8b..10382df 100644
a4f3a1
--- a/modules/proxy/mod_proxy_ftp.c
a4f3a1
+++ b/modules/proxy/mod_proxy_ftp.c
a4f3a1
@@ -218,7 +218,7 @@ static int ftp_check_string(const char *x)
a4f3a1
  * (EBCDIC) machines either.
a4f3a1
  */
a4f3a1
 static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb,
a4f3a1
-        char *buff, apr_size_t bufflen, int *eos)
a4f3a1
+        char *buff, apr_size_t bufflen, int *eos, apr_size_t *outlen)
a4f3a1
 {
a4f3a1
     apr_bucket *e;
a4f3a1
     apr_status_t rv;
a4f3a1
@@ -230,6 +230,7 @@ static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb,
a4f3a1
     /* start with an empty string */
a4f3a1
     buff[0] = 0;
a4f3a1
     *eos = 0;
a4f3a1
+    *outlen = 0;
a4f3a1
 
a4f3a1
     /* loop through each brigade */
a4f3a1
     while (!found) {
a4f3a1
@@ -273,6 +274,7 @@ static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb,
a4f3a1
                 if (len > 0) {
a4f3a1
                     memcpy(pos, response, len);
a4f3a1
                     pos += len;
a4f3a1
+                    *outlen += len;
a4f3a1
                 }
a4f3a1
             }
a4f3a1
             APR_BUCKET_REMOVE(e);
a4f3a1
@@ -386,28 +388,37 @@ static int ftp_getrc_msg(conn_rec *ftp_ctrl, apr_bucket_brigade *bb, char *msgbu
a4f3a1
     char buff[5];
a4f3a1
     char *mb = msgbuf, *me = &msgbuf[msglen];
a4f3a1
     apr_status_t rv;
a4f3a1
+    apr_size_t nread;
a4f3a1
+    
a4f3a1
     int eos;
a4f3a1
 
a4f3a1
-    if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) {
a4f3a1
+    if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) {
a4f3a1
         return -1;
a4f3a1
     }
a4f3a1
 /*
a4f3a1
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
a4f3a1
                  "<%s", response);
a4f3a1
 */
a4f3a1
+    if (nread < 4) {
a4f3a1
+        ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(10229) "Malformed FTP response '%s'", response);
a4f3a1
+        *mb = '\0';
a4f3a1
+        return -1;
a4f3a1
+    }
a4f3a1
+
a4f3a1
+
a4f3a1
     if (!apr_isdigit(response[0]) || !apr_isdigit(response[1]) ||
a4f3a1
-    !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-'))
a4f3a1
+        !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-'))
a4f3a1
         status = 0;
a4f3a1
     else
a4f3a1
         status = 100 * response[0] + 10 * response[1] + response[2] - 111 * '0';
a4f3a1
 
a4f3a1
     mb = apr_cpystrn(mb, response + 4, me - mb);
a4f3a1
 
a4f3a1
-    if (response[3] == '-') {
a4f3a1
+    if (response[3] == '-') { /* multi-line reply "123-foo\nbar\n123 baz" */
a4f3a1
         memcpy(buff, response, 3);
a4f3a1
         buff[3] = ' ';
a4f3a1
         do {
a4f3a1
-            if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) {
a4f3a1
+            if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) {
a4f3a1
                 return -1;
a4f3a1
             }
a4f3a1
             mb = apr_cpystrn(mb, response + (' ' == response[0] ? 1 : 4), me - mb);