curl tool: OOM handling fixes
authorYang Tse <yangsita@gmail.com>
Wed, 5 Oct 2011 13:06:26 +0000 (15:06 +0200)
committerYang Tse <yangsita@gmail.com>
Wed, 5 Oct 2011 13:06:26 +0000 (15:06 +0200)
src/tool_getparam.c
src/tool_operate.c
src/tool_operhlp.c
src/tool_operhlp.h
src/tool_paramhlp.c
src/tool_paramhlp.h

index 7ddd736..ae2970f 100644 (file)
@@ -600,7 +600,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         if(config->url_get || ((config->url_get = config->url_list) != NULL)) {
           /* there's a node here, if it already is filled-in continue to find
              an "empty" node */
-          while(config->url_get && (config->url_get->flags&GETOUT_URL))
+          while(config->url_get && (config->url_get->flags & GETOUT_URL))
             config->url_get = config->url_get->next;
         }
 
@@ -613,7 +613,9 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
           /* there was no free node, create one! */
           url = new_getout(config);
 
-        if(url) {
+        if(!url)
+          return PARAM_NO_MEM;
+        else {
           /* fill in the URL */
           GetStr(&url->url, nextarg);
           url->flags |= GETOUT_URL;
@@ -941,6 +943,8 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
           /* no data from the file, point to a zero byte string to make this
              get sent as a POST anyway */
           postdata = strdup("");
+          if(!postdata)
+            return PARAM_NO_MEM;
           size = 0;
         }
         else {
@@ -1004,7 +1008,9 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         if(!postdata) {
           /* no data from the file, point to a zero byte string to make this
              get sent as a POST anyway */
-          postdata=strdup("");
+          postdata = strdup("");
+          if(!postdata)
+            return PARAM_NO_MEM;
         }
       }
       else {
@@ -1298,7 +1304,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
       if(config->url_out || ((config->url_out = config->url_list) != NULL)) {
         /* there's a node here, if it already is filled-in continue to find
            an "empty" node */
-        while(config->url_out && (config->url_out->flags&GETOUT_OUTFILE))
+        while(config->url_out && (config->url_out->flags & GETOUT_OUTFILE))
           config->url_out = config->url_out->next;
       }
 
@@ -1311,7 +1317,9 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         /* there was no free node, create one! */
         url = new_getout(config);
 
-      if(url) {
+      if(!url)
+        return PARAM_NO_MEM;
+      else {
         /* fill in the outfile */
         if('o' == letter) {
           GetStr(&url->outfile, nextarg);
@@ -1379,6 +1387,8 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         snprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", off);
         Curl_safefree(config->range);
         config->range = strdup(buffer);
+        if(!config->range)
+          return PARAM_NO_MEM;
       }
       {
         /* byte range requested */
@@ -1427,7 +1437,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
       if(config->url_out || ((config->url_out = config->url_list) != NULL)) {
         /* there's a node here, if it already is filled-in continue to find
            an "empty" node */
-        while(config->url_out && (config->url_out->flags&GETOUT_UPLOAD))
+        while(config->url_out && (config->url_out->flags & GETOUT_UPLOAD))
           config->url_out = config->url_out->next;
       }
 
@@ -1440,7 +1450,9 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         /* there was no free node, create one! */
         url = new_getout(config);
 
-      if(url) {
+      if(!url)
+        return PARAM_NO_MEM;
+      else {
         url->flags |= GETOUT_UPLOAD; /* mark -T used */
         if(!*nextarg)
           url->flags |= GETOUT_NOUPLOAD;
@@ -1455,19 +1467,25 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
       /* user:password  */
       GetStr(&config->userpwd, nextarg);
       cleanarg(nextarg);
-      checkpasswd("host", &config->userpwd);
+      err = checkpasswd("host", &config->userpwd);
+      if(err)
+        return err;
       break;
     case 'U':
       /* Proxy user:password  */
       GetStr(&config->proxyuserpwd, nextarg);
       cleanarg(nextarg);
-      checkpasswd("proxy", &config->proxyuserpwd);
+      err = checkpasswd("proxy", &config->proxyuserpwd);
+      if(err)
+        return err;
       break;
     case 'v':
       if(toggle) {
         /* the '%' thing here will cause the trace get sent to stderr */
         Curl_safefree(config->trace_dump);
         config->trace_dump = strdup("%");
+        if(!config->trace_dump)
+          return PARAM_NO_MEM;
         if(config->tracetype && (config->tracetype != TRACE_PLAIN))
           warnf(config,
                 "-v, --verbose overrides an earlier trace/verbose option\n");
index 9624f42..d4671eb 100644 (file)
@@ -317,6 +317,11 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
       /* Use the postfields data for a http get */
       httpgetfields = strdup(config->postfields);
       Curl_safefree(config->postfields);
+      if(!httpgetfields) {
+        helpf(config->errors, "out of memory\n");
+        res = CURLE_OUT_OF_MEMORY;
+        goto quit_curl;
+      }
       if(SetHTTPrequest(config,
                         (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET),
                         &config->httpreq)) {
@@ -515,7 +520,9 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
 
           if(!outfile) {
             /* extract the file name from the URL */
-            outfile = get_url_file_name(this_url);
+            res = get_url_file_name(&outfile, this_url);
+            if(res)
+              goto show_error;
             if((!outfile || !*outfile) && !config->content_disposition) {
               helpf(config->errors, "Remote file name has no length!\n");
               res = CURLE_WRITE_ERROR;
index 1a72035..5a6a670 100644 (file)
@@ -152,14 +152,17 @@ char *add_file_name_to_url(CURL *curl, char *url, const char *filename)
 }
 
 /* Extracts the name portion of the URL.
- * Returns a heap-allocated string, or NULL if no name part
+ * Returns a pointer to a heap-allocated string or NULL if
+ * no name part, at location indicated by first argument.
  */
-char *get_url_file_name(const char *url)
+CURLcode get_url_file_name(char **filename, const char *url)
 {
-  char *fn = NULL;
+  const char *pc;
+
+  *filename = NULL;
 
   /* Find and get the remote file name */
-  const char *pc = strstr(url, "://");
+  pc = strstr(url, "://");
   if(pc)
     pc += 3;
   else
@@ -169,9 +172,13 @@ char *get_url_file_name(const char *url)
   if(pc) {
     /* duplicate the string beyond the slash */
     pc++;
-    fn = *pc ? strdup(pc): NULL;
+    if(*pc) {
+      *filename = strdup(pc);
+      if(!*filename)
+        return CURLE_OUT_OF_MEMORY;
+    }
   }
-  return fn;
+  return CURLE_OK;
 }
 
 /*
index 911f2f8..3629bf1 100644 (file)
@@ -35,7 +35,7 @@ bool stdin_upload(const char *uploadfile);
 
 char *add_file_name_to_url(CURL *curl, char *url, const char *filename);
 
-char *get_url_file_name(const char *url);
+CURLcode get_url_file_name(char **filename, const char *url);
 
 CURLcode main_init(void);
 
index 4f36719..97681c1 100644 (file)
 
 struct getout *new_getout(struct Configurable *config)
 {
-  struct getout *node =malloc(sizeof(struct getout));
-  struct getout *last= config->url_last;
+  struct getout *node = calloc(1, sizeof(struct getout));
+  struct getout *last = config->url_last;
   if(node) {
-    /* clear the struct */
-    memset(node, 0, sizeof(struct getout));
-
     /* append this new node last in the list */
     if(last)
       last->next = node;
@@ -120,8 +117,11 @@ ParameterError file2memory(char **bufp, size_t *size, FILE *file)
     buffer[nused] = '\0';
     /* free trailing slack space, if possible */
     if(alloc != nused) {
-      if((newbuf = realloc(buffer, nused+1)) != NULL)
-        buffer = newbuf;
+      if((newbuf = realloc(buffer, nused+1)) == NULL) {
+        Curl_safefree(buffer);
+        return PARAM_NO_MEM;
+      }
+      buffer = newbuf;
     }
     /* discard buffer if nothing was read */
     if(!nused) {
@@ -221,6 +221,8 @@ long proto2num(struct Configurable *config, long *val, const char *str)
     return 1;
 
   buffer = strdup(str); /* because strtok corrupts it */
+  if(!buffer)
+    return 1;
 
   for(token = strtok(buffer, sep);
       token;
@@ -298,17 +300,18 @@ int str2offset(curl_off_t *val, const char *str)
   return 0;
 }
 
-void checkpasswd(const char *kind, /* for what purpose */
-                 char **userpwd)   /* pointer to allocated string */
+ParameterError checkpasswd(const char *kind, /* for what purpose */
+                           char **userpwd)   /* pointer to allocated string */
 {
   char *ptr;
+
   if(!*userpwd)
-    return;
+    return PARAM_OK;
 
   ptr = strchr(*userpwd, ':');
   if(!ptr) {
     /* no password present, prompt for one */
-    char passwd[256]="";
+    char passwd[256] = "";
     char prompt[256];
     size_t passwdlen;
     size_t userlen = strlen(*userpwd);
@@ -327,14 +330,15 @@ void checkpasswd(const char *kind, /* for what purpose */
     passptr = realloc(*userpwd,
                       passwdlen + 1 + /* an extra for the colon */
                       userlen + 1);   /* an extra for the zero */
+    if(!passptr)
+      return PARAM_NO_MEM;
 
-    if(passptr) {
-      /* append the password separated with a colon */
-      passptr[userlen]=':';
-      memcpy(&passptr[userlen+1], passwd, passwdlen+1);
-      *userpwd = passptr;
-    }
+    /* append the password separated with a colon */
+    passptr[userlen] = ':';
+    memcpy(&passptr[userlen+1], passwd, passwdlen+1);
+    *userpwd = passptr;
   }
+  return PARAM_OK;
 }
 
 ParameterError add2list(struct curl_slist **list, const char *ptr)
index 8b7ec94..f179991 100644 (file)
@@ -37,7 +37,7 @@ long proto2num(struct Configurable *config, long *val, const char *str);
 
 int str2offset(curl_off_t *val, const char *str);
 
-void checkpasswd(const char *kind, char **userpwd);
+ParameterError checkpasswd(const char *kind, char **userpwd);
 
 ParameterError add2list(struct curl_slist **list, const char *ptr);
 
@@ -47,7 +47,5 @@ int ftpcccmethod(struct Configurable *config, const char *str);
 
 long delegation(struct Configurable *config, char *str);
 
-
-
 #endif /* HEADER_CURL_TOOL_PARAMHLP_H */