Line data Source code
1 : /* TLD library -- Test the TLD library by including the tld.c file.
2 : * Copyright (c) 2011-2023 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the
6 : * "Software"), to deal in the Software without restriction, including
7 : * without limitation the rights to use, copy, modify, merge, publish,
8 : * distribute, sublicense, and/or sell copies of the Software, and to
9 : * permit persons to whom the Software is furnished to do so, subject to
10 : * the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included
13 : * in all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 : */
23 :
24 : /** \file
25 : * \brief Test the tld.c, tld_data.c, and tld_domain_to_lowercase.c functions.
26 : *
27 : * This file implements various tests that can directly access the internal
28 : * functions of the tld.c, tld_data.c, and tld_domain_to_lowercase.c
29 : * files.
30 : *
31 : * For that purpose we directly include those files in this test. This
32 : * is why the test is not actually linked against the library, it
33 : * includes it within itself.
34 : */
35 :
36 : // libtld sources
37 : //
38 : #include <libtld/tld.cpp>
39 : #include <libtld/tld_file.cpp>
40 :
41 : extern "C" {
42 : #include <libtld/tld_data.c>
43 : #include <libtld/tld_domain_to_lowercase.c>
44 : #include <libtld/tld_strings.c>
45 : }
46 :
47 :
48 : // C
49 : //
50 : #include <stdlib.h>
51 : #include <string.h>
52 :
53 :
54 :
55 : extern "C" {
56 :
57 :
58 : int err_count = 0;
59 : int verbose = 0;
60 :
61 1 : void test_compare()
62 : {
63 : struct data
64 : {
65 : const char *a;
66 : const char *b;
67 : int n;
68 : int r;
69 : };
70 1 : struct data d[] = {
71 : { "uj", "uk", 2, -1 },
72 : { "uk", "uk", 2, 0 },
73 : { "ul", "uk", 2, 1 },
74 :
75 : { "uj", "ukmore", 2, -1 },
76 : { "uk", "ukstuff", 2, 0 },
77 : { "ul", "ukhere", 2, 1 },
78 :
79 : { "uk1", "ukmore", 2, 1 },
80 : { "uk2", "ukstuff", 2, 1 },
81 : { "uk3", "ukhere", 2, 1 },
82 :
83 : { "uk1", "uk.", 3, 1 },
84 : { "uk2", "uk.", 3, 1 },
85 : { "uk3", "uk.", 3, 1 },
86 :
87 : { "uk1", ".uk", 3, 1 },
88 : { "uk2", ".uk", 3, 1 },
89 : { "uk3", ".uk", 3, 1 },
90 :
91 : { "uk", "uk1", 3, -1 },
92 : { "uk", "uk22", 4, -1 },
93 : { "uk", "uk333", 5, -1 },
94 :
95 : { "uk1", "uk", 2, 1 },
96 : { "uk22", "uk", 2, 1 },
97 : { "uk333", "uk", 2, 1 },
98 : };
99 : int i, r, max;
100 : char *s, *vd, *u;
101 :
102 1 : max = sizeof(d) / sizeof(d[0]);
103 22 : for(i = 0; i < max; ++i)
104 : {
105 21 : r = cmp(d[i].a, strlen(d[i].a), d[i].b, d[i].n);
106 21 : if(r != d[i].r) {
107 0 : fprintf(stderr, "error: cmp() failed with \"%s\" / \"%s\", expected %d and got %d [1]\n",
108 : d[i].a, d[i].b, d[i].r, r);
109 0 : ++err_count;
110 : }
111 :
112 : // create a version with uppercase and try again
113 21 : s = strdup(d[i].b);
114 101 : for(u = s; *u != '\0'; ++u)
115 : {
116 80 : if(*u >= 'a' && *u <= 'z')
117 : {
118 68 : *u &= 0x5F;
119 : }
120 : }
121 21 : vd = tld_domain_to_lowercase(s);
122 21 : r = cmp(d[i].a, strlen(d[i].a), d[i].b, d[i].n);
123 21 : if(r != d[i].r) {
124 0 : fprintf(stderr, "error: cmp() failed with \"%s\" / \"%s\", expected %d and got %d (with domain to lowercase) [2]\n",
125 : d[i].a, d[i].b, d[i].r, r);
126 0 : ++err_count;
127 : }
128 21 : free(vd);
129 21 : free(s);
130 : }
131 1 : }
132 :
133 1 : void test_search()
134 : {
135 : struct search_info
136 : {
137 : int f_start;
138 : int f_end;
139 : const char * f_tld;
140 : int f_length;
141 : int f_result;
142 : };
143 1 : struct search_info d[] = {
144 : /*
145 : * This table is very annoying since each time the data changes
146 : * it gets out of sync. On the other hand that's the best way
147 : * to make sure our tests work like in the real world.
148 : */
149 :
150 : /* get the .uk offset */
151 : { 10339, 11965, "uk", 2, 11847 },
152 :
153 : /* get each offset of the .uk 2nd level domain */
154 : { 10013, 10043, "ac", 2, 10013 },
155 : { 10013, 10043, "barsy", 5, 10014 },
156 : { 10013, 10043, "co", 2, 10015 },
157 : { 10013, 10043, "conn", 4, 10016 },
158 : { 10013, 10043, "copro", 5, 10017 },
159 : { 10013, 10043, "gov", 3, 10018 },
160 : { 10013, 10043, "govt", 4, 10019 },
161 : { 10013, 10043, "hosp", 4, 10020 },
162 : { 10013, 10043, "icnet", 5, 10021 },
163 : { 10013, 10043, "independent-commission", 22, 10022 },
164 : { 10013, 10043, "independent-inquest", 19, 10023 },
165 : { 10013, 10043, "independent-inquiry", 19, 10024 },
166 : { 10013, 10043, "independent-panel", 17, 10025 },
167 : { 10013, 10043, "independent-review", 18, 10026 },
168 : { 10013, 10043, "lea", 3, 10027 },
169 : { 10013, 10043, "ltd", 3, 10028 },
170 : { 10013, 10043, "me", 2, 10029 },
171 : { 10013, 10043, "mil", 3, 10030 },
172 : { 10013, 10043, "net", 3, 10031 },
173 : { 10013, 10043, "nhs", 3, 10032 },
174 : { 10013, 10043, "nimsite", 7, 10033 },
175 : { 10013, 10043, "oraclegovcloudapps", 18, 10034 },
176 : { 10013, 10043, "org", 3, 10035 },
177 : { 10013, 10043, "orgn", 4, 10036 },
178 : { 10013, 10043, "plc", 3, 10037 },
179 : { 10013, 10043, "police", 6, 10038 },
180 : { 10013, 10043, "public-inquiry", 14, 10039 },
181 : { 10013, 10043, "pymnt", 5, 10040 },
182 : { 10013, 10043, "royal-commission", 16, 10041 },
183 : { 10013, 10043, "sch", 3, 10042 },
184 :
185 : /* test with a few invalid TLDs for .uk */
186 : { 10022, 10052, "com", 3, -1 },
187 : { 10022, 10052, "aca", 3, -1 },
188 : { 10022, 10052, "aac", 3, -1 },
189 : { 10022, 10052, "bl", 2, -1 },
190 : { 10022, 10052, "british-library", 15, -1 },
191 : { 10022, 10052, "ca", 2, -1 },
192 : { 10022, 10052, "cn", 2, -1 },
193 : { 10022, 10052, "cp", 2, -1 },
194 : { 10022, 10052, "cz", 2, -1 },
195 : { 10022, 10052, "jet", 3, -1 },
196 : { 10022, 10052, "mod", 3, -1 },
197 : { 10022, 10052, "national-library-scotland", 25, -1 },
198 : { 10022, 10052, "nel", 3, -1 },
199 : { 10022, 10052, "nic", 3, -1 },
200 : { 10022, 10052, "nls", 3, -1 },
201 : { 10022, 10052, "parliament", 10, -1 },
202 : { 10022, 10052, "school", 2, -1 },
203 :
204 : /* get the .vu offset */
205 : { 10339, 11965, "vu", 2, 11894 },
206 :
207 : /* get the 2nd level .vu offsets */
208 : { 10249, 10257, "blog", 4, 10249 },
209 : { 10249, 10257, "cn", 2, 10250 },
210 : { 10249, 10257, "com", 3, 10251 },
211 : { 10249, 10257, "dev", 3, 10252 },
212 : { 10249, 10257, "edu", 3, 10253 },
213 : { 10249, 10257, "me", 2, 10254 },
214 : { 10249, 10257, "net", 3, 10255 },
215 : { 10249, 10257, "org", 3, 10256 },
216 :
217 : /* test with a few .vu 2nd level domains that do not exist */
218 : { 10249, 10257, "gov", 3, -1 },
219 : { 10249, 10257, "nom", 3, -1 },
220 : { 10249, 10257, "sch", 3, -1 },
221 : { 10249, 10257, "zero", 4, -1 },
222 :
223 : /* verify ordering of mari, mari-el, and marine (from .ru) */
224 : { 9282, 9432, "mari", 4, 9349 },
225 : { 9282, 9432, "mari-el", 7, 9350 },
226 : { 9282, 9432, "marine", 6, 9351 },
227 : };
228 :
229 : size_t i;
230 :
231 1 : size_t const max = sizeof(d) / sizeof(d[0]);
232 65 : for(i = 0; i < max; ++i)
233 : {
234 64 : int const r = search(d[i].f_start, d[i].f_end, d[i].f_tld, d[i].f_length);
235 64 : if(r != d[i].f_result)
236 : {
237 0 : fprintf(stderr, "error: test_search() failed with \"%s\", expected %d and got %d [3]\n",
238 : d[i].f_tld, d[i].f_result, r);
239 0 : ++err_count;
240 : }
241 : }
242 1 : }
243 :
244 :
245 1107 : void test_search_array(int start, int end)
246 : {
247 1107 : const struct tld_description * tld(nullptr);
248 1107 : int i(0), r(0);
249 1107 : uint32_t l(0);
250 1107 : const char * name(nullptr);
251 :
252 : /* now test all from the arrays */
253 13072 : for(i = start; i < end; ++i)
254 : {
255 11965 : tld = tld_file_description(g_tld_file, i);
256 11965 : name = tld_file_string(g_tld_file, tld->f_tld, &l);
257 11965 : if(verbose)
258 : {
259 0 : printf("{%d..%d} i = %d, [%.*s]\n", start, end, i, l, name);
260 : }
261 11965 : r = search(start, end, name, l);
262 11965 : if(r != i)
263 : {
264 0 : fprintf(stderr, "error: test_search_array() failed with \"%.*s\", expected %d and got %d [4]\n",
265 : l, name, i, r);
266 0 : ++err_count;
267 : }
268 11965 : if(tld->f_start_offset != USHRT_MAX)
269 : {
270 1106 : test_search_array(tld->f_start_offset, tld->f_end_offset);
271 : }
272 : }
273 1107 : }
274 :
275 1 : void test_search_all()
276 : {
277 1 : test_search_array(
278 1 : g_tld_file->f_header->f_tld_start_offset
279 1 : , g_tld_file->f_header->f_tld_end_offset);
280 1 : }
281 :
282 :
283 1 : int main(int argc, char *argv[])
284 : {
285 1 : fprintf(stderr, "testing internal tld version %s\n", tld_version());
286 :
287 1 : if(argc > 1)
288 : {
289 0 : if(strcmp(argv[1], "-v") == 0)
290 : {
291 0 : verbose = 1;
292 : }
293 : }
294 :
295 : /* call all the tests, one by one
296 : * failures are "recorded" in the err_count global variable
297 : * and the process stops with an error message and exit(1)
298 : * if err_count is not zero.
299 : */
300 1 : test_compare();
301 1 : test_search();
302 1 : test_search_all();
303 :
304 1 : if(err_count)
305 : {
306 0 : fprintf(stderr, "%d error%s occured.\n",
307 0 : err_count, err_count != 1 ? "s" : "");
308 : }
309 1 : exit(err_count ? 1 : 0);
310 : }
311 :
312 : } // extern "C"
313 :
314 : // vim: ts=4 sw=4 et
|