LCOV - code coverage report
Current view: top level - tests - tld_test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 87 134 64.9 %
Date: 2018-08-28 01:54:14 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* TLD library -- test the TLD interface
       2             :  * Copyright (c) 2011-2018  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             : #include "libtld/tld.h"
      33             : #include <string.h>
      34             : #include <stdlib.h>
      35             : #include <stdio.h>
      36             : #include <limits.h>
      37             : 
      38             : /* we get access to the table with all the TLDs so we can go through them all
      39             :  * the library does not give direct access by default... (although maybe we
      40             :  * could give users access to the data)
      41             :  */
      42             : #include "tld_data.h"
      43             : extern const struct tld_description tld_descriptions[];
      44             : extern unsigned short tld_start_offset;
      45             : extern unsigned short tld_end_offset;
      46             : 
      47             : int err_count = 0;
      48             : int verbose = 0;
      49             : 
      50             : /*
      51             :  * This test calls the tld() function with all the TLDs and then
      52             :  * with wrong TLDs to make sure that the tld() functions works as
      53             :  * expected.
      54             :  *
      55             :  * extern enum tld_result tld(const char *uri, struct tld_info *info);
      56             :  */
      57             : 
      58             : 
      59             : /** \brief Build an extension from any offset.
      60             :  *
      61             :  * Create a domain name extensions from any entry in the TLD
      62             :  * descriptions.
      63             :  *
      64             :  * \param[in] offset  The offset in the tld_descriptions table
      65             :  * \param[in] uri  The URI buffer
      66             :  */
      67       48760 : void cat_ext(int offset, char *uri)
      68             : {
      69             :         int     k, l;
      70             : 
      71       48760 :         strcat(uri, tld_descriptions[offset].f_tld);
      72       48760 :         l = offset;
      73   435723940 :         for(k = offset + 1; k < tld_end_offset; ++k)
      74             :         {
      75   435675180 :                 if(l >= tld_descriptions[k].f_start_offset
      76    33592090 :                 && l < tld_descriptions[k].f_end_offset)
      77             :                 {
      78             :                         /* found a parent */
      79       56290 :                         strcat(uri, ".");
      80       56290 :                         strcat(uri, tld_descriptions[k].f_tld);
      81       56290 :                         l = k;
      82       56290 :                         k = tld_descriptions[k].f_end_offset;
      83             :                 }
      84             :         }
      85       48760 : }
      86             : 
      87             : /*
      88             :  * This test goes through all the domain names and extracts the domain,
      89             :  * sub-domains and TLDs. (Or at least verifies that we get the correct
      90             :  * information in order to do so.)
      91             :  *
      92             :  * It builds a URI with zero to many sub-domain names, adds a specific
      93             :  * domain name, then append a complete TLD. The result is then checked
      94             :  * with the tld() function from the library. The tld() is expected to
      95             :  * either return VALID or INVALID but nothing else (since all those
      96             :  * TLDs exist in our table.) Then we verify that the returned offset is
      97             :  * a perfect match.
      98             :  */
      99           1 : void test_all()
     100             : {
     101           1 :         const char *sub_domains[] = {
     102             :                 "",
     103             :                 "www.",
     104             :                 "tld.",
     105             :                 "george.snap.",
     106             :                 "very.long.sub.domain.ext.en.sion.here."
     107             :                 "host.%20.space."
     108             :                 "host.%fa.u-acute."
     109             :                 "host.%FA.U-acute."
     110             :         };
     111             :         struct tld_info info;
     112             :         char                    uri[256], extension_uri[256];
     113             :         int                             i, j, p, max_subdomains;
     114             :         enum tld_result r;
     115             : 
     116           1 :         max_subdomains = sizeof(sub_domains) / sizeof(sub_domains[0]);
     117             : 
     118        9732 :         for(i = 0; i < tld_end_offset; ++i)
     119             :         {
     120       58386 :                 for(j = 0; j < max_subdomains; ++j)
     121             :                 {
     122       48655 :                         strcpy(uri, sub_domains[j]);
     123       48655 :                         strcat(uri, "domain-name.");
     124       48655 :                         cat_ext(i, uri);
     125             :                         /* reset the structure so we can verify it gets initialized */
     126       48655 :                         memset(&info, 0xFE, sizeof(info));
     127       48655 :                         r = tld(uri, &info);
     128             :                         /*
     129             :                         for(size_t l = 0; l < sizeof(info); ++l)
     130             :                         {
     131             :                                 fprintf(stderr, "0x%02X ", ((unsigned char*)&info)[l]);
     132             :                         }
     133             :                         fprintf(stderr, "\nresult for [%s]: category[%d], status[%d/%d], country[%s],"
     134             :                                                                 " tld[%s], offset[%d]\n",
     135             :                                         uri,
     136             :                                         (int)info.f_category,
     137             :                                         (int)info.f_status, (int)tld_descriptions[i].f_status,
     138             :                                         info.f_country,
     139             :                                                 info.f_tld, (int)info.f_offset);
     140             :                         */
     141       48655 :                         p = i;
     142       48655 :                         if(tld_descriptions[i].f_status == TLD_STATUS_EXCEPTION)
     143             :                         {
     144         105 :                                 if(tld_descriptions[i].f_exception_apply_to == USHRT_MAX)
     145             :                                 {
     146           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",
     147             :                                                         uri, i, r);
     148           0 :                                         ++err_count;
     149             :                                 }
     150             :                                 else
     151             :                                 {
     152         105 :                                         p = tld_descriptions[i].f_exception_apply_to;
     153             :                                 }
     154             :                         }
     155       48655 :                         if(tld_descriptions[i].f_status == TLD_STATUS_VALID)
     156             :                         {
     157       46830 :                                 if(r != TLD_RESULT_SUCCESS)
     158             :                                 {
     159           0 :                                         fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     160             :                                                         uri, i, r);
     161           0 :                                         ++err_count;
     162             :                                 }
     163             :                                 else
     164             :                                 {
     165             :                                         /* in this case we have to test the top domain name only */
     166       46830 :                                         if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     167             :                                         {
     168           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     169             :                                                                 uri, i, r);
     170           0 :                                                 ++err_count;
     171             :                                         }
     172             :                                         /*
     173             :                                         else
     174             :                                                 fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
     175             :                                         */
     176             :                                 }
     177             :                         }
     178        1825 :                         else if(tld_descriptions[i].f_status == TLD_STATUS_EXCEPTION)
     179             :                         {
     180         105 :                                 if(r != TLD_RESULT_SUCCESS)
     181             :                                 {
     182           0 :                                         fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     183             :                                                         uri, i, r);
     184           0 :                                         ++err_count;
     185             :                                 }
     186             :                                 else
     187             :                                 {
     188         105 :                                         strcpy(extension_uri, ".");
     189         105 :                                         cat_ext(p, extension_uri);
     190         105 :                                         if(strcmp(info.f_tld, extension_uri) != 0)
     191             :                                         //if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     192             :                                         {
     193           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     194             :                                                                 uri, i, r);
     195           0 :                                                 ++err_count;
     196             :                                         }
     197             :                                         /*
     198             :                                         else
     199             :                                                 fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
     200             :                                         */
     201             :                                 }
     202             :                         }
     203             :                         else
     204             :                         {
     205        1720 :                                 if(tld_descriptions[i].f_status == TLD_STATUS_UNUSED
     206         985 :                                 && tld_descriptions[i].f_start_offset != USHRT_MAX
     207         680 :                                 && strcmp(tld_descriptions[tld_descriptions[i].f_start_offset].f_tld, "*") == 0)
     208             :                                 {
     209             :                                         /* this is somewhat of a special case, at this point
     210             :                                          * we have entries such as:
     211             :                                          *
     212             :                                          *     *.blah.com
     213             :                                          *
     214             :                                          * and that means the result is going to be SUCCESS
     215             :                                          * instead of INVALID...
     216             :                                          */
     217         310 :                                         if(r != TLD_RESULT_INVALID
     218         155 :                                         || info.f_status != TLD_STATUS_UNUSED)
     219             :                                         {
     220           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d) [1]\n",
     221             :                                                                 uri, i, r);
     222           0 :                                                 ++err_count;
     223             :                                         }
     224             :                                 }
     225        1565 :                                 else if(r != TLD_RESULT_INVALID)
     226             :                                 {
     227           0 :                                         fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d) [2]\n",
     228             :                                                         uri, i, r);
     229           0 :                                         ++err_count;
     230             :                                 }
     231        1565 :                                 else if(p != i)
     232             :                                 {
     233           0 :                                         strcpy(extension_uri, ".");
     234           0 :                                         cat_ext(p, extension_uri);
     235           0 :                                         if(strcmp(info.f_tld, extension_uri) != 0)
     236             :                                         {
     237           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s) [1]\n",
     238             :                                                                 uri, i, r, info.f_tld);
     239           0 :                                                 ++err_count;
     240             :                                         }
     241             :                                         /*
     242             :                                         else
     243             :                                                 fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 
     244             :                                         */
     245             :                                 }
     246             :                                 else
     247             :                                 {
     248        1565 :                                         if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     249             :                                         {
     250           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s) [2]\n",
     251             :                                                                 uri, i, r, info.f_tld);
     252           0 :                                                 ++err_count;
     253             :                                         }
     254             :                                         /*
     255             :                                         else
     256             :                                                 fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 
     257             :                                         */
     258             :                                 }
     259             :                         }
     260             :                 }
     261             :         }
     262           1 : }
     263             : 
     264             : 
     265             : /*
     266             :  * This test checks out URIs that end with an invalid TLD. This is
     267             :  * expected to return an error every single time.
     268             :  */
     269           1 : void test_unknown()
     270             : {
     271             :         struct bad_data
     272             :         {
     273             :                 const char *            f_uri;
     274             :         };
     275           1 :         struct bad_data d[] =
     276             :         {
     277             :                 { "this.is.wrong" },
     278             :                 { "missing.tld" },
     279             :                 { ".net.absolutely.com.no.info.on.this" }
     280             :         };
     281             :         struct tld_info info;
     282             :         int i, max;
     283             :         enum tld_result r;
     284             : 
     285           1 :         max = sizeof(d) / sizeof(d[0]);
     286           4 :         for(i = 0; i < max; ++i)
     287             :         {
     288           3 :                 memset(&info, 0xFE, sizeof(info));
     289           3 :                 r = tld(d[i].f_uri, &info);
     290           3 :                 if(r != TLD_RESULT_NOT_FOUND)
     291             :                 {
     292           0 :                         fprintf(stderr, "error: the invalid URI \"%s\" was found by tld()!\n", d[i].f_uri);
     293           0 :                         ++err_count;
     294             :                 }
     295             :         }
     296           1 : }
     297             : 
     298             : 
     299             : 
     300             : 
     301           1 : void test_invalid()
     302             : {
     303             :         struct tld_info undefined_info;
     304             :         struct tld_info clear_info;
     305             :         struct tld_info info;
     306             :         enum tld_result r;
     307             : 
     308             :         /*
     309             :          * We reset the undefined_info the same way we reset the info
     310             :          * structure because the alignment on 64bits may add another
     311             :          * 4 bytes at the end of the structure that are not otherwise
     312             :          * accessible.
     313             :          */
     314           1 :         memset(&undefined_info, 0xFE, sizeof(undefined_info));
     315           1 :         undefined_info.f_category = TLD_CATEGORY_UNDEFINED;
     316           1 :         undefined_info.f_status   = TLD_STATUS_UNDEFINED;
     317           1 :         undefined_info.f_country  = (const char *) 0;
     318           1 :         undefined_info.f_tld      = (const char *) 0;
     319           1 :         undefined_info.f_offset   = -1;
     320             : 
     321           1 :         memset(&clear_info, 0xFE, sizeof(clear_info));
     322             : 
     323             :         /* test: NULL */
     324           1 :         info = clear_info;
     325           1 :         r = tld(NULL, &info);
     326           1 :         if(r != TLD_RESULT_NULL)
     327             :         {
     328           0 :                 fprintf(stderr, "error: the NULL URI did not return the TLD_RESULT_NULL result.\n");
     329           0 :                 ++err_count;
     330             :         }
     331           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     332             :         {
     333           0 :                 fprintf(stderr, "error: the NULL URI did not return a reset info structure.\n");
     334           0 :                 ++err_count;
     335             :         }
     336             : 
     337             :         /* test: "" */
     338           1 :         info = clear_info;
     339           1 :         r = tld("", &info);
     340           1 :         if(r != TLD_RESULT_NULL)
     341             :         {
     342           0 :                 fprintf(stderr, "error: the \"\" URI did not return the TLD_RESULT_NULL result.\n");
     343           0 :                 ++err_count;
     344             :         }
     345           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     346             :         {
     347           0 :                 fprintf(stderr, "error: the \"\" URI did not return a reset info structure.\n");
     348           0 :                 ++err_count;
     349             :         }
     350             : 
     351             :         /* test: ".." (two periods one after another) */
     352           1 :         info = clear_info;
     353           1 :         r = tld("test..com", &info);
     354           1 :         if(r != TLD_RESULT_BAD_URI)
     355             :         {
     356           0 :                 fprintf(stderr, "error: the \"test..com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
     357           0 :                 ++err_count;
     358             :         }
     359           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     360             :         {
     361           0 :                 fprintf(stderr, "error: the \"test..com\" URI did not return a reset info structure.\n");
     362           0 :                 ++err_count;
     363             :         }
     364             : 
     365             :         /* test: ".." (two periods one after another) */
     366           1 :         info = clear_info;
     367           1 :         r = tld("more..test.com", &info);
     368           1 :         if(r != TLD_RESULT_BAD_URI)
     369             :         {
     370           0 :                 fprintf(stderr, "error: the \"more..test.com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
     371           0 :                 ++err_count;
     372             :         }
     373           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     374             :         {
     375           0 :                 fprintf(stderr, "error: the \"more..test.com\" URI did not return a reset info structure.\n");
     376           0 :                 ++err_count;
     377             :         }
     378             : 
     379             :         /* test: "noperiodanywhere" (no periods anywhere) */
     380           1 :         info = clear_info;
     381           1 :         r = tld("noperiodanywhere", &info);
     382           1 :         if(r != TLD_RESULT_NO_TLD)
     383             :         {
     384           0 :                 fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return the TLD_RESULT_NO_TLD result.\n");
     385           0 :                 ++err_count;
     386             :         }
     387           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     388             :         {
     389           0 :                 fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return a reset info structure.\n");
     390           0 :                 ++err_count;
     391             :         }
     392           1 : }
     393             : 
     394             : 
     395             : 
     396             : 
     397           1 : int main(int argc, char *argv[])
     398             : {
     399           1 :         fprintf(stderr, "testing tld version %s\n", tld_version());
     400             : 
     401           1 :         if(argc > 1)
     402             :         {
     403           0 :                 if(strcmp(argv[1], "-v") == 0)
     404             :                 {
     405           0 :                         verbose = 1;
     406             :                 }
     407             :         }
     408             : 
     409             :         /* call all the tests, one by one
     410             :          * failures are "recorded" in the err_count global variable
     411             :          * and the process stops with an error message and exit(1)
     412             :          * if err_count is not zero.
     413             :          */
     414           1 :         test_all();
     415           1 :         test_unknown();
     416           1 :         test_invalid();
     417             : 
     418           1 :         if(err_count)
     419             :         {
     420           0 :                 fprintf(stderr, "%d error%s occured.\n",
     421           0 :                                         err_count, err_count != 1 ? "s" : "");
     422             :         }
     423           1 :         exit(err_count ? 1 : 0);
     424             : }
     425             : 
     426             : /* vim: ts=4 sw=4
     427             :  */

Generated by: LCOV version 1.12