Line data Source code
1 : /* TLD library -- test the TLD interface
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() function like an end user.
26 : *
27 : * This file implements various tests verifying the tld() function.
28 : * The tests defined here are not for coverage but rather edge
29 : * cases which could be hard to expect in a full coverage test.
30 : */
31 :
32 : // libtld
33 : //
34 : #include <libtld/tld.h>
35 : #include <libtld/tld_data.h>
36 : #include <libtld/tld_file.h>
37 :
38 :
39 : // C
40 : //
41 : #include <string.h>
42 : #include <stdlib.h>
43 : #include <stdio.h>
44 : #include <limits.h>
45 :
46 :
47 :
48 :
49 :
50 :
51 : int err_count = 0;
52 : int verbose = 0;
53 :
54 : /*
55 : * This test calls the tld() function with all the TLDs and then
56 : * with wrong TLDs to make sure that the tld() functions works as
57 : * expected.
58 : *
59 : * extern enum tld_result tld(const char *uri, struct tld_info *info);
60 : */
61 :
62 :
63 : char * g_filename1 = "../../BUILD/Debug/contrib/libtld/libtld/tlds.tld";
64 : char * g_filename2 = "../libtld/tlds.tld";
65 : struct tld_file * g_tld_file = NULL;
66 :
67 :
68 : /* we get access to the table with all the TLDs so we can go through them all
69 : * the library does not give direct access by default... (although maybe we
70 : * could give users access to the data)
71 : */
72 1 : void load_tlds()
73 : {
74 : enum tld_file_error err;
75 :
76 1 : err = tld_file_load(g_filename1, &g_tld_file);
77 1 : if(err == TLD_FILE_ERROR_NONE)
78 : {
79 1 : return;
80 : }
81 :
82 0 : err = tld_file_load(g_filename2, &g_tld_file);
83 0 : if(err == TLD_FILE_ERROR_NONE)
84 : {
85 0 : return;
86 : }
87 :
88 0 : fprintf(stderr, "fatal error: could not read TLD files \"%s\" or \"%s\".\n",
89 : g_filename1, g_filename2);
90 0 : exit(1);
91 : }
92 :
93 :
94 1 : void free_tlds()
95 : {
96 1 : tld_file_free(&g_tld_file);
97 1 : }
98 :
99 :
100 : /** \brief Build an extension from any offset.
101 : *
102 : * Create a domain name extensions from any entry in the TLD
103 : * descriptions.
104 : *
105 : * \param[in] offset The offset in the tld_descriptions table
106 : * \param[in] uri The URI buffer
107 : *
108 : * \return true if the first TLD is a star ("*").
109 : */
110 59920 : int cat_ext(int offset, char * uri)
111 : {
112 : int o, has_star;
113 59920 : uint32_t k, l;
114 : struct tld_description const * tld;
115 : char const * name;
116 59920 : char * d = uri;
117 :
118 1998250 : while(*d != '\0')
119 : {
120 1938330 : ++d;
121 : }
122 :
123 59920 : tld = tld_file_description(g_tld_file, offset);
124 59920 : name = tld_file_string(g_tld_file, tld->f_tld, &l);
125 :
126 : // verify that the names do match between the library TLDs file and
127 : // our copy of the file
128 : {
129 59920 : struct tld_file const * lib_tld = tld_get_tlds();
130 59920 : tld = tld_file_description(lib_tld, offset);
131 59920 : uint32_t length = 2000;
132 59920 : char const * name2 = tld_file_string(lib_tld, tld->f_tld, &length);
133 59920 : if(l != length || memcmp(name, name2, l) != 0)
134 : {
135 0 : fprintf(stderr, "error: the names in our and the library files do not match: [%.*s] vs [%.*s]\n",
136 : l, name, length, name2);
137 0 : abort();
138 : }
139 : }
140 :
141 59920 : has_star = l == 1 && name[0] == '*';
142 :
143 59920 : if(!has_star)
144 : {
145 59110 : *d++ = '.';
146 460270 : for(; *name != '\0' && l > 0; --l)
147 : {
148 401160 : *d++ = *name++;
149 : }
150 : //strcat(uri, ".");
151 : //strncat(uri, name, l);
152 : }
153 59920 : o = offset;
154 662052290 : for(k = offset + 1; k < g_tld_file->f_descriptions_count; ++k)
155 : {
156 661992370 : tld = tld_file_description(g_tld_file, k);
157 661992370 : if(o >= tld->f_start_offset
158 60325135 : && o < tld->f_end_offset)
159 : {
160 : /* found a parent */
161 76140 : name = tld_file_string(g_tld_file, tld->f_tld, &l);
162 76140 : if(l != 1 || name[0] != '*')
163 : {
164 76140 : *d++ = '.';
165 392505 : for(; *name != '\0' && l > 0; --l)
166 : {
167 316365 : *d++ = *name++;
168 : }
169 : }
170 : else
171 : {
172 0 : fprintf(stderr, "fatal error: found \"*\" at the wrong place; it's only supported as the very first segment.\n");
173 0 : exit(1);
174 : }
175 76140 : o = k;
176 76140 : k = tld->f_end_offset;
177 : }
178 : }
179 :
180 59920 : *d = '\0';
181 :
182 59920 : return has_star;
183 : }
184 :
185 :
186 :
187 :
188 : struct test_uris
189 : {
190 : const char * f_uri;
191 : enum tld_result f_result;
192 : int f_offset;
193 : };
194 :
195 :
196 : const struct test_uris g_uris[] =
197 : {
198 : {
199 : "advisor-z2-ngprod-1997768525.us-west-2.elb.amazonaws.com",
200 : TLD_RESULT_SUCCESS,
201 : 28,
202 : },
203 : {
204 : "us-west-2.elb.amazonaws.com",
205 : TLD_RESULT_SUCCESS,
206 : 0,
207 : },
208 : {
209 : "m2osw.com",
210 : TLD_RESULT_SUCCESS,
211 : 5,
212 : },
213 : {
214 : ".com",
215 : TLD_RESULT_SUCCESS,
216 : 0,
217 : },
218 : {
219 : "com",
220 : TLD_RESULT_NO_TLD,
221 : -1,
222 : },
223 : {
224 : ".ar",
225 : TLD_RESULT_SUCCESS,
226 : 0,
227 : },
228 : {
229 : "int.ar",
230 : TLD_RESULT_SUCCESS,
231 : 0,
232 : },
233 : {
234 : "blah.int.ar",
235 : TLD_RESULT_SUCCESS,
236 : 4,
237 : },
238 : {
239 : "orange.blah.int.ar",
240 : TLD_RESULT_SUCCESS,
241 : 11,
242 : },
243 : {
244 : "congresodelalengua3.ar", /* congresodelalengua3 is an exceptional 2nd level */
245 : TLD_RESULT_SUCCESS,
246 : 19,
247 : },
248 : {
249 : "special.congresodelalengua3.ar", /* congresodelalengua3 is an exceptional 2nd level */
250 : TLD_RESULT_SUCCESS,
251 : 27,
252 : },
253 : {
254 : "night-club.kawasaki.jp",
255 : TLD_RESULT_SUCCESS,
256 : 0,
257 : },
258 : {
259 : "orange.night-club.kawasaki.jp",
260 : TLD_RESULT_SUCCESS,
261 : 6,
262 : },
263 : };
264 :
265 :
266 : /*
267 : * This tests various ad hoc domains with expected results.
268 : *
269 : * This way we can verify specific things we want to check.
270 : */
271 1 : void test_specific()
272 : {
273 14 : for(size_t idx = 0; idx < sizeof(g_uris) / sizeof(g_uris[0]); ++idx)
274 : {
275 13 : struct tld_info info;
276 13 : enum tld_result r = tld(g_uris[idx].f_uri, &info);
277 13 : if(verbose)
278 : {
279 0 : fprintf(
280 : stderr
281 : , "info: URI \"%s\" returned %d and TLD is \"%s\"\n"
282 0 : , g_uris[idx].f_uri
283 : , r
284 0 : , g_uris[idx].f_uri + info.f_offset);
285 : }
286 :
287 13 : if(r != g_uris[idx].f_result)
288 : {
289 0 : fprintf(stderr, "error: testing URI \"%s\" got result %d, expected %d and TLD of \"%s\"\n",
290 0 : g_uris[idx].f_uri, r, g_uris[idx].f_result,
291 0 : g_uris[idx].f_uri + g_uris[idx].f_offset);
292 0 : ++err_count;
293 : }
294 13 : else if(info.f_offset != g_uris[idx].f_offset)
295 : {
296 0 : fprintf(stderr, "error: testing URI \"%s\" got offset %d, expected %d and TLD of \"%s\"\n",
297 0 : g_uris[idx].f_uri, info.f_offset, g_uris[idx].f_offset,
298 0 : g_uris[idx].f_uri + info.f_offset);
299 0 : ++err_count;
300 : }
301 : }
302 1 : }
303 :
304 :
305 : /*
306 : * This test goes through all the domain names and extracts the domain,
307 : * sub-domains and TLDs. (Or at least verifies that we get the correct
308 : * information in order to do so.)
309 : *
310 : * It builds a URI with zero to many sub-domain names, adds a specific
311 : * domain name, then append a complete TLD. The result is then checked
312 : * with the tld() function from the library. The tld() is expected to
313 : * either return VALID or INVALID but nothing else (since all those
314 : * TLDs exist in our table.) Then we verify that the returned offset is
315 : * a perfect match.
316 : */
317 1 : void test_all()
318 : {
319 1 : char const * sub_domains[] = {
320 : "",
321 : "www.",
322 : "tld.",
323 : "george.snap.",
324 : "very.long.sub.domain.ext.en.sion.here."
325 : "host.%20.space."
326 : "host.%fa.u-acute."
327 : "host.%FA.U-acute."
328 : };
329 1 : struct tld_info info;
330 1 : char uri[256], extension_uri[256];
331 : char const * name;
332 1 : uint32_t i, j, l, p, max_subdomains;
333 : int has_star, sub_has_star;
334 : enum tld_result r;
335 : struct tld_description const * tld_desc;
336 : struct tld_description const * sub_tld;
337 :
338 1 : max_subdomains = sizeof(sub_domains) / sizeof(sub_domains[0]);
339 :
340 11966 : for(i = 0; i < g_tld_file->f_descriptions_count; ++i)
341 : {
342 71790 : for(j = 0; j < max_subdomains; ++j)
343 : {
344 59825 : strcpy(uri, sub_domains[j]);
345 59825 : strcat(uri, "domain-name");
346 59825 : has_star = cat_ext(i, uri);
347 :
348 : /* just in case make sure that we did not overflow the buffer */
349 59825 : if(strlen(uri) >= sizeof(uri))
350 : {
351 0 : fprintf(stderr, "fatal error: the URI \"%s\" is longer than the uri[] array.\n", uri);
352 0 : exit(1);
353 : }
354 :
355 : /* reset the structure so we can verify it gets initialized */
356 59825 : memset(&info, 0xFE, sizeof(info));
357 :
358 59825 : r = tld(uri, &info);
359 : #if 0
360 : if(i == 5108)
361 : {
362 : for(size_t l = 0; l < sizeof(info); ++l)
363 : {
364 : if((l % 16) == 0 && l > 0)
365 : {
366 : fprintf(stderr, "\n");
367 : }
368 : fprintf(stderr, "0x%02X ", ((unsigned char*)&info)[l]);
369 : }
370 : fprintf(stderr, "\nresult for [%s]: category[%d], status[%d/%%d n.a.], country[%s],"
371 : " tld[%s], offset[%d]\n",
372 : uri,
373 : (int)info.f_category,
374 : (int)info.f_status, //(int)tld_descriptions[i].f_status,
375 : info.f_country,
376 : info.f_tld, (int)info.f_offset);
377 : }
378 : #endif
379 59825 : p = i;
380 59825 : tld_desc = tld_file_description(g_tld_file, i);
381 59825 : if(tld_desc->f_status == TLD_STATUS_EXCEPTION)
382 : {
383 95 : if(tld_desc->f_exception_apply_to == USHRT_MAX)
384 : {
385 0 : fprintf(stderr, "error: domain name for \"%s\" (%d) is said to be an exception but it has no apply-to parameter. (result: %d)\n",
386 : uri, i, r);
387 0 : ++err_count;
388 : }
389 : else
390 : {
391 95 : p = tld_desc->f_exception_apply_to;
392 : }
393 : }
394 59825 : if(tld_desc->f_status == TLD_STATUS_VALID)
395 : {
396 48975 : if(r != TLD_RESULT_SUCCESS)
397 : {
398 0 : fprintf(stderr, "error: valid domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
399 : uri, i, r);
400 0 : ++err_count;
401 : }
402 48975 : else if(has_star)
403 : {
404 : /* the "domain-name" is absorbed as part of the TLD */
405 810 : int expected = strlen(sub_domains[j]);
406 810 : if(expected != 0)
407 : {
408 648 : --expected; /* ignore the "." */
409 : }
410 810 : if(info.f_offset != expected)
411 : {
412 0 : fprintf(stderr, "error: valid domain name for \"%s\" (%d) could not be extracted successfully (offset: %d, expected: %d)\n",
413 : uri, i,
414 : info.f_offset, expected);
415 0 : ++err_count;
416 : }
417 : }
418 : else
419 : {
420 : /* verify the top domain name */
421 48165 : if(info.f_offset < 11)
422 : {
423 0 : fprintf(stderr, "error: somehow the top domain name in \"%s\" (%d) cannot properly be extracted\n",
424 : uri, i);
425 0 : ++err_count;
426 : }
427 48165 : else if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
428 : {
429 0 : fprintf(stderr, "error: valid domain name for \"%s\" (%d) could not be extracted successfully (offset: %d)\n",
430 : uri, i, info.f_offset);
431 0 : ++err_count;
432 : }
433 : /*
434 : else
435 : fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
436 : */
437 : }
438 : }
439 10850 : else if(tld_desc->f_status == TLD_STATUS_EXCEPTION)
440 : {
441 95 : if(r != TLD_RESULT_SUCCESS)
442 : {
443 0 : fprintf(stderr, "error: exceptional domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
444 : uri, i, r);
445 0 : ++err_count;
446 : }
447 : else
448 : {
449 95 : extension_uri[0] = '\0';
450 95 : cat_ext(p, extension_uri);
451 95 : if(strcmp(info.f_tld, extension_uri) != 0)
452 : //if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
453 : {
454 0 : fprintf(stderr, "error: exceptional domain name for \"%s\" (%d/%d) could not be extracted successfully as \"%s\" (offset: %d)\n",
455 : uri, i, p, extension_uri, info.f_offset);
456 0 : ++err_count;
457 : }
458 : /*
459 : else
460 : fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
461 : */
462 : }
463 : }
464 : else
465 : {
466 10755 : sub_has_star = 0;
467 10755 : if(tld_desc->f_status == TLD_STATUS_UNUSED
468 3125 : && tld_desc->f_start_offset != USHRT_MAX)
469 : {
470 2780 : sub_tld = tld_file_description(g_tld_file, tld_desc->f_start_offset);
471 2780 : name = tld_file_string(g_tld_file, sub_tld->f_tld, &l);
472 2780 : sub_has_star = l == 1 && name[0] == '*';
473 : }
474 10755 : if(sub_has_star)
475 : {
476 : /* this is a special case, an entry such as:
477 : *
478 : * *.blah.com
479 : *
480 : * and that means the result is going to be SUCCESS
481 : * and VALID...
482 : */
483 810 : if(r != TLD_RESULT_SUCCESS
484 810 : || info.f_status != TLD_STATUS_VALID)
485 : {
486 0 : fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d) [1]\n",
487 : uri, i, r);
488 0 : ++err_count;
489 : }
490 : }
491 9945 : else if(r != TLD_RESULT_INVALID)
492 : {
493 0 : fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d) [2]\n",
494 : uri, i, r);
495 0 : ++err_count;
496 : }
497 9945 : else if(p != i)
498 : {
499 0 : extension_uri[0] = '\0';
500 0 : cat_ext(p, extension_uri);
501 0 : if(strcmp(info.f_tld, extension_uri) != 0)
502 : {
503 0 : fprintf(stderr, "error: other domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s != %s) [1]\n",
504 : uri, i, r, info.f_tld, extension_uri);
505 0 : ++err_count;
506 : }
507 : /*
508 : else
509 : fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
510 : */
511 : }
512 : else
513 : {
514 9945 : if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
515 : {
516 0 : fprintf(stderr, "error: other domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s) [2]\n",
517 : uri, i, r, info.f_tld);
518 0 : ++err_count;
519 : }
520 : /*
521 : else
522 : fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
523 : */
524 : }
525 : }
526 : }
527 : }
528 1 : }
529 :
530 :
531 : /*
532 : * This test checks out URIs that end with an invalid TLD. This is
533 : * expected to return an error every single time.
534 : */
535 1 : void test_unknown()
536 : {
537 : struct bad_data
538 : {
539 : const char * f_uri;
540 : };
541 1 : struct bad_data d[] =
542 : {
543 : { "this.is.wrong" },
544 : { "missing.tld" },
545 : { ".net.absolutely.com.no.info.on.this" }
546 : };
547 1 : struct tld_info info;
548 : int i, max;
549 : enum tld_result r;
550 :
551 1 : max = sizeof(d) / sizeof(d[0]);
552 4 : for(i = 0; i < max; ++i)
553 : {
554 3 : memset(&info, 0xFE, sizeof(info));
555 3 : r = tld(d[i].f_uri, &info);
556 3 : if(r != TLD_RESULT_NOT_FOUND)
557 : {
558 0 : fprintf(stderr, "error: the invalid URI \"%s\" was found by tld()!\n", d[i].f_uri);
559 0 : ++err_count;
560 : }
561 : }
562 1 : }
563 :
564 :
565 :
566 :
567 1 : void test_invalid()
568 : {
569 1 : struct tld_info undefined_info;
570 1 : struct tld_info clear_info;
571 1 : struct tld_info info;
572 : enum tld_result r;
573 :
574 : /*
575 : * We reset the undefined_info the same way we reset the info
576 : * structure because the alignment on 64bits may add another
577 : * 4 bytes at the end of the structure that are not otherwise
578 : * accessible.
579 : */
580 1 : memset(&undefined_info, 0xFE, sizeof(undefined_info));
581 1 : undefined_info.f_category = TLD_CATEGORY_UNDEFINED;
582 1 : undefined_info.f_status = TLD_STATUS_UNDEFINED;
583 1 : memset(undefined_info.f_country, 0, sizeof(undefined_info.f_country));
584 1 : undefined_info.f_tld = (const char *) 0;
585 1 : undefined_info.f_offset = -1;
586 1 : undefined_info.f_tld_index = -1;
587 :
588 1 : memset(&clear_info, 0xFE, sizeof(clear_info));
589 :
590 : /* test: NULL */
591 1 : info = clear_info;
592 1 : r = tld(NULL, &info);
593 1 : if(r != TLD_RESULT_NULL)
594 : {
595 0 : fprintf(stderr, "error: the NULL URI did not return the TLD_RESULT_NULL result.\n");
596 0 : ++err_count;
597 : }
598 1 : if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
599 : {
600 0 : fprintf(stderr, "error: the NULL URI did not return a reset info structure.\n");
601 0 : ++err_count;
602 : }
603 :
604 : /* test: "" */
605 1 : info = clear_info;
606 1 : r = tld("", &info);
607 1 : if(r != TLD_RESULT_NULL)
608 : {
609 0 : fprintf(stderr, "error: the \"\" URI did not return the TLD_RESULT_NULL result.\n");
610 0 : ++err_count;
611 : }
612 1 : if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
613 : {
614 0 : fprintf(stderr, "error: the \"\" URI did not return a reset info structure.\n");
615 0 : ++err_count;
616 : }
617 :
618 : /* test: ".." (two periods one after another) */
619 1 : info = clear_info;
620 1 : r = tld("test..com", &info);
621 1 : if(r != TLD_RESULT_BAD_URI)
622 : {
623 0 : fprintf(stderr, "error: the \"test..com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
624 0 : ++err_count;
625 : }
626 1 : if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
627 : {
628 0 : fprintf(stderr, "error: the \"test..com\" URI did not return a reset info structure.\n");
629 0 : ++err_count;
630 : }
631 :
632 : /* test: ".." (two periods one after another) */
633 1 : info = clear_info;
634 1 : r = tld("more..test.com", &info);
635 1 : if(r != TLD_RESULT_BAD_URI)
636 : {
637 0 : fprintf(stderr, "error: the \"more..test.com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
638 0 : ++err_count;
639 : }
640 1 : if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
641 : {
642 0 : fprintf(stderr, "error: the \"more..test.com\" URI did not return a reset info structure.\n");
643 0 : ++err_count;
644 : }
645 :
646 : /* test: "noperiodanywhere" (no periods anywhere) */
647 1 : info = clear_info;
648 1 : r = tld("noperiodanywhere", &info);
649 1 : if(r != TLD_RESULT_NO_TLD)
650 : {
651 0 : fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return the TLD_RESULT_NO_TLD result.\n");
652 0 : ++err_count;
653 : }
654 1 : if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
655 : {
656 0 : fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return a reset info structure.\n");
657 0 : ++err_count;
658 : }
659 1 : }
660 :
661 :
662 1 : void test_tags()
663 : {
664 1 : struct tld_info info;
665 : enum tld_result result;
666 1 : const char * tld_name = "info.%e6%be%b3%e9%96%80";
667 : int tag_count;
668 1 : struct tld_tag_definition tag_info;
669 :
670 1 : result = tld(tld_name, &info);
671 1 : if(result != TLD_RESULT_SUCCESS)
672 : {
673 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return a valid info structure (error: %d).\n",
674 : result);
675 0 : ++err_count;
676 0 : return;
677 : }
678 :
679 1 : if(info.f_status != TLD_STATUS_VALID)
680 : {
681 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return a VALID status as expected.\n");
682 0 : ++err_count;
683 0 : return;
684 : }
685 :
686 1 : if(info.f_category != TLD_CATEGORY_COUNTRY)
687 : {
688 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return a country category as expected, got %d instead.\n",
689 0 : info.f_category);
690 0 : ++err_count;
691 0 : return;
692 : }
693 :
694 1 : if(strcmp(info.f_country, "Macao") != 0)
695 : {
696 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return \"Macao\" as the country name.\n");
697 0 : ++err_count;
698 0 : return;
699 : }
700 :
701 1 : if(info.f_tld != tld_name + 4)
702 : {
703 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return the expected f_tld pointer.\n");
704 0 : ++err_count;
705 0 : return;
706 : }
707 :
708 1 : if(info.f_offset != 4)
709 : {
710 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return the expected f_offset.\n");
711 0 : ++err_count;
712 0 : return;
713 : }
714 :
715 : // info.f_tld_index -- we assume this will change, there is no real point
716 : // in testing this specifically
717 :
718 1 : tag_count = tld_tag_count(&info);
719 1 : if(tag_count < 0)
720 : {
721 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI returned a negative tag_count.\n");
722 0 : ++err_count;
723 0 : return;
724 : }
725 1 : if(tag_count != 6)
726 : {
727 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI was expected to have 6 tags. Edit test if new tags were added.\n");
728 0 : ++err_count;
729 : }
730 :
731 7 : for(int idx = 0; idx < tag_count; ++idx)
732 : {
733 6 : result = tld_get_tag(&info, idx, &tag_info);
734 6 : if(result != TLD_RESULT_SUCCESS)
735 : {
736 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI returned an error retrieving tag %d.\n", idx);
737 0 : ++err_count;
738 0 : return;
739 : }
740 :
741 : // the order in which tags are saved in not guaranteed, so we must
742 : // test the name and decide what to do next
743 : //
744 6 : if(tag_info.f_name_length == 7
745 1 : && memcmp(tag_info.f_name, "country", 7) == 0)
746 : {
747 1 : if(tag_info.f_value_length != 5
748 1 : || memcmp(tag_info.f_value, "Macao", 5) != 0)
749 : {
750 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"country\" name was expected to be \"Macao\".\n");
751 0 : ++err_count;
752 0 : return;
753 : }
754 : }
755 5 : else if(tag_info.f_name_length == 17
756 1 : && memcmp(tag_info.f_name, "country_full_name", 17) == 0)
757 : {
758 1 : if(tag_info.f_value_length != 76
759 1 : || memcmp(tag_info.f_value, "Macao Special Administrative Region of the People's Republic of China (MSAR)", 76) != 0)
760 : {
761 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"country_full_name\" was expected to be \"Macao Special Administrative Region of the People's Republic of China (MSAR)\".\n");
762 0 : ++err_count;
763 0 : return;
764 : }
765 : }
766 4 : else if(tag_info.f_name_length == 11
767 1 : && memcmp(tag_info.f_name, "description", 11) == 0)
768 : {
769 1 : if(tag_info.f_value_length != 12
770 1 : || memcmp(tag_info.f_value, "Macao Island", 12) != 0)
771 : {
772 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"description\" was expected to be \"Macao Island\".\n");
773 0 : ++err_count;
774 0 : return;
775 : }
776 : }
777 3 : else if(tag_info.f_name_length == 4
778 1 : && memcmp(tag_info.f_name, "note", 4) == 0)
779 : {
780 1 : if(tag_info.f_value_length != 5
781 1 : || memcmp(tag_info.f_value, "Macao", 5) != 0)
782 : {
783 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"note\" was expected to be \"Macao\".\n");
784 0 : ++err_count;
785 0 : return;
786 : }
787 : }
788 2 : else if(tag_info.f_name_length == 8
789 2 : && memcmp(tag_info.f_name, "language", 8) == 0)
790 : {
791 1 : if(tag_info.f_value_length != 20
792 1 : || memcmp(tag_info.f_value, "Chinese, Traditional", 20) != 0)
793 : {
794 0 : fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"language\" was expected to be \"Chinese, Traditional\".\n");
795 0 : ++err_count;
796 0 : return;
797 : }
798 : }
799 : }
800 : }
801 :
802 :
803 :
804 :
805 1 : int main(int argc, char *argv[])
806 : {
807 1 : fprintf(stderr, "testing tld version %s\n", tld_version());
808 :
809 1 : if(argc > 1)
810 : {
811 0 : if(strcmp(argv[1], "-v") == 0)
812 : {
813 0 : verbose = 1;
814 : }
815 : else
816 : {
817 0 : fprintf(stderr, "error: unknown command line option \"%s\"\n", argv[1]);
818 0 : exit(1);
819 : }
820 : }
821 :
822 : /* call all the tests, one by one
823 : * failures are "recorded" in the err_count global variable
824 : * and the process stops with an error message and exit(1)
825 : * if err_count is not zero.
826 : */
827 1 : load_tlds();
828 1 : test_specific();
829 1 : test_all();
830 1 : test_unknown();
831 1 : test_invalid();
832 1 : test_tags();
833 1 : free_tlds();
834 :
835 1 : if(err_count)
836 : {
837 0 : fprintf(stderr, "%d error%s occured.\n",
838 0 : err_count, err_count != 1 ? "s" : "");
839 : }
840 1 : exit(err_count ? 1 : 0);
841 : }
842 :
843 : /* vim: ts=4 sw=4 et
844 : */
|