diff options
author | Patrick Valsecchi <pvalsecc@cisco.com> | 2013-04-22 23:32:02 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2013-04-22 23:32:02 +0200 |
commit | b5135bbc66cf6f0a884937a9eccc61ac795b1ee0 (patch) | |
tree | f8f06624b9a70826fabfb0492f18f9a1e69e1e8c | |
parent | 9a92b80191af997c910fca973307bef339e7b767 (diff) | |
download | c-ares-b5135bbc66cf6f0a884937a9eccc61ac795b1ee0.tar.gz c-ares-b5135bbc66cf6f0a884937a9eccc61ac795b1ee0.tar.bz2 c-ares-b5135bbc66cf6f0a884937a9eccc61ac795b1ee0.zip |
ares_parse_txt_reply: return a ares_txt_reply node for each sub-string
Previously, the function would wrongly return all substrings merged into
one.
-rw-r--r-- | ares_parse_txt_reply.3 | 2 | ||||
-rw-r--r-- | ares_parse_txt_reply.c | 84 |
2 files changed, 38 insertions, 48 deletions
diff --git a/ares_parse_txt_reply.3 b/ares_parse_txt_reply.3 index c9926bc..063b3ff 100644 --- a/ares_parse_txt_reply.3 +++ b/ares_parse_txt_reply.3 @@ -27,7 +27,7 @@ ares_parse_txt_reply \- Parse a reply to a DNS query of type TXT The .B ares_parse_txt_reply function parses the response to a query of type TXT into a -linked list of +linked list (one element per sub-string) of .I struct ares_txt_reply The parameters .I abuf diff --git a/ares_parse_txt_reply.c b/ares_parse_txt_reply.c index 3a43d6a..981db4c 100644 --- a/ares_parse_txt_reply.c +++ b/ares_parse_txt_reply.c @@ -48,7 +48,7 @@ int ares_parse_txt_reply (const unsigned char *abuf, int alen, struct ares_txt_reply **txt_out) { - size_t substr_len, str_len; + size_t substr_len; unsigned int qdcount, ancount, i; const unsigned char *aptr; const unsigned char *strptr; @@ -115,23 +115,6 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, /* Check if we are really looking at a TXT record */ if (rr_class == C_IN && rr_type == T_TXT) { - /* Allocate storage for this TXT answer appending it to the list */ - txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY); - if (!txt_curr) - { - status = ARES_ENOMEM; - break; - } - if (txt_last) - { - txt_last->next = txt_curr; - } - else - { - txt_head = txt_curr; - } - txt_last = txt_curr; - /* * There may be multiple substrings in a single TXT record. Each * substring may be up to 255 characters in length, with a @@ -140,42 +123,49 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, * substrings contained therein. */ - /* Compute total length to allow a single memory allocation */ strptr = aptr; while (strptr < (aptr + rr_len)) { substr_len = (unsigned char)*strptr; - txt_curr->length += substr_len; - strptr += substr_len + 1; - } - - if (strptr != (aptr + rr_len)) - { - status = ARES_EBADRESP; - break; - } - - /* Including null byte */ - txt_curr->txt = malloc (txt_curr->length + 1); - if (txt_curr->txt == NULL) - { - status = ARES_ENOMEM; - break; - } + if (strptr + substr_len + 1 > aptr + rr_len) + { + status = ARES_EBADRESP; + break; + } + + ++strptr; + + /* Allocate storage for this TXT answer appending it to the list */ + txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY); + if (!txt_curr) + { + status = ARES_ENOMEM; + break; + } + if (txt_last) + { + txt_last->next = txt_curr; + } + else + { + txt_head = txt_curr; + } + txt_last = txt_curr; + + txt_curr->length = substr_len; + txt_curr->txt = malloc (substr_len + 1/* Including null byte */); + if (txt_curr->txt == NULL) + { + status = ARES_ENOMEM; + break; + } + memcpy ((char *) txt_curr->txt, strptr, substr_len); + + /* Make sure we NULL-terminate */ + txt_curr->txt[substr_len] = 0; - /* Step through the list of substrings, concatenating them */ - str_len = 0; - strptr = aptr; - while (strptr < (aptr + rr_len)) - { - substr_len = (unsigned char)*strptr; - strptr++; - memcpy ((char *) txt_curr->txt + str_len, strptr, substr_len); - str_len += substr_len; strptr += substr_len; } - /* Make sure we NULL-terminate */ - *((char *) txt_curr->txt + txt_curr->length) = '\0'; } /* Don't lose memory in the next iteration */ |