1 /* Tests for ns_name_pton.
2    Copyright (C) 2017-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <arpa/nameser.h>
20 #include <array_length.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <support/check.h>
26 #include <support/support.h>
27 #include <support/test-driver.h>
28 
29 /* Bits which indicate which functions are supposed to report
30    success.  */
31 enum
32   {
33     hnok = 1,
34     dnok = 2,
35     mailok = 4,
36     ownok = 8,
37     allnomailok = hnok | dnok | ownok,
38     allok = hnok | dnok | mailok | ownok
39   };
40 
41 /* A string of 60 characters.  */
42 #define STRING60 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
43 
44 /* A string of 63 characters (maximum label length).  */
45 #define STRING63 STRING60 "zzz"
46 
47 /* A string of 60 bytes (non-ASCII).  */
48 #define STRING60OCT \
49   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
50   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
51   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
52   "\377\377\377\377\377\377\377\377\377"
53 
54 /* A string of 63 bytes (non-ASCII).  */
55 #define STRING63OCT STRING60OCT "\377\377\377"
56 
57 /* A string of 60 bytes (non-ASCII, quoted decimal).  */
58 #define STRING60DEC \
59   "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
60   "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
61   "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
62   "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
63   "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
64   "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255"
65 
66 /* A string of 63 bytes (non-ASCII, quoted decimal).  */
67 #define STRING63DEC STRING60DEC "\\255\\255\\255"
68 
69 /* Combines a test name with the expected results.  */
70 struct test_case
71 {
72   const char *dn;
73   const char *back; /* Expected test result converted using ns_name_ntop.  */
74   bool fully_qualified; /* True if the domain name has a trailing dot.  */
75 };
76 
77 static const struct test_case tests[] =
78   {
79     { "", ".", false },
80     { ".", ".", true },
81     { "..", NULL, },
82     { "www", "www", false },
83     { "www.", "www", true },
84     { "www\\.", "www\\.", false },
85     { ".www", NULL, },
86     { ".www\\.", NULL, },
87     { "example.com", "example.com", false },
88     { "example.com.", "example.com", true },
89     { ".example.com", NULL, },
90     { ".example.com.", NULL, },
91     { "example\\.com", "example\\.com", false },
92     { "example\\.com.", "example\\.com", true },
93     { "example..", NULL, },
94     { "example..com", NULL, },
95     { "example..com", NULL, },
96     { "\\0", NULL, },
97     { "\\00", NULL, },
98     { "\\000", "\\000", false },
99     { "\\1", NULL, },
100     { "\\01", NULL, },
101     { "\\001", "\\001", false },
102     { "\\1x", NULL, },
103     { "\\01x", NULL, },
104     { "\\001x", "\\001x", false },
105     { "\\256", NULL, },
106     { "\\0641", "\\@1", false },
107     { "\\0011", "\\0011", false },
108     { STRING63, STRING63, false },
109     { STRING63 ".", STRING63, true },
110     { STRING63 "z", NULL, },
111     { STRING63 "\\.", NULL, },
112     { STRING60 "zz\\.", STRING60 "zz\\.", false },
113     { STRING60 "zz\\..", STRING60 "zz\\.", true },
114     { STRING63 "." STRING63 "." STRING63 "." STRING60 "z",
115       STRING63 "." STRING63 "." STRING63 "." STRING60 "z", false },
116     { STRING63 "." STRING63 "." STRING63 "." STRING60 "z.",
117       STRING63 "." STRING63 "." STRING63 "." STRING60 "z", true },
118     { STRING63 "." STRING63 "." STRING63 "." STRING60 "zz", NULL, },
119     { STRING63 "." STRING63 "." STRING63 "." STRING60 "zzz", NULL, },
120     { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT "\377",
121       STRING63DEC "." STRING63DEC "." STRING63DEC "." STRING60DEC "\\255",
122       false },
123     { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT "\377.",
124       STRING63DEC "." STRING63DEC "." STRING63DEC "." STRING60DEC "\\255",
125       true },
126     { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
127       "\377\377", NULL, },
128     { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
129       "\377\377\377", NULL, },
130     { "\\", NULL, },
131     { "\\\\", "\\\\", false },
132     { "\\\\.", "\\\\", true },
133     { "\\\\\\", NULL, },
134     { "a\\", NULL, },
135     { "a.\\", NULL, },
136     { "a.b\\", NULL, },
137   };
138 
139 static int
do_test(void)140 do_test (void)
141 {
142   unsigned char *wire = xmalloc (NS_MAXCDNAME);
143   char *text = xmalloc (NS_MAXDNAME);
144   for (const struct test_case *test = tests; test < array_end (tests); ++test)
145     {
146       if (test_verbose)
147         printf ("info: testing domain name [[[%s]]]\n", test->dn);
148       int ret = ns_name_pton (test->dn, wire, NS_MAXCDNAME);
149       if (ret == -1)
150         {
151           if (test->back != NULL)
152             {
153               support_record_failure ();
154               printf ("error: unexpected decoding failure for [[%s]]\n",
155                       test->dn);
156             }
157           /* Otherwise, we have an expected decoding failure.  */
158           continue;
159         }
160 
161       if (ret < -1 || ret > 1)
162         {
163           support_record_failure ();
164           printf ("error: invalid return value %d for [[%s]]\n",
165                   ret, test->dn);
166           continue;
167         }
168 
169       int ret2 = ns_name_ntop (wire, text, NS_MAXDNAME);
170 
171       if (ret2 < 0)
172         {
173           support_record_failure ();
174           printf ("error: failure to convert back [[%s]]\n", test->dn);
175         }
176 
177       if (test->back == NULL)
178         {
179           support_record_failure ();
180           printf ("error: unexpected success converting [[%s]]\n", test->dn);
181           if (ret2 >= 1)
182             printf ("error:   result converts back to [[%s]]\n", test->dn);
183           continue;
184         }
185 
186       if (strcmp (text, test->back) != 0)
187         {
188           support_record_failure ();
189           printf ("error: back-conversion of [[%s]] did not match\n",
190                   test->dn);
191           printf ("error:   expected: [[%s]]\n", test->back);
192           printf ("error:     actual: [[%s]]\n", text);
193         }
194 
195       if (ret != test->fully_qualified)
196         {
197           support_record_failure ();
198           printf ("error: invalid fully-qualified status for [[%s]]\n",
199                   test->dn);
200           printf ("error:   expected: %d\n", (int) test->fully_qualified);
201           printf ("error:     actual: %d\n", ret);
202         }
203     }
204 
205   free (text);
206   free (wire);
207   return 0;
208 }
209 
210 #include <support/test-driver.c>
211