From 66f5baa16e83c0e629d19e47da21de15aa65b77d Mon Sep 17 00:00:00 2001
From: Dan Fandrich <dan@coneharvesters.com>
Date: Sun, 9 Aug 2009 23:15:20 +0000
Subject: [PATCH] Fixed some memory leaks in the command-line tool that caused
 most of the torture tests to fail.

---
 CHANGES    |  4 ++++
 src/main.c | 51 +++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/CHANGES b/CHANGES
index 2f0b740154..e5fec2df0e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@
 
                                   Changelog
 
+Daniel Fandrich (9 Aug 2009)
+- Fixed some memory leaks in the command-line tool that caused most of the
+  torture tests to fail.
+
 Daniel Stenberg (2 Aug 2009)
 - Curt Bogmine reported a problem with SNI enabled on a particular server. We
   should introduce an option to disable SNI, but as we're in feature freeze
diff --git a/src/main.c b/src/main.c
index c9ccdf292e..2dc1a66865 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4378,8 +4378,11 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
              file output call */
 
           if(config->create_dirs &&
-             (-1 == create_dir_hierarchy(outfile, config->errors)))
-            return CURLE_WRITE_ERROR;
+             (-1 == create_dir_hierarchy(outfile, config->errors))) {
+            free(url);
+	    res = CURLE_WRITE_ERROR;
+	    break;
+	  }
 
           if(config->resume_from_current) {
             /* We're told to continue from where we are now. Get the
@@ -4404,7 +4407,9 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
             outs.stream=(FILE *) fopen(outfile, config->resume_from?"ab":"wb");
             if (!outs.stream) {
               helpf(config->errors, "Can't open '%s'!\n", outfile);
-              return CURLE_WRITE_ERROR;
+              free(url);
+	      res = CURLE_WRITE_ERROR;
+	      break;
             }
           }
           else {
@@ -4449,13 +4454,15 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
               char *urlbuffer = malloc(strlen(url) + strlen(filep) + 3);
               if(!urlbuffer) {
                 helpf(config->errors, "out of memory\n");
-                return CURLE_OUT_OF_MEMORY;
+                free(url);
+	        res = CURLE_OUT_OF_MEMORY;
+	        break;
               }
               if(ptr)
                 /* there is a trailing slash on the URL */
                 sprintf(urlbuffer, "%s%s", url, filep);
               else
-                /* thers is no trailing slash on the URL */
+                /* there is no trailing slash on the URL */
                 sprintf(urlbuffer, "%s/%s", url, filep);
 
               curl_free(filep);
@@ -4552,7 +4559,21 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
           urlbuffer = malloc(strlen(url) + strlen(httpgetfields) + 3);
           if(!urlbuffer) {
             helpf(config->errors, "out of memory\n");
-            return CURLE_OUT_OF_MEMORY;
+
+            /* Free the list of remaining URLs and globbed upload files
+             * to force curl to exit immediately
+             */
+            if(urls) {
+              glob_cleanup(urls);
+              urls = NULL;
+            }
+            if(inglob) {
+              glob_cleanup(inglob);
+              inglob = NULL;
+            }
+
+	    res = CURLE_OUT_OF_MEMORY;
+	    goto quit_urls;
           }
           if (pc)
             sprintf(urlbuffer, "%s%c%s", url, sep, httpgetfields);
@@ -4704,8 +4725,22 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
             my_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, file);
             curl_free(file);
           }
-          else
-            return CURLE_OUT_OF_MEMORY;
+          else {
+            /* Free the list of remaining URLs and globbed upload files
+             * to force curl to exit immediately
+             */
+            if(urls) {
+              glob_cleanup(urls);
+              urls = NULL;
+            }
+            if(inglob) {
+              glob_cleanup(inglob);
+              inglob = NULL;
+            }
+
+	    res = CURLE_OUT_OF_MEMORY;
+	    goto quit_urls;
+          }
         }
 
         if(config->no_body || config->remote_time) {
-- 
GitLab