LCOV - code coverage report
Current view: top level - tests - tld_test.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.0 % 300 183
Test Date: 2026-11-11 12:24:48 Functions: 100.0 % 9 9
Legend: Lines: hit not hit

            Line data    Source code
       1              : /* TLD library -- test the TLD interface
       2              :  * Copyright (c) 2011-2025  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              :         "a-really-long-name-is-not-considered-valid-when-more-than-63-chars.com",
     265              :         TLD_RESULT_BAD_URI,
     266              :         -1,
     267              :     },
     268              :     {
     269              :         "very.many.sub-domain.names.can.make.the.uri.more.than.the.allowed.253.characterss.because.the.dns.limit.is.255.bytes.total.but.that.includes.an.extra.size.and.the.null.terminator.so.we.cannot.have.that.many.names.after.all.although.frankly.this.is.huge.com",
     270              :         TLD_RESULT_BAD_URI,
     271              :         -1,
     272              :     },
     273              : };
     274              : 
     275              : 
     276              : /*
     277              :  * This tests various ad hoc domains with expected results.
     278              :  *
     279              :  * This way we can verify specific things we want to check.
     280              :  */
     281            1 : void test_specific()
     282              : {
     283           16 :     for(size_t idx = 0; idx < sizeof(g_uris) / sizeof(g_uris[0]); ++idx)
     284              :     {
     285           15 :         struct tld_info info;
     286           15 :         enum tld_result r = tld(g_uris[idx].f_uri, &info);
     287           15 :         if(verbose)
     288              :         {
     289            0 :             fprintf(
     290              :                   stderr
     291              :                 , "info: URI \"%s\" returned %d and TLD is \"%s\"\n"
     292            0 :                 , g_uris[idx].f_uri
     293              :                 , r
     294            0 :                 , g_uris[idx].f_uri + info.f_offset);
     295              :         }
     296              : 
     297           15 :         if(r != g_uris[idx].f_result)
     298              :         {
     299            0 :             fprintf(stderr, "error: testing URI \"%s\" got result %d, expected %d and TLD of \"%s\"\n",
     300            0 :                         g_uris[idx].f_uri, r, g_uris[idx].f_result,
     301            0 :                         g_uris[idx].f_uri + g_uris[idx].f_offset);
     302            0 :             ++err_count;
     303              :         }
     304           15 :         else if(info.f_offset != g_uris[idx].f_offset)
     305              :         {
     306            0 :             fprintf(stderr, "error: testing URI \"%s\" got offset %d, expected %d and TLD of \"%s\"\n",
     307            0 :                         g_uris[idx].f_uri, info.f_offset, g_uris[idx].f_offset,
     308            0 :                         g_uris[idx].f_uri + info.f_offset);
     309            0 :             ++err_count;
     310              :         }
     311              :     }
     312            1 : }
     313              : 
     314              : 
     315              : /*
     316              :  * This test goes through all the domain names and extracts the domain,
     317              :  * sub-domains and TLDs. (Or at least verifies that we get the correct
     318              :  * information in order to do so.)
     319              :  *
     320              :  * It builds a URI with zero to many sub-domain names, adds a specific
     321              :  * domain name, then append a complete TLD. The result is then checked
     322              :  * with the tld() function from the library. The tld() is expected to
     323              :  * either return VALID or INVALID but nothing else (since all those
     324              :  * TLDs exist in our table.) Then we verify that the returned offset is
     325              :  * a perfect match.
     326              :  */
     327            1 : void test_all()
     328              : {
     329            1 :     char const * sub_domains[] = {
     330              :         "",
     331              :         "www.",
     332              :         "tld.",
     333              :         "george.snap.",
     334              :         "very.long.sub.domain.ext.en.sion.here."
     335              :         "host.%20.space."
     336              :         "host.%fa.u-acute."
     337              :         "host.%FA.U-acute."
     338              :     };
     339            1 :     struct tld_info                 info;
     340            1 :     char                            uri[256], extension_uri[256];
     341              :     char const *                    name;
     342            1 :     uint32_t                        i, j, l, p, max_subdomains;
     343              :     int                             has_star, sub_has_star;
     344              :     enum tld_result                 r;
     345              :     struct tld_description const  * tld_desc;
     346              :     struct tld_description const  * sub_tld;
     347              : 
     348            1 :     max_subdomains = sizeof(sub_domains) / sizeof(sub_domains[0]);
     349              : 
     350        11966 :     for(i = 0; i < g_tld_file->f_descriptions_count; ++i)
     351              :     {
     352        71790 :         for(j = 0; j < max_subdomains; ++j)
     353              :         {
     354        59825 :             strcpy(uri, sub_domains[j]);
     355        59825 :             strcat(uri, "domain-name");
     356        59825 :             has_star = cat_ext(i, uri);
     357              : 
     358              :             /* just in case make sure that we did not overflow the buffer */
     359        59825 :             if(strlen(uri) >= sizeof(uri))
     360              :             {
     361            0 :                 fprintf(stderr, "fatal error: the URI \"%s\" is longer than the uri[] array.\n", uri);
     362            0 :                 exit(1);
     363              :             }
     364              : 
     365              :             /* reset the structure so we can verify it gets initialized */
     366        59825 :             memset(&info, 0xFE, sizeof(info));
     367              : 
     368        59825 :             r = tld(uri, &info);
     369              : #if 0
     370              :             if(i == 5108)
     371              :             {
     372              :                 for(size_t l = 0; l < sizeof(info); ++l)
     373              :                 {
     374              :                     if((l % 16) == 0 && l > 0)
     375              :                     {
     376              :                         fprintf(stderr, "\n");
     377              :                     }
     378              :                     fprintf(stderr, "0x%02X ", ((unsigned char*)&info)[l]);
     379              :                 }
     380              :                 fprintf(stderr, "\nresult for [%s]: category[%d], status[%d/%%d n.a.], country[%s],"
     381              :                                     " tld[%s], offset[%d]\n",
     382              :                         uri,
     383              :                         (int)info.f_category,
     384              :                         (int)info.f_status, //(int)tld_descriptions[i].f_status,
     385              :                         info.f_country,
     386              :                             info.f_tld, (int)info.f_offset);
     387              :             }
     388              : #endif
     389        59825 :             p = i;
     390        59825 :             tld_desc = tld_file_description(g_tld_file, i);
     391        59825 :             if(tld_desc->f_status == TLD_STATUS_EXCEPTION)
     392              :             {
     393           95 :                 if(tld_desc->f_exception_apply_to == USHRT_MAX)
     394              :                 {
     395            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",
     396              :                             uri, i, r);
     397            0 :                     ++err_count;
     398              :                 }
     399              :                 else
     400              :                 {
     401           95 :                     p = tld_desc->f_exception_apply_to;
     402              :                 }
     403              :             }
     404        59825 :             if(tld_desc->f_status == TLD_STATUS_VALID)
     405              :             {
     406        48975 :                 if(r != TLD_RESULT_SUCCESS)
     407              :                 {
     408            0 :                     fprintf(stderr, "error: valid domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     409              :                             uri, i, r);
     410            0 :                     ++err_count;
     411              :                 }
     412        48975 :                 else if(has_star)
     413              :                 {
     414              :                     /* the "domain-name" is absorbed as part of the TLD */
     415          810 :                     int expected = strlen(sub_domains[j]);
     416          810 :                     if(expected != 0)
     417              :                     {
     418          648 :                         --expected;     /* ignore the "." */
     419              :                     }
     420          810 :                     if(info.f_offset != expected)
     421              :                     {
     422            0 :                         fprintf(stderr, "error: valid domain name for \"%s\" (%d) could not be extracted successfully (offset: %d, expected: %d)\n",
     423              :                                 uri, i,
     424              :                                 info.f_offset, expected);
     425            0 :                         ++err_count;
     426              :                     }
     427              :                 }
     428              :                 else
     429              :                 {
     430              :                     /* verify the top domain name */
     431        48165 :                     if(info.f_offset < 11)
     432              :                     {
     433            0 :                         fprintf(stderr, "error: somehow the top domain name in \"%s\" (%d) cannot properly be extracted\n",
     434              :                                 uri, i);
     435            0 :                         ++err_count;
     436              :                     }
     437        48165 :                     else if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     438              :                     {
     439            0 :                         fprintf(stderr, "error: valid domain name for \"%s\" (%d) could not be extracted successfully (offset: %d)\n",
     440              :                                 uri, i, info.f_offset);
     441            0 :                         ++err_count;
     442              :                     }
     443              :                     /*
     444              :                     else
     445              :                         fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
     446              :                     */
     447              :                 }
     448              :             }
     449        10850 :             else if(tld_desc->f_status == TLD_STATUS_EXCEPTION)
     450              :             {
     451           95 :                 if(r != TLD_RESULT_SUCCESS)
     452              :                 {
     453            0 :                     fprintf(stderr, "error: exceptional domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     454              :                             uri, i, r);
     455            0 :                     ++err_count;
     456              :                 }
     457              :                 else
     458              :                 {
     459           95 :                     extension_uri[0] = '\0';
     460           95 :                     cat_ext(p, extension_uri);
     461           95 :                     if(strcmp(info.f_tld, extension_uri) != 0)
     462              :                     //if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     463              :                     {
     464            0 :                         fprintf(stderr, "error: exceptional domain name for \"%s\" (%d/%d) could not be extracted successfully as \"%s\" (offset: %d)\n",
     465              :                                 uri, i, p, extension_uri, info.f_offset);
     466            0 :                         ++err_count;
     467              :                     }
     468              :                     /*
     469              :                     else
     470              :                         fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
     471              :                     */
     472              :                 }
     473              :             }
     474              :             else
     475              :             {
     476        10755 :                 sub_has_star = 0;
     477        10755 :                 if(tld_desc->f_status == TLD_STATUS_UNUSED
     478         3125 :                 && tld_desc->f_start_offset != USHRT_MAX)
     479              :                 {
     480         2780 :                     sub_tld = tld_file_description(g_tld_file, tld_desc->f_start_offset);
     481         2780 :                     name = tld_file_string(g_tld_file, sub_tld->f_tld, &l);
     482         2780 :                     sub_has_star = l == 1 && name[0] == '*';
     483              :                 }
     484        10755 :                 if(sub_has_star)
     485              :                 {
     486              :                     /* this is a special case, an entry such as:
     487              :                      *
     488              :                      *     *.blah.com
     489              :                      *
     490              :                      * and that means the result is going to be SUCCESS
     491              :                      * and VALID...
     492              :                      */
     493          810 :                     if(r != TLD_RESULT_SUCCESS
     494          810 :                     || info.f_status != TLD_STATUS_VALID)
     495              :                     {
     496            0 :                         fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d) [1]\n",
     497              :                                 uri, i, r);
     498            0 :                         ++err_count;
     499              :                     }
     500              :                 }
     501         9945 :                 else if(r != TLD_RESULT_INVALID)
     502              :                 {
     503            0 :                     fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d) [2]\n",
     504              :                             uri, i, r);
     505            0 :                     ++err_count;
     506              :                 }
     507         9945 :                 else if(p != i)
     508              :                 {
     509            0 :                     extension_uri[0] = '\0';
     510            0 :                     cat_ext(p, extension_uri);
     511            0 :                     if(strcmp(info.f_tld, extension_uri) != 0)
     512              :                     {
     513            0 :                         fprintf(stderr, "error: other domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s != %s) [1]\n",
     514              :                                 uri, i, r, info.f_tld, extension_uri);
     515            0 :                         ++err_count;
     516              :                     }
     517              :                     /*
     518              :                     else
     519              :                         fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 
     520              :                     */
     521              :                 }
     522              :                 else
     523              :                 {
     524         9945 :                     if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     525              :                     {
     526            0 :                         fprintf(stderr, "error: other domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s) [2]\n",
     527              :                                 uri, i, r, info.f_tld);
     528            0 :                         ++err_count;
     529              :                     }
     530              :                     /*
     531              :                     else
     532              :                         fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 
     533              :                     */
     534              :                 }
     535              :             }
     536              :         }
     537              :     }
     538            1 : }
     539              : 
     540              : 
     541              : /*
     542              :  * This test checks out URIs that end with an invalid TLD. This is
     543              :  * expected to return an error every single time.
     544              :  */
     545            1 : void test_unknown()
     546              : {
     547              :     struct bad_data
     548              :     {
     549              :         const char *        f_uri;
     550              :     };
     551            1 :     struct bad_data d[] =
     552              :     {
     553              :         { "this.is.wrong" },
     554              :         { "missing.tld" },
     555              :         { ".net.absolutely.com.no.info.on.this" }
     556              :     };
     557            1 :     struct tld_info info;
     558              :     int i, max;
     559              :     enum tld_result r;
     560              : 
     561            1 :     max = sizeof(d) / sizeof(d[0]);
     562            4 :     for(i = 0; i < max; ++i)
     563              :     {
     564            3 :         memset(&info, 0xFE, sizeof(info));
     565            3 :         r = tld(d[i].f_uri, &info);
     566            3 :         if(r != TLD_RESULT_NOT_FOUND)
     567              :         {
     568            0 :             fprintf(stderr, "error: the invalid URI \"%s\" was found by tld()!\n", d[i].f_uri);
     569            0 :             ++err_count;
     570              :         }
     571              :     }
     572            1 : }
     573              : 
     574              : 
     575              : 
     576              : 
     577            1 : void test_invalid()
     578              : {
     579            1 :     struct tld_info undefined_info;
     580            1 :     struct tld_info clear_info;
     581            1 :     struct tld_info info;
     582              :     enum tld_result r;
     583              : 
     584              :     /*
     585              :      * We reset the undefined_info the same way we reset the info
     586              :      * structure because the alignment on 64bits may add another
     587              :      * 4 bytes at the end of the structure that are not otherwise
     588              :      * accessible.
     589              :      */
     590            1 :     memset(&undefined_info, 0xFE, sizeof(undefined_info));
     591            1 :     undefined_info.f_category  = TLD_CATEGORY_UNDEFINED;
     592            1 :     undefined_info.f_status    = TLD_STATUS_UNDEFINED;
     593            1 :     memset(undefined_info.f_country, 0, sizeof(undefined_info.f_country));
     594            1 :     undefined_info.f_tld       = (const char *) 0;
     595            1 :     undefined_info.f_offset    = -1;
     596            1 :     undefined_info.f_tld_index = -1;
     597              : 
     598            1 :     memset(&clear_info, 0xFE, sizeof(clear_info));
     599              : 
     600              :     /* test: NULL */
     601            1 :     info = clear_info;
     602            1 :     r = tld(NULL, &info);
     603            1 :     if(r != TLD_RESULT_NULL)
     604              :     {
     605            0 :         fprintf(stderr, "error: the NULL URI did not return the TLD_RESULT_NULL result.\n");
     606            0 :         ++err_count;
     607              :     }
     608            1 :     if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     609              :     {
     610            0 :         fprintf(stderr, "error: the NULL URI did not return a reset info structure.\n");
     611            0 :         ++err_count;
     612              :     }
     613              : 
     614              :     /* test: "" */
     615            1 :     info = clear_info;
     616            1 :     r = tld("", &info);
     617            1 :     if(r != TLD_RESULT_NULL)
     618              :     {
     619            0 :         fprintf(stderr, "error: the \"\" URI did not return the TLD_RESULT_NULL result.\n");
     620            0 :         ++err_count;
     621              :     }
     622            1 :     if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     623              :     {
     624            0 :         fprintf(stderr, "error: the \"\" URI did not return a reset info structure.\n");
     625            0 :         ++err_count;
     626              :     }
     627              : 
     628              :     /* test: ".." (two periods one after another) */
     629            1 :     info = clear_info;
     630            1 :     r = tld("test..com", &info);
     631            1 :     if(r != TLD_RESULT_BAD_URI)
     632              :     {
     633            0 :         fprintf(stderr, "error: the \"test..com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
     634            0 :         ++err_count;
     635              :     }
     636            1 :     if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     637              :     {
     638            0 :         fprintf(stderr, "error: the \"test..com\" URI did not return a reset info structure.\n");
     639            0 :         ++err_count;
     640              :     }
     641              : 
     642              :     /* test: ".." (two periods one after another) */
     643            1 :     info = clear_info;
     644            1 :     r = tld("more..test.com", &info);
     645            1 :     if(r != TLD_RESULT_BAD_URI)
     646              :     {
     647            0 :         fprintf(stderr, "error: the \"more..test.com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
     648            0 :         ++err_count;
     649              :     }
     650            1 :     if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     651              :     {
     652            0 :         fprintf(stderr, "error: the \"more..test.com\" URI did not return a reset info structure.\n");
     653            0 :         ++err_count;
     654              :     }
     655              : 
     656              :     /* test: "noperiodanywhere" (no periods anywhere) */
     657            1 :     info = clear_info;
     658            1 :     r = tld("noperiodanywhere", &info);
     659            1 :     if(r != TLD_RESULT_NO_TLD)
     660              :     {
     661            0 :         fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return the TLD_RESULT_NO_TLD result.\n");
     662            0 :         ++err_count;
     663              :     }
     664            1 :     if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     665              :     {
     666            0 :         fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return a reset info structure.\n");
     667            0 :         ++err_count;
     668              :     }
     669            1 : }
     670              : 
     671              : 
     672            1 : void test_tags()
     673              : {
     674            1 :     struct tld_info info;
     675              :     enum tld_result result;
     676            1 :     const char * tld_name = "info.%e6%be%b3%e9%96%80";
     677              :     int tag_count;
     678            1 :     struct tld_tag_definition tag_info;
     679              : 
     680            1 :     result = tld(tld_name, &info);
     681            1 :     if(result != TLD_RESULT_SUCCESS)
     682              :     {
     683            0 :         fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return a valid info structure (error: %d).\n",
     684              :                 result);
     685            0 :         ++err_count;
     686            0 :         return;
     687              :     }
     688              : 
     689            1 :     if(info.f_status != TLD_STATUS_VALID)
     690              :     {
     691            0 :         fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return a VALID status as expected.\n");
     692            0 :         ++err_count;
     693            0 :         return;
     694              :     }
     695              : 
     696            1 :     if(info.f_category != TLD_CATEGORY_COUNTRY)
     697              :     {
     698            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",
     699            0 :                         info.f_category);
     700            0 :         ++err_count;
     701            0 :         return;
     702              :     }
     703              : 
     704            1 :     if(strcmp(info.f_country, "Macao") != 0)
     705              :     {
     706            0 :         fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return \"Macao\" as the country name.\n");
     707            0 :         ++err_count;
     708            0 :         return;
     709              :     }
     710              : 
     711            1 :     if(info.f_tld != tld_name + 4)
     712              :     {
     713            0 :         fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return the expected f_tld pointer.\n");
     714            0 :         ++err_count;
     715            0 :         return;
     716              :     }
     717              : 
     718            1 :     if(info.f_offset != 4)
     719              :     {
     720            0 :         fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI did not return the expected f_offset.\n");
     721            0 :         ++err_count;
     722            0 :         return;
     723              :     }
     724              : 
     725              :     // info.f_tld_index -- we assume this will change, there is no real point
     726              :     //                     in testing this specifically
     727              : 
     728            1 :     tag_count = tld_tag_count(&info);
     729            1 :     if(tag_count < 0)
     730              :     {
     731            0 :         fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI returned a negative tag_count.\n");
     732            0 :         ++err_count;
     733            0 :         return;
     734              :     }
     735            1 :     if(tag_count != 6)
     736              :     {
     737            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");
     738            0 :         ++err_count;
     739              :     }
     740              : 
     741            7 :     for(int idx = 0; idx < tag_count; ++idx)
     742              :     {
     743            6 :         result = tld_get_tag(&info, idx, &tag_info);
     744            6 :         if(result != TLD_RESULT_SUCCESS)
     745              :         {
     746            0 :             fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI returned an error retrieving tag %d.\n", idx);
     747            0 :             ++err_count;
     748            0 :             return;
     749              :         }
     750              : 
     751              :         // the order in which tags are saved in not guaranteed, so we must
     752              :         // test the name and decide what to do next
     753              :         //
     754            6 :         if(tag_info.f_name_length == 7
     755            1 :         && memcmp(tag_info.f_name, "country", 7) == 0)
     756              :         {
     757            1 :             if(tag_info.f_value_length != 5
     758            1 :             || memcmp(tag_info.f_value, "Macao", 5) != 0)
     759              :             {
     760            0 :                 fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"country\" name was expected to be \"Macao\".\n");
     761            0 :                 ++err_count;
     762            0 :                 return;
     763              :             }
     764              :         }
     765            5 :         else if(tag_info.f_name_length == 17
     766            1 :              && memcmp(tag_info.f_name, "country_full_name", 17) == 0)
     767              :         {
     768            1 :             if(tag_info.f_value_length != 76
     769            1 :             || memcmp(tag_info.f_value, "Macao Special Administrative Region of the People's Republic of China (MSAR)", 76) != 0)
     770              :             {
     771            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");
     772            0 :                 ++err_count;
     773            0 :                 return;
     774              :             }
     775              :         }
     776            4 :         else if(tag_info.f_name_length == 11
     777            1 :              && memcmp(tag_info.f_name, "description", 11) == 0)
     778              :         {
     779            1 :             if(tag_info.f_value_length != 12
     780            1 :             || memcmp(tag_info.f_value, "Macao Island", 12) != 0)
     781              :             {
     782            0 :                 fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"description\" was expected to be \"Macao Island\".\n");
     783            0 :                 ++err_count;
     784            0 :                 return;
     785              :             }
     786              :         }
     787            3 :         else if(tag_info.f_name_length == 4
     788            1 :              && memcmp(tag_info.f_name, "note", 4) == 0)
     789              :         {
     790            1 :             if(tag_info.f_value_length != 5
     791            1 :             || memcmp(tag_info.f_value, "Macao", 5) != 0)
     792              :             {
     793            0 :                 fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"note\" was expected to be \"Macao\".\n");
     794            0 :                 ++err_count;
     795            0 :                 return;
     796              :             }
     797              :         }
     798            2 :         else if(tag_info.f_name_length == 8
     799            2 :              && memcmp(tag_info.f_name, "language", 8) == 0)
     800              :         {
     801            1 :             if(tag_info.f_value_length != 20
     802            1 :             || memcmp(tag_info.f_value, "Chinese, Traditional", 20) != 0)
     803              :             {
     804            0 :                 fprintf(stderr, "error: the \"info.\xE6\xBE\xB3\xE9\x96\x80\" URI \"language\" was expected to be \"Chinese, Traditional\".\n");
     805            0 :                 ++err_count;
     806            0 :                 return;
     807              :             }
     808              :         }
     809              :     }
     810              : }
     811              : 
     812              : 
     813              : 
     814              : 
     815            1 : int main(int argc, char *argv[])
     816              : {
     817            1 :     fprintf(stderr, "testing tld version %s\n", tld_version());
     818              : 
     819            1 :     if(argc > 1)
     820              :     {
     821            0 :         if(strcmp(argv[1], "-v") == 0)
     822              :         {
     823            0 :             verbose = 1;
     824              :         }
     825              :         else
     826              :         {
     827            0 :             fprintf(stderr, "error: unknown command line option \"%s\"\n", argv[1]);
     828            0 :             exit(1);
     829              :         }
     830              :     }
     831              : 
     832              :     /* call all the tests, one by one
     833              :      * failures are "recorded" in the err_count global variable
     834              :      * and the process stops with an error message and exit(1)
     835              :      * if err_count is not zero.
     836              :      */
     837            1 :     load_tlds();
     838            1 :     test_specific();
     839            1 :     test_all();
     840            1 :     test_unknown();
     841            1 :     test_invalid();
     842            1 :     test_tags();
     843            1 :     free_tlds();
     844              : 
     845            1 :     if(err_count)
     846              :     {
     847            0 :         fprintf(stderr, "%d error%s occured.\n",
     848            0 :                     err_count, err_count != 1 ? "s" : "");
     849              :     }
     850            1 :     exit(err_count ? 1 : 0);
     851              : }
     852              : 
     853              : /* vim: ts=4 sw=4 et
     854              :  */
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions