• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 1998 Massachusetts Institute of Technology
4  * Copyright (c) The c-ares project and its contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * SPDX-License-Identifier: MIT
26  */
27 
28 #include "ares_setup.h"
29 
30 #ifdef HAVE_NETINET_IN_H
31 #  include <netinet/in.h>
32 #endif
33 
34 #include "ares_nameser.h"
35 
36 #include "ares.h"
37 #include "ares_private.h" /* for the memdebug */
38 
39 /* Simply decodes a length-encoded character string. The first byte of the
40  * input is the length of the string to be returned and the bytes thereafter
41  * are the characters of the string. The returned result will be NULL
42  * terminated.
43  */
ares_expand_string_ex(const unsigned char * encoded,const unsigned char * abuf,size_t alen,unsigned char ** s,size_t * enclen)44 ares_status_t ares_expand_string_ex(const unsigned char *encoded,
45                                     const unsigned char *abuf, size_t alen,
46                                     unsigned char **s, size_t *enclen)
47 {
48   ares_status_t status;
49   ares__buf_t  *buf = NULL;
50   size_t        start_len;
51   size_t        len = 0;
52 
53   if (encoded == NULL || abuf == NULL || alen == 0 || enclen == NULL) {
54     return ARES_EBADSTR; /* EFORMERR would be better */
55   }
56 
57   if (encoded < abuf || encoded >= abuf + alen) {
58     return ARES_EBADSTR; /* EFORMERR would be better */
59   }
60 
61   *enclen = 0;
62 
63   /* NOTE: we allow 's' to be NULL to skip it */
64   if (s) {
65     *s = NULL;
66   }
67 
68   buf = ares__buf_create_const(abuf, alen);
69 
70   if (buf == NULL) {
71     return ARES_ENOMEM;
72   }
73 
74   status = ares__buf_set_position(buf, (size_t)(encoded - abuf));
75   if (status != ARES_SUCCESS) {
76     goto done;
77   }
78 
79   start_len = ares__buf_len(buf);
80   status =
81     ares__buf_parse_dns_binstr(buf, ares__buf_len(buf), s, &len, ARES_FALSE);
82   /* hrm, no way to pass back 'len' with the prototype */
83   if (status != ARES_SUCCESS) {
84     goto done;
85   }
86 
87   *enclen = start_len - ares__buf_len(buf);
88 
89 done:
90   ares__buf_destroy(buf);
91   if (status == ARES_EBADNAME || status == ARES_EBADRESP) {
92     status = ARES_EBADSTR;
93   }
94   return status;
95 }
96 
ares_expand_string(const unsigned char * encoded,const unsigned char * abuf,int alen,unsigned char ** s,long * enclen)97 int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
98                        int alen, unsigned char **s, long *enclen)
99 {
100   ares_status_t status;
101   size_t        temp_enclen = 0;
102 
103   if (alen < 0) {
104     return ARES_EBADRESP;
105   }
106 
107   status = ares_expand_string_ex(encoded, abuf, (size_t)alen, s, &temp_enclen);
108 
109   *enclen = (long)temp_enclen;
110   return (int)status;
111 }
112