ares_data.c: iterate through substructs when freeing

Previous code recursed into substructures, which makes it more likely
that large/heavily-nested responses could use up lots of stack.
pull/154/head
David Drysdale 8 years ago committed by David Drysdale
parent 3768a2da5a
commit 10bf61065b
  1. 147
      ares_data.c

@ -40,10 +40,9 @@
void ares_free_data(void *dataptr) void ares_free_data(void *dataptr)
{ {
struct ares_data *ptr; while (dataptr != NULL) {
struct ares_data *ptr;
if (!dataptr) void *next_data = NULL;
return;
#ifdef __INTEL_COMPILER #ifdef __INTEL_COMPILER
# pragma warning(push) # pragma warning(push)
@ -51,80 +50,82 @@ void ares_free_data(void *dataptr)
/* 1684: conversion from pointer to same-sized integral type */ /* 1684: conversion from pointer to same-sized integral type */
#endif #endif
ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
#ifdef __INTEL_COMPILER #ifdef __INTEL_COMPILER
# pragma warning(pop) # pragma warning(pop)
#endif #endif
if (ptr->mark != ARES_DATATYPE_MARK) if (ptr->mark != ARES_DATATYPE_MARK)
return; return;
switch (ptr->type) switch (ptr->type)
{ {
case ARES_DATATYPE_MX_REPLY: case ARES_DATATYPE_MX_REPLY:
if (ptr->data.mx_reply.next) if (ptr->data.mx_reply.next)
ares_free_data(ptr->data.mx_reply.next); next_data = ptr->data.mx_reply.next;
if (ptr->data.mx_reply.host) if (ptr->data.mx_reply.host)
ares_free(ptr->data.mx_reply.host); ares_free(ptr->data.mx_reply.host);
break; break;
case ARES_DATATYPE_SRV_REPLY: case ARES_DATATYPE_SRV_REPLY:
if (ptr->data.srv_reply.next) if (ptr->data.srv_reply.next)
ares_free_data(ptr->data.srv_reply.next); next_data = ptr->data.srv_reply.next;
if (ptr->data.srv_reply.host) if (ptr->data.srv_reply.host)
ares_free(ptr->data.srv_reply.host); ares_free(ptr->data.srv_reply.host);
break; break;
case ARES_DATATYPE_TXT_REPLY: case ARES_DATATYPE_TXT_REPLY:
case ARES_DATATYPE_TXT_EXT: case ARES_DATATYPE_TXT_EXT:
if (ptr->data.txt_reply.next) if (ptr->data.txt_reply.next)
ares_free_data(ptr->data.txt_reply.next); next_data = ptr->data.txt_reply.next;
if (ptr->data.txt_reply.txt) if (ptr->data.txt_reply.txt)
ares_free(ptr->data.txt_reply.txt); ares_free(ptr->data.txt_reply.txt);
break; break;
case ARES_DATATYPE_ADDR_NODE: case ARES_DATATYPE_ADDR_NODE:
if (ptr->data.addr_node.next) if (ptr->data.addr_node.next)
ares_free_data(ptr->data.addr_node.next); next_data = ptr->data.addr_node.next;
break; break;
case ARES_DATATYPE_ADDR_PORT_NODE: case ARES_DATATYPE_ADDR_PORT_NODE:
if (ptr->data.addr_port_node.next) if (ptr->data.addr_port_node.next)
ares_free_data(ptr->data.addr_port_node.next); next_data = ptr->data.addr_port_node.next;
break; break;
case ARES_DATATYPE_NAPTR_REPLY: case ARES_DATATYPE_NAPTR_REPLY:
if (ptr->data.naptr_reply.next) if (ptr->data.naptr_reply.next)
ares_free_data(ptr->data.naptr_reply.next); next_data = ptr->data.naptr_reply.next;
if (ptr->data.naptr_reply.flags) if (ptr->data.naptr_reply.flags)
ares_free(ptr->data.naptr_reply.flags); ares_free(ptr->data.naptr_reply.flags);
if (ptr->data.naptr_reply.service) if (ptr->data.naptr_reply.service)
ares_free(ptr->data.naptr_reply.service); ares_free(ptr->data.naptr_reply.service);
if (ptr->data.naptr_reply.regexp) if (ptr->data.naptr_reply.regexp)
ares_free(ptr->data.naptr_reply.regexp); ares_free(ptr->data.naptr_reply.regexp);
if (ptr->data.naptr_reply.replacement) if (ptr->data.naptr_reply.replacement)
ares_free(ptr->data.naptr_reply.replacement); ares_free(ptr->data.naptr_reply.replacement);
break; break;
case ARES_DATATYPE_SOA_REPLY: case ARES_DATATYPE_SOA_REPLY:
if (ptr->data.soa_reply.nsname) if (ptr->data.soa_reply.nsname)
ares_free(ptr->data.soa_reply.nsname); ares_free(ptr->data.soa_reply.nsname);
if (ptr->data.soa_reply.hostmaster) if (ptr->data.soa_reply.hostmaster)
ares_free(ptr->data.soa_reply.hostmaster); ares_free(ptr->data.soa_reply.hostmaster);
break; break;
default: default:
return; return;
} }
ares_free(ptr); ares_free(ptr);
dataptr = next_data;
}
} }

Loading…
Cancel
Save