1 | /* Tests for res_hnok and related functions. |
2 | Copyright (C) 2017-2022 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 <array_length.h> |
20 | #include <resolv.h> |
21 | #include <string.h> |
22 | #include <support/check.h> |
23 | #include <support/test-driver.h> |
24 | |
25 | /* Bits which indicate which functions are supposed to report |
26 | success. */ |
27 | enum |
28 | { |
29 | hnok = 1, |
30 | dnok = 2, |
31 | mailok = 4, |
32 | ownok = 8, |
33 | allnomailok = hnok | dnok | ownok, |
34 | allok = hnok | dnok | mailok | ownok |
35 | }; |
36 | |
37 | /* A string of 60 characters. */ |
38 | #define STRING60 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" |
39 | |
40 | /* A string of 63 characters (maximum label length). */ |
41 | #define STRING63 STRING60 "zzz" |
42 | |
43 | /* Combines a test name with the expected results. */ |
44 | struct test_case |
45 | { |
46 | const char *dn; |
47 | unsigned int result; /* Combination of the *ok flags. */ |
48 | }; |
49 | |
50 | static const struct test_case tests[] = |
51 | { |
52 | { "" , allok }, |
53 | { "." , allok }, |
54 | { ".." , 0 }, |
55 | { "www" , allnomailok }, |
56 | { "www." , allnomailok }, |
57 | { "example" , allnomailok }, |
58 | { "example.com" , allok }, |
59 | { "www.example.com" , allok }, |
60 | { "www.example.com." , allok }, |
61 | { "www-.example.com." , allok }, |
62 | { "www.-example.com." , allok }, |
63 | { "*.example.com" , dnok | mailok | ownok }, |
64 | { "-v" , dnok }, |
65 | { "-v.example.com" , mailok | dnok }, |
66 | { "**.example.com" , dnok | mailok }, |
67 | { "www.example.com\\" , 0 }, |
68 | { STRING63, allnomailok }, |
69 | { STRING63 "." , allnomailok }, |
70 | { STRING63 "\\." , 0 }, |
71 | { STRING63 "z" , 0 }, |
72 | { STRING63 ".example.com" , allok }, |
73 | { STRING63 "." STRING63 "." STRING63 "." STRING60 "z" , allok }, |
74 | { STRING63 "." STRING63 "." STRING63 "." STRING60 "z." , allok }, |
75 | { STRING63 "." STRING63 "." STRING63 "." STRING60 "zz" , 0 }, |
76 | { STRING63 "." STRING63 "." STRING63 "." STRING60 "zzz" , 0 }, |
77 | { "hostmaster@mail.example.com" , dnok | mailok }, |
78 | { "hostmaster\\@mail.example.com" , dnok | mailok }, |
79 | { "with whitespace" , 0 }, |
80 | { "with\twhitespace" , 0 }, |
81 | { "with\nwhitespace" , 0 }, |
82 | { "with.whitespace " , 0 }, |
83 | { "with.whitespace\t" , 0 }, |
84 | { "with.whitespace\n" , 0 }, |
85 | { "with\\ whitespace" , 0 }, |
86 | { "with\\\twhitespace" , 0 }, |
87 | { "with\\\nwhitespace" , 0 }, |
88 | { "with.whitespace\\ " , 0 }, |
89 | { "with.whitespace\\\t" , 0 }, |
90 | { "with.whitespace\\\n" , 0 }, |
91 | }; |
92 | |
93 | /* Run test case *TEST with FUNC (named FUNCNAME) and report an error |
94 | if the result does not match the result flag at BIT. */ |
95 | static void |
96 | one_test (const struct test_case *test, const char *funcname, |
97 | int (*func) (const char *), unsigned int bit) |
98 | { |
99 | int expected = (test->result & bit) != 0; |
100 | int actual = func (test->dn); |
101 | if (actual != expected) |
102 | { |
103 | support_record_failure (); |
104 | printf (format: "error: %s (\"%s\"): expected=%d, actual=%d\n" , |
105 | funcname, test->dn, expected, actual); |
106 | } |
107 | } |
108 | |
109 | /* Run 255 tests using all the bytes from 1 to 255, surround the byte |
110 | with the strings PREFIX and SUFFIX, and check that FUNC (named |
111 | FUNCNAME) accepts only those bytes listed in ACCEPTED. */ |
112 | static void |
113 | one_char (const char *prefix, const char *accepted, const char *suffix, |
114 | const char *funcname, int (*func) (const char *)) |
115 | { |
116 | for (int ch = 1; ch <= 255; ++ch) |
117 | { |
118 | char dn[1024]; |
119 | snprintf (s: dn, maxlen: sizeof (dn), format: "%s%c%s" , prefix, ch, suffix); |
120 | int expected = strchr (s: accepted, c: ch) != NULL; |
121 | int actual = func (dn); |
122 | if (actual != expected) |
123 | { |
124 | support_record_failure (); |
125 | printf (format: "error: %s (\"%s\"): expected=%d, actual=%d\n" , |
126 | funcname, dn, expected, actual); |
127 | } |
128 | } |
129 | } |
130 | |
131 | #define LETTERSDIGITS \ |
132 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
133 | |
134 | #define PRINTABLE \ |
135 | "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~" |
136 | |
137 | static int |
138 | do_test (void) |
139 | { |
140 | for (const struct test_case *test = tests; test < array_end (tests); ++test) |
141 | { |
142 | if (test_verbose) |
143 | printf (format: "info: testing domain name [[[%s]]] (0x%x)\n" , |
144 | test->dn, test->result); |
145 | one_test (test, funcname: "res_hnok" , func: res_hnok, bit: hnok); |
146 | one_test (test, funcname: "res_dnok" , func: res_dnok, bit: dnok); |
147 | one_test (test, funcname: "res_mailok" , func: res_mailok, bit: mailok); |
148 | one_test (test, funcname: "res_ownok" , func: res_ownok, bit: ownok); |
149 | } |
150 | |
151 | one_char |
152 | (prefix: "" , LETTERSDIGITS "._" , suffix: "" , funcname: "res_hnok" , func: res_hnok); |
153 | one_char |
154 | (prefix: "middle" , |
155 | LETTERSDIGITS ".-_\\" , /* "middle\\suffix" == "middlesuffix", so good. */ |
156 | suffix: "suffix" , funcname: "res_hnok" , func: res_hnok); |
157 | one_char |
158 | (prefix: "middle" , |
159 | LETTERSDIGITS ".-_" PRINTABLE, |
160 | suffix: "suffix.example" , funcname: "res_mailok" , func: res_mailok); |
161 | one_char |
162 | (prefix: "mailbox.middle" , |
163 | LETTERSDIGITS ".-_\\" , |
164 | suffix: "suffix.example" , funcname: "res_mailok" , func: res_mailok); |
165 | |
166 | return 0; |
167 | } |
168 | |
169 | #include <support/test-driver.c> |
170 | |