Fix core dump in FTP code

Hrvoje Niksic <[email protected]> Mon, 16 May 2005 17:17:40 +0200
Newsgroups gmane.comp.web.wget.patches
Message-ID <[email protected]>
I noticed that Wget dumps core when losing the data connection to an
FTP server.  This is due to functions in ftp-basic.c erroneously
free-ing respline after ftp_response returns read error (FTPRERR).

This patch fixes the problem.

2005-05-16  Hrvoje Niksic  <[email protected]>

	* ftp-basic.c: Don't xfree() the line returned by ftp_response if
	the returned code is not FTPOK.

Index: src/ftp-basic.c
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp-basic.c,v
retrieving revision 1.45
diff -u -r1.45 ftp-basic.c
--- src/ftp-basic.c	2005/05/07 01:06:26	1.45
+++ src/ftp-basic.c	2005/05/16 15:16:18
@@ -57,8 +57,12 @@
 /* Get the response of FTP server and allocate enough room to handle
    it.  <CR> and <LF> characters are stripped from the line, and the
    line is 0-terminated.  All the response lines but the last one are
-   skipped.  The last line is determined as described in RFC959.  */
+   skipped.  The last line is determined as described in RFC959.
 
+   If the line is successfully read, FTPOK is returned, and *ret_line
+   is assigned a freshly allocated line.  Otherwise, FTPRERR is
+   returned, and the value of *ret_line should be ignored.  */
+
 uerr_t
 ftp_response (int fd, char **ret_line)
 {
@@ -170,10 +174,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   /* An unprobable possibility of logging without a password.  */
   if (*respline == '2')
     {
@@ -237,10 +238,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline != '2')
     {
       xfree (respline);
@@ -315,7 +313,6 @@
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
     {
-      xfree (respline);
       fd_close (*local_sock);
       return err;
     }
@@ -408,7 +405,6 @@
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
     {
-      xfree (respline);
       fd_close (*local_sock);
       return err;
     }
@@ -489,7 +485,6 @@
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
     {
-      xfree (respline);
       fd_close (*local_sock);
       return err;
     }
@@ -533,10 +528,7 @@
   /* Get the server response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline != '2')
     {
       xfree (respline);
@@ -603,10 +595,7 @@
   /* Get the server response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline != '2')
     {
       xfree (respline);
@@ -768,10 +757,7 @@
   /* Get the server response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline != '2')
     {
       xfree (respline);
@@ -867,10 +853,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline != '2')
     {
       xfree (respline);
@@ -902,10 +885,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline == '5')
     {
       xfree (respline);
@@ -940,10 +920,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline != '3')
     {
       xfree (respline);
@@ -974,10 +951,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline == '5')
     {
       xfree (respline);
@@ -1014,10 +988,7 @@
   /* Get appropriate respone.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline == '5')
     {
       xfree (respline);
@@ -1054,10 +1025,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline == '5')
     {
       xfree (respline);
@@ -1110,10 +1078,7 @@
   /* Get appropriate response.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
-    {
-      xfree (respline);
-      return err;
-    }
+    return err;
   if (*respline == '5')
     {
       xfree (respline);
@@ -1158,7 +1123,6 @@
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
     {
-      xfree (respline);
       *size = 0;
       return err;
     }