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