libtld 1.2.0
|
00001 /* TLD library -- test the TLD interface 00002 * Copyright (C) 2011 Made to Order Software Corp. 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00017 */ 00018 00019 #include "tld.h" 00020 #include <string.h> 00021 #include <stdlib.h> 00022 #include <stdio.h> 00023 #include <limits.h> 00024 00025 /* we get access to the table with all the TLDs so we can go through them all 00026 * the library does not give direct access by default... (although maybe we 00027 * could give users access to the data) 00028 */ 00029 #include "tld_data.h" 00030 extern const struct tld_description tld_descriptions[]; 00031 extern unsigned short tld_start_offset; 00032 extern unsigned short tld_end_offset; 00033 00034 int err_count = 0; 00035 00036 /* 00037 * This test calls the tld() function with all the TLDs and then 00038 * with wrong TLDs to make sure that the tld() functions works as 00039 * expected. 00040 * 00041 * extern enum tld_result tld(const char *uri, struct tld_info *info); 00042 */ 00043 00044 00053 void cat_ext(int offset, char *uri) 00054 { 00055 int k, l; 00056 00057 strcat(uri, tld_descriptions[offset].f_tld); 00058 l = offset; 00059 for(k = offset + 1; k < tld_end_offset; ++k) 00060 { 00061 if(l >= tld_descriptions[k].f_start_offset 00062 && l < tld_descriptions[k].f_end_offset) 00063 { 00064 /* found a parent */ 00065 strcat(uri, "."); 00066 strcat(uri, tld_descriptions[k].f_tld); 00067 l = k; 00068 k = tld_descriptions[k].f_end_offset; 00069 } 00070 } 00071 } 00072 00073 /* 00074 * This test goes through all the domain names and extracts the domain, 00075 * sub-domains and TLDs. (Or at least verifies that we get the correct 00076 * information in order to do so.) 00077 * 00078 * It builds a URI with zero to many sub-domain names, adds a specific 00079 * domain name, then append a complete TLD. The result is then checked 00080 * with the tld() function from the library. The tld() is expected to 00081 * either return VALID or INVALID but nothing else (since all those 00082 * TLDs exist in our table.) Then we verify that the returned offset is 00083 * a perfect match. 00084 */ 00085 void test_all() 00086 { 00087 const char *sub_domains[] = { 00088 "", 00089 "www.", 00090 "tld.", 00091 "george.snap.", 00092 "very.long.sub.domain.ext.en.sion.here." 00093 }; 00094 struct tld_info info; 00095 char uri[256], extension_uri[256]; 00096 int i, j, k, l, p, max_subdomains; 00097 char *s; 00098 enum tld_result r; 00099 00100 max_subdomains = sizeof(sub_domains) / sizeof(sub_domains[0]); 00101 00102 for(i = 0; i < tld_end_offset; ++i) 00103 { 00104 for(j = 0; j < max_subdomains; ++j) 00105 { 00106 strcpy(uri, sub_domains[j]); 00107 strcat(uri, "domain-name."); 00108 cat_ext(i, uri); 00109 /* reset the structure so we can verify it gets initialized */ 00110 memset(&info, 0xFE, sizeof(info)); 00111 r = tld(uri, &info); 00112 /* 00113 for(l = 0; l < sizeof(info); ++l) 00114 { 00115 fprintf(stderr, "0x%02X ", ((unsigned char*)&info)[l]); 00116 } 00117 fprintf(stderr, "\nresult for [%s]: category[%d], status[%d], country[%s]," 00118 " tld[%s], offset[%d]\n", 00119 uri, 00120 (int)info.f_category, (int)info.f_status, info.f_country, 00121 info.f_tld, (int)info.f_offset); 00122 */ 00123 p = i; 00124 if(tld_descriptions[i].f_status == TLD_STATUS_EXCEPTION) 00125 { 00126 if(tld_descriptions[i].f_exception_apply_to == USHRT_MAX) 00127 { 00128 fprintf(stderr, "error: domain name for \"%s\" (%d) is said to be an exception but it has no apply-to parameter.\n", 00129 uri, i, r); 00130 ++err_count; 00131 } 00132 else 00133 { 00134 p = tld_descriptions[i].f_exception_apply_to; 00135 } 00136 } 00137 if(tld_descriptions[i].f_status == TLD_STATUS_VALID) 00138 { 00139 if(r != TLD_RESULT_SUCCESS) 00140 { 00141 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n", 00142 uri, i, r); 00143 ++err_count; 00144 } 00145 else 00146 { 00147 if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0) 00148 { 00149 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n", 00150 uri, i, r); 00151 ++err_count; 00152 } 00153 /* 00154 else 00155 fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 00156 */ 00157 } 00158 } 00159 else 00160 { 00161 if(r != TLD_RESULT_INVALID) 00162 { 00163 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d)\n", 00164 uri, i, r); 00165 ++err_count; 00166 } 00167 else if(p != i) 00168 { 00169 strcpy(extension_uri, "."); 00170 cat_ext(p, extension_uri); 00171 l = strlen(extension_uri); 00172 if(strcmp(info.f_tld, extension_uri) != 0) 00173 { 00174 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s)\n", 00175 uri, i, r, info.f_tld); 00176 ++err_count; 00177 } 00178 /* 00179 else 00180 fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 00181 */ 00182 } 00183 else 00184 { 00185 if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0) 00186 { 00187 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s)\n", 00188 uri, i, r, info.f_tld); 00189 ++err_count; 00190 } 00191 /* 00192 else 00193 fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 00194 */ 00195 } 00196 } 00197 } 00198 } 00199 } 00200 00201 00202 /* 00203 * This test checks out URIs that end with an invalid TLD. This is 00204 * expected to return an error every single time. 00205 */ 00206 void test_unknown() 00207 { 00208 struct bad_data 00209 { 00210 const char * f_uri; 00211 }; 00212 struct bad_data d[] = { 00213 "this.is.wrong", 00214 "missing.tld", 00215 ".net.absolutely.com.no.info.on.this" 00216 }; 00217 struct tld_info info; 00218 int i, max; 00219 enum tld_result r; 00220 00221 max = sizeof(d) / sizeof(d[0]); 00222 for(i = 0; i < max; ++i) 00223 { 00224 memset(&info, 0xFE, sizeof(info)); 00225 r = tld(d[i].f_uri, &info); 00226 if(r != TLD_RESULT_NOT_FOUND) 00227 { 00228 fprintf(stderr, "error: the invalid URI \"%s\" was found by tld()!\n", d[i].f_uri); 00229 ++err_count; 00230 } 00231 } 00232 } 00233 00234 00235 00236 00237 void test_invalid() 00238 { 00239 struct tld_info undefined_info; 00240 struct tld_info clear_info; 00241 struct tld_info info; 00242 enum tld_result r; 00243 00244 /* 00245 * We reset the undefined_info the same way we reset the info 00246 * structure because the alignment on 64bits may add another 00247 * 4 bytes at the end of the structure that are not otherwise 00248 * accessible. 00249 */ 00250 memset(&undefined_info, 0xFE, sizeof(undefined_info)); 00251 undefined_info.f_category = TLD_CATEGORY_UNDEFINED; 00252 undefined_info.f_status = TLD_STATUS_UNDEFINED; 00253 undefined_info.f_country = (const char *) 0; 00254 undefined_info.f_tld = (const char *) 0; 00255 undefined_info.f_offset = -1; 00256 00257 memset(&clear_info, 0xFE, sizeof(clear_info)); 00258 00259 /* test: NULL */ 00260 info = clear_info; 00261 r = tld(NULL, &info); 00262 if(r != TLD_RESULT_NULL) 00263 { 00264 fprintf(stderr, "error: the NULL URI did not return the TLD_RESULT_NULL result.\n"); 00265 ++err_count; 00266 } 00267 if(memcmp(&info, &undefined_info, sizeof(info)) != 0) 00268 { 00269 fprintf(stderr, "error: the NULL URI did not return a reset info structure.\n"); 00270 ++err_count; 00271 } 00272 00273 /* test: "" */ 00274 info = clear_info; 00275 r = tld("", &info); 00276 if(r != TLD_RESULT_NULL) 00277 { 00278 fprintf(stderr, "error: the \"\" URI did not return the TLD_RESULT_NULL result.\n"); 00279 ++err_count; 00280 } 00281 if(memcmp(&info, &undefined_info, sizeof(info)) != 0) 00282 { 00283 fprintf(stderr, "error: the \"\" URI did not return a reset info structure.\n"); 00284 ++err_count; 00285 } 00286 00287 /* test: ".." (two periods one after another) */ 00288 info = clear_info; 00289 r = tld("test..com", &info); 00290 if(r != TLD_RESULT_BAD_URI) 00291 { 00292 fprintf(stderr, "error: the \"test..com\" URI did not return the TLD_RESULT_BAD_URI result.\n"); 00293 ++err_count; 00294 } 00295 if(memcmp(&info, &undefined_info, sizeof(info)) != 0) 00296 { 00297 fprintf(stderr, "error: the \"test..com\" URI did not return a reset info structure.\n"); 00298 ++err_count; 00299 } 00300 00301 /* test: ".." (two periods one after another) */ 00302 info = clear_info; 00303 r = tld("more..test.com", &info); 00304 if(r != TLD_RESULT_BAD_URI) 00305 { 00306 fprintf(stderr, "error: the \"more..test.com\" URI did not return the TLD_RESULT_BAD_URI result.\n"); 00307 ++err_count; 00308 } 00309 if(memcmp(&info, &undefined_info, sizeof(info)) != 0) 00310 { 00311 fprintf(stderr, "error: the \"more..test.com\" URI did not return a reset info structure.\n"); 00312 ++err_count; 00313 } 00314 00315 /* test: "noperiodanywhere" (no periods anywhere) */ 00316 info = clear_info; 00317 r = tld("noperiodanywhere", &info); 00318 if(r != TLD_RESULT_NO_TLD) 00319 { 00320 fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return the TLD_RESULT_NO_TLD result.\n"); 00321 ++err_count; 00322 } 00323 if(memcmp(&info, &undefined_info, sizeof(info)) != 0) 00324 { 00325 fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return a reset info structure.\n"); 00326 ++err_count; 00327 } 00328 } 00329 00330 00331 00332 00333 int main(int argc, char *argv[]) 00334 { 00335 fprintf(stderr, "testing tld version %s\n", tld_version()); 00336 00337 /* call all the tests, one by one 00338 * failures are "recorded" in the err_count global variable 00339 * and the process stops with an error message and exit(1) 00340 * if err_count is not zero. 00341 */ 00342 test_all(); 00343 test_unknown(); 00344 test_invalid(); 00345 00346 if(err_count) 00347 { 00348 fprintf(stderr, "%d error%s occured.\n", 00349 err_count, err_count != 1 ? "s" : ""); 00350 } 00351 exit(err_count ? 1 : 0); 00352 } 00353 00354 /* vim: ts=4 sw=4 00355 */
This document is part of the libtld Project.
Copyright by Made to Order Software Corp.