ares_parse_txt_reply: return a ares_txt_reply node for each sub-string
authorPatrick Valsecchi <pvalsecc@cisco.com>
Mon, 22 Apr 2013 21:32:02 +0000 (23:32 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 22 Apr 2013 21:32:02 +0000 (23:32 +0200)
Previously, the function would wrongly return all substrings merged into
one.

ares_parse_txt_reply.3
ares_parse_txt_reply.c

index c9926bc..063b3ff 100644 (file)
@@ -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
index 3a43d6a..981db4c 100644 (file)
@@ -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 */