LCOV - code coverage report
Current view: top level - tests - tld_test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 173 282 61.3 %
Date: 2022-02-19 13:28:04 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          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             :  */

Generated by: LCOV version 1.13