Brad House provided a fix for ares_save_options(): Apparently I overlooked
authorDaniel Stenberg <daniel@haxx.se>
Sat, 22 Sep 2007 20:45:50 +0000 (20:45 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 22 Sep 2007 20:45:50 +0000 (20:45 +0000)
something with the ares_save_options() where it would try to do a malloc(0)
when no options of that type needed to be saved.  On most platforms, this was
fine because malloc(0) doesn't actually return NULL, but on AIX it does, so
ares_save_options would return ARES_ENOMEM.

CHANGES
ares_init.c

diff --git a/CHANGES b/CHANGES
index 86d46ed..160489c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,17 @@
   Changelog for the c-ares project
 
+* September 22 2007 (Daniel Stenberg)
+
+- Brad House provided a fix for ares_save_options():
+
+  Apparently I overlooked something with the ares_save_options() where it
+  would try to do a malloc(0) when no options of that type needed to be saved.
+  On most platforms, this was fine because malloc(0) doesn't actually return
+  NULL, but on AIX it does, so ares_save_options would return ARES_ENOMEM.
+
 * July 14 2007 (Daniel Stenberg)
 
 - Vlad Dinulescu fixed two outstanding valgrind reports:
-
  
   1. In ares_query.c , in find_query_by_id we compare q->qid (which is a short
   int variable) with qid, which is declared as an int variable.  Moreover,
index 06dbb6c..add3ffe 100644 (file)
@@ -244,40 +244,49 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
   options->sock_state_cb_data = channel->sock_state_cb_data;
 
   /* Copy servers */
-  options->servers =
-    malloc(channel->nservers * sizeof(struct server_state));
-  if (!options->servers && channel->nservers != 0)
-    return ARES_ENOMEM;
-  for (i = 0; i < channel->nservers; i++)
-    options->servers[i] = channel->servers[i].addr;
+  if (channel->nservers) {
+    options->servers =
+      malloc(channel->nservers * sizeof(struct server_state));
+    if (!options->servers && channel->nservers != 0)
+      return ARES_ENOMEM;
+    for (i = 0; i < channel->nservers; i++)
+      options->servers[i] = channel->servers[i].addr;
+  }
   options->nservers = channel->nservers;
 
   /* copy domains */
-  options->domains = malloc(channel->ndomains * sizeof(char *));
-  if (!options->domains)
-    return ARES_ENOMEM;
-  for (i = 0; i < channel->ndomains; i++)
-  {
-    options->ndomains = i;
-    options->domains[i] = strdup(channel->domains[i]);
-    if (!options->domains[i])
+  if (channel->ndomains) {
+    options->domains = malloc(channel->ndomains * sizeof(char *));
+    if (!options->domains)
       return ARES_ENOMEM;
+
+    for (i = 0; i < channel->ndomains; i++)
+    {
+      options->ndomains = i;
+      options->domains[i] = strdup(channel->domains[i]);
+      if (!options->domains[i])
+        return ARES_ENOMEM;
+    }
   }
   options->ndomains = channel->ndomains;
 
   /* copy lookups */
-  options->lookups = strdup(channel->lookups);
-  if (!options->lookups)
-    return ARES_ENOMEM;
+  if (channel->lookups) {
+    options->lookups = strdup(channel->lookups);
+    if (!options->lookups && channel->lookups)
+      return ARES_ENOMEM;
+  }
 
   /* copy sortlist */
-  options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
-  if (!options->sortlist)
-    return ARES_ENOMEM;
-  for (i = 0; i < channel->nsort; i++)
-  {
-    memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
-           sizeof(struct apattern));
+  if (channel->nsort) {
+    options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
+    if (!options->sortlist)
+      return ARES_ENOMEM;
+    for (i = 0; i < channel->nsort; i++)
+    {
+      memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
+             sizeof(struct apattern));
+    }
   }
   options->nsort = channel->nsort;