]> granicus.if.org Git - curl/commitdiff
avoid a couple of potential zero size memory allocations
authorYang Tse <yangsita@gmail.com>
Mon, 6 Nov 2006 13:56:51 +0000 (13:56 +0000)
committerYang Tse <yangsita@gmail.com>
Mon, 6 Nov 2006 13:56:51 +0000 (13:56 +0000)
ares/CHANGES
ares/ares_cancel.c
ares/ares_destroy.c
ares/ares_init.c

index 770f037eba567bd4e6829c72f6a0ff85f8e52d22..378a81816fb572b863c40ae4cacc6b6c1f441c13 100644 (file)
@@ -2,6 +2,8 @@
 
 * November 6
 
+- Yang Tse removed a couple of potential zero size memory allocations.
+
 - Andreas Rieke fixed the line endings in the areslib.dsp file that I (Daniel)
   broke in the 1.3.2 release. We should switch to a system where that file is
   auto-generated. We could rip some code for that from curl...
index 8e3efa3b2296cb9d1b9dc222a33165230857f3a1..9641dab20a358209c0b98c0840d04ddd59b297dd 100644 (file)
@@ -39,7 +39,10 @@ void ares_cancel(ares_channel channel)
   channel->queries = NULL;
   if (!(channel->flags & ARES_FLAG_STAYOPEN))
   {
-    for (i = 0; i < channel->nservers; i++)
-      ares__close_sockets(channel, &channel->servers[i]);
+    if (channel->servers)
+    {
+      for (i = 0; i < channel->nservers; i++)
+        ares__close_sockets(channel, &channel->servers[i]);
+    }
   }
 }
index b7a21e9e3e879f081c60efae82df6a774a6d3cb2..fd243c30a905aeb13cd43547e85dfabeb9f0fc2f 100644 (file)
@@ -25,23 +25,37 @@ void ares_destroy(ares_channel channel)
   int i;
   struct query *query;
 
-  for (i = 0; i < channel->nservers; i++)
-    ares__close_sockets(channel, &channel->servers[i]);
-  free(channel->servers);
-  for (i = 0; i < channel->ndomains; i++)
-    free(channel->domains[i]);
-  free(channel->domains);
+  if (!channel)
+    return;
+
+  if (channel->servers) {
+    for (i = 0; i < channel->nservers; i++)
+      ares__close_sockets(channel, &channel->servers[i]);
+    free(channel->servers);
+  }
+
+  if (channel->domains) {
+    for (i = 0; i < channel->ndomains; i++)
+      free(channel->domains[i]);
+    free(channel->domains);
+  }
+
   if(channel->sortlist)
     free(channel->sortlist);
-  free(channel->lookups);
-  while (channel->queries)
-    {
-      query = channel->queries;
-      channel->queries = query->next;
-      query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
+
+  if (channel->lookups)
+    free(channel->lookups);
+
+  while (channel->queries) {
+    query = channel->queries;
+    channel->queries = query->next;
+    query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
+    if (query->tcpbuf)
       free(query->tcpbuf);
+    if (query->skip_server)
       free(query->skip_server);
-      free(query);
-    }
+    free(query);
+  }
+
   free(channel);
 }
index a9fa8fbc177169a556b558b9c9ddf65b1b5b02a0..7246bc48474feb104fb433fcc18a642503ea1e95 100644 (file)
@@ -125,7 +125,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
   channel->queries = NULL;
   channel->domains = NULL;
   channel->sortlist = NULL;
+  channel->servers = NULL;
   channel->sock_state_cb = NULL;
+  channel->sock_state_cb_data = NULL;
 
   /* Initialize configuration by each of the four sources, from highest
    * precedence to lowest.
@@ -140,7 +142,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
   if (status != ARES_SUCCESS)
     {
       /* Something failed; clean up memory we may have allocated. */
-      if (channel->nservers != -1)
+      if (channel->servers)
         free(channel->servers);
       if (channel->domains)
         {
@@ -214,12 +216,16 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
   /* Copy the servers, if given. */
   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
     {
-      channel->servers =
-        malloc(options->nservers * sizeof(struct server_state));
-      if (!channel->servers && options->nservers != 0)
-        return ARES_ENOMEM;
-      for (i = 0; i < options->nservers; i++)
-        channel->servers[i].addr = options->servers[i];
+      /* Avoid zero size allocations at any cost */
+      if (options->nservers > 0)
+        {
+          channel->servers =
+            malloc(options->nservers * sizeof(struct server_state));
+          if (!channel->servers)
+            return ARES_ENOMEM;
+          for (i = 0; i < options->nservers; i++)
+            channel->servers[i].addr = options->servers[i];
+        }
       channel->nservers = options->nservers;
     }
 
@@ -228,16 +234,20 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
    */
   if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
     {
-      channel->domains = malloc(options->ndomains * sizeof(char *));
-      if (!channel->domains && options->ndomains != 0)
-        return ARES_ENOMEM;
-      for (i = 0; i < options->ndomains; i++)
-        {
-          channel->ndomains = i;
-          channel->domains[i] = strdup(options->domains[i]);
-          if (!channel->domains[i])
-            return ARES_ENOMEM;
-        }
+      /* Avoid zero size allocations at any cost */
+      if (options->ndomains > 0)
+      {
+        channel->domains = malloc(options->ndomains * sizeof(char *));
+        if (!channel->domains)
+          return ARES_ENOMEM;
+        for (i = 0; i < options->ndomains; i++)
+          {
+            channel->ndomains = i;
+            channel->domains[i] = strdup(options->domains[i]);
+            if (!channel->domains[i])
+              return ARES_ENOMEM;
+          }
+      }
       channel->ndomains = options->ndomains;
     }
 
@@ -711,7 +721,6 @@ static int init_by_defaults(ares_channel channel)
       if (gethostname(hostname, sizeof(hostname)) == -1
           || !strchr(hostname, '.'))
         {
-          channel->domains = malloc(0);
           channel->ndomains = 0;
         }
       else
@@ -940,6 +949,7 @@ static int set_search(ares_channel channel, const char *str)
     for(n=0; n < channel->ndomains; n++)
       free(channel->domains[n]);
     free(channel->domains);
+    channel->domains = NULL;
     channel->ndomains = -1;
   }
 
@@ -955,8 +965,14 @@ static int set_search(ares_channel channel, const char *str)
       n++;
     }
 
+  if (!n)
+    {
+      channel->ndomains = 0;
+      return ARES_SUCCESS;
+    }
+
   channel->domains = malloc(n * sizeof(char *));
-  if (!channel->domains && n)
+  if (!channel->domains)
     return ARES_ENOMEM;
 
   /* Now copy the domains. */