static void test_psl(void) { /* punycode generation: idn ?? */ /* octal code generation: echo -n "??" | od -b */ static const struct test_data { const char *domain; int result; } test_data[] = { { "www.example.com", 0 }, { "com.ar", 1 }, { "www.com.ar", 0 }, { "cc.ar.us", 1 }, { ".cc.ar.us", 1 }, { "www.cc.ar.us", 0 }, { "www.ck", 0 }, /* exception from *.ck */ { "abc.www.ck", 0 }, { "xxx.ck", 1 }, { "www.xxx.ck", 0 }, { "\345\225\206\346\240\207", 1 }, /* xn--czr694b or ?? */ { "www.\345\225\206\346\240\207", 0 }, /* some special test follow ('name' and 'forgot.his.name' are public, but e.g. his.name is not) */ { "name", 1 }, { ".name", 1 }, { "his.name", 0 }, { ".his.name", 0 }, { "forgot.his.name", 1 }, { ".forgot.his.name", 1 }, { "whoever.his.name", 0 }, { "whoever.forgot.his.name", 0 }, { ".", 1 }, /* special case */ { "", 1 }, /* special case */ { NULL, 1 }, /* special case */ { "adfhoweirh", 1 }, /* unknown TLD */ }; unsigned it; psl_ctx_t *psl; psl = psl_load_file(PSL_FILE); printf("loaded %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl)); for (it = 0; it < countof(test_data); it++) { const struct test_data *t = &test_data[it]; int result = psl_is_public_suffix(psl, t->domain); if (result == t->result) { ok++; } else { failed++; printf("psl_is_public_suffix(%s)=%d (expected %d)\n", t->domain, result, t->result); } } psl_free(psl); }
static void test_psl(void) { FILE *fp; const psl_ctx_t *psl; char buf[256], domain[128], expected_regdom[128]; psl = psl_builtin(); printf("have %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl)); /* special check with NULL values */ test(NULL, NULL, NULL); /* special check with NULL psl context */ test(NULL, "www.example.com", NULL); /* special check with NULL psl context and TLD */ test(NULL, "com", NULL); /* Norwegian with uppercase oe */ #ifdef WITH_LIBICU test(psl, "www.\303\230yer.no", "www.\303\270yer.no"); #endif /* Norwegian with lowercase oe */ test(psl, "www.\303\270yer.no", "www.\303\270yer.no"); /* special check with NULL psl context and TLD */ test(psl, "whoever.forgot.his.name", "whoever.forgot.his.name"); /* special check with NULL psl context and TLD */ test(psl, "forgot.his.name", NULL); /* special check with NULL psl context and TLD */ test(psl, "his.name", "his.name"); if ((fp = fopen(PSL_TESTFILE, "r"))) { while ((fgets(buf, sizeof(buf), fp))) { if (sscanf(buf, " checkPublicSuffix('%127[^']' , '%127[^']", domain, expected_regdom) != 2) { if (sscanf(buf, " checkPublicSuffix('%127[^']' , %127[nul]", domain, expected_regdom) != 2) continue; } if (!strcmp(expected_regdom, "null")) test(psl, domain, NULL); else test(psl, domain, expected_regdom); } fclose(fp); } else { printf("Failed to open %s\n", PSL_TESTFILE); failed++; } }
static void test_psl(void) { FILE *fp; psl_ctx_t *psl, *psl3, *psl4, *psl5; const psl_ctx_t *psl2; int type = 0; char buf[256], *linep, *p; psl = psl_load_file(PSL_FILE); /* PSL_FILE can be set by ./configure --with-psl-file=[PATH] */ printf("loaded %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl)); psl2 = psl_builtin(); printf("builtin PSL has %d suffixes and %d exceptions\n", psl_suffix_count(psl2), psl_suffix_exception_count(psl2)); if (!(psl3 = psl_load_file(PSL_DAFSA))) { fprintf(stderr, "Failed to load 'psl.dafsa'\n"); failed++; } if (!(psl4 = psl_load_file(PSL_ASCII_DAFSA))) { fprintf(stderr, "Failed to load 'psl_ascii.dafsa'\n"); failed++; } psl5 = psl_latest("psl.dafsa"); if ((fp = fopen(PSL_FILE, "r"))) { #ifdef HAVE_CLOCK_GETTIME clock_gettime(CLOCK_REALTIME, &ts1); #endif while ((linep = fgets(buf, sizeof(buf), fp))) { while (_isspace_ascii(*linep)) linep++; /* ignore leading whitespace */ if (!*linep) continue; /* skip empty lines */ if (*linep == '/' && linep[1] == '/') { if (!type) { if (strstr(linep + 2, "===BEGIN ICANN DOMAINS===")) type = PSL_TYPE_ICANN; else if (!type && strstr(linep + 2, "===BEGIN PRIVATE DOMAINS===")) type = PSL_TYPE_PRIVATE; } else if (type == PSL_TYPE_ICANN && strstr(linep + 2, "===END ICANN DOMAINS===")) type = 0; else if (type == PSL_TYPE_PRIVATE && strstr(linep + 2, "===END PRIVATE DOMAINS===")) type = 0; continue; /* skip comments */ } /* parse suffix rule */ for (p = linep; *linep && !_isspace_ascii(*linep);) linep++; *linep = 0; test_psl_entry(psl, p, type); if (psl2) test_psl_entry(psl2, p, type); if (psl3) test_psl_entry(psl3, p, type); if (psl4) test_psl_entry(psl4, p, type); if (psl5) test_psl_entry(psl5, p, type); } #ifdef HAVE_CLOCK_GETTIME clock_gettime(CLOCK_REALTIME, &ts2); #endif fclose(fp); } else { printf("Failed to open %s\n", PSL_FILE); failed++; } psl_free(psl5); psl_free(psl4); psl_free(psl3); psl_free((psl_ctx_t *)psl2); psl_free(psl); }
static void test_psl(void) { FILE *fp; psl_ctx_t *psl; int result; char buf[256], domain[64], *linep, *p; psl = psl_load_file(PSL_FILE); /* PSL_FILE can be set by ./configure --with-psl-file=[PATH] */ printf("loaded %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl)); if ((fp = fopen(PSL_FILE, "r"))) { while ((linep = fgets(buf, sizeof(buf), fp))) { while (_isspace_ascii(*linep)) linep++; /* ignore leading whitespace */ if (!*linep) continue; /* skip empty lines */ if (*linep == '/' && linep[1] == '/') continue; /* skip comments */ /* parse suffix rule */ for (p = linep; *linep && !_isspace_ascii(*linep);) linep++; *linep = 0; if (*p == '!') { /* an exception to a wildcard, e.g. !www.ck (wildcard is *.ck) */ if ((result = psl_is_public_suffix(psl, p + 1))) { failed++; printf("psl_is_public_suffix(%s)=%d (expected 0)\n", p, result); } else ok++; if (!(result = psl_is_public_suffix(psl, strchr(p, '.') + 1))) { failed++; printf("psl_is_public_suffix(%s)=%d (expected 1)\n", strchr(p, '.') + 1, result); } else ok++; } else if (*p == '*') { /* a wildcard, e.g. *.ck */ if (!(result = psl_is_public_suffix(psl, p + 1))) { failed++; printf("psl_is_public_suffix(%s)=%d (expected 1)\n", p + 1, result); } else ok++; *p = 'x'; if (!(result = psl_is_public_suffix(psl, p))) { failed++; printf("psl_is_public_suffix(%s)=%d (expected 1)\n", p, result); } else ok++; } else { if (!(result = psl_is_public_suffix(psl, p))) { failed++; printf("psl_is_public_suffix(%s)=%d (expected 1)\n", p, result); } else ok++; snprintf(domain, sizeof(domain), "xxxx.%s", p); if ((result = psl_is_public_suffix(psl, domain))) { failed++; printf("psl_is_public_suffix(%s)=%d (expected 0)\n", domain, result); } else ok++; } } fclose(fp); } else { printf("Failed to open %s\n", PSL_FILE); failed++; } psl_free(psl); }
int main(int argc, const char *const *argv) { int mode = 1; const char *const *arg, *psl_file = NULL, *cookie_domain = NULL; psl_ctx_t *psl = (psl_ctx_t *) psl_builtin(); /* set current locale according to the environment variables */ #include <locale.h> setlocale(LC_ALL, ""); for (arg = argv + 1; arg < argv + argc; arg++) { if (!strncmp(*arg, "--", 2)) { if (!strcmp(*arg, "--is-public-suffix")) mode = 1; else if (!strcmp(*arg, "--print-unreg-domain")) mode = 2; else if (!strcmp(*arg, "--print-reg-domain")) mode = 3; else if (!strcmp(*arg, "--print-info")) mode = 99; else if (!strcmp(*arg, "--is-cookie-domain-acceptable") && arg < argv + argc - 1) { mode = 4; cookie_domain = *(++arg); } else if (!strcmp(*arg, "--use-builtin-data")) { psl_free(psl); if (psl_file) { fprintf(stderr, "Dropped data from %s\n", psl_file); psl_file = NULL; } if (!(psl = (psl_ctx_t *) psl_builtin())) printf("No builtin PSL data available\n"); } else if (!strcmp(*arg, "--load-psl-file") && arg < argv + argc - 1) { psl_free(psl); if (psl_file) { fprintf(stderr, "Dropped data from %s\n", psl_file); psl_file = NULL; } if (!(psl = psl_load_file(psl_file = *(++arg)))) { fprintf(stderr, "Failed to load PSL data from %s\n\n", psl_file); psl_file = NULL; } } else if (!strcmp(*arg, "--help")) { fprintf(stdout, "`psl' explores the Public Suffix List\n\n"); usage(0, stdout); } else if (!strcmp(*arg, "--version")) { printf("psl %s\n", PACKAGE_VERSION); printf("libpsl %s\n", psl_get_version()); printf("\n"); printf("Copyright (C) 2014-2015 Tim Ruehsen\n"); printf("License: MIT\n"); exit(0); } else if (!strcmp(*arg, "--")) { arg++; break; } else { fprintf(stderr, "Unknown option '%s'\n", *arg); usage(1, stderr); } } else break; } if (mode != 99) { if (!psl) { fprintf(stderr, "No PSL data available - aborting\n"); exit(2); } if (arg >= argv + argc) { char buf[256], *domain, *lower; size_t len; psl_error_t rc; /* read URLs from STDIN */ while (fgets(buf, sizeof(buf), stdin)) { for (domain = buf; isspace(*domain); domain++); /* skip leading spaces */ if (*domain == '#' || !*domain) continue; /* skip empty lines and comments */ for (len = strlen(domain); len && isspace(domain[len - 1]); len--); /* skip trailing spaces */ domain[len] = 0; if ((rc = psl_str_to_utf8lower(domain, NULL, NULL, &lower)) != PSL_SUCCESS) fprintf(stderr, "%s: Failed to convert to lowercase UTF-8 (%d)\n", domain, rc); else if (mode == 1) printf("%s: %d (%s)\n", domain, psl_is_public_suffix(psl, lower), lower); else if (mode == 2) printf("%s: %s\n", domain, psl_unregistrable_domain(psl, lower)); else if (mode == 3) printf("%s: %s\n", domain, psl_registrable_domain(psl, lower)); else if (mode == 4) { char *cookie_domain_lower; if ((rc = psl_str_to_utf8lower(domain, NULL, NULL, &cookie_domain_lower)) != PSL_SUCCESS) fprintf(stderr, "%s: Failed to convert cookie domain '%s' to lowercase UTF-8 (%d)\n", domain, cookie_domain, rc); else printf("%s: %d\n", domain, psl_is_cookie_domain_acceptable(psl, lower, cookie_domain)); free(cookie_domain_lower); } free(lower); } psl_free(psl); exit(0); } } if (mode == 1) { for (; arg < argv + argc; arg++) printf("%s: %d\n", *arg, psl_is_public_suffix(psl, *arg)); } else if (mode == 2) { for (; arg < argv + argc; arg++) printf("%s: %s\n", *arg, psl_unregistrable_domain(psl, *arg)); } else if (mode == 3) { for (; arg < argv + argc; arg++) printf("%s: %s\n", *arg, psl_registrable_domain(psl, *arg)); } else if (mode == 4) { for (; arg < argv + argc; arg++) printf("%s: %d\n", *arg, psl_is_cookie_domain_acceptable(psl, *arg, cookie_domain)); } else if (mode == 99) { if (psl && psl != psl_builtin()) { printf("suffixes: %d\n", psl_suffix_count(psl)); printf("exceptions: %d\n", psl_suffix_exception_count(psl)); printf("wildcards: %d\n", psl_suffix_wildcard_count(psl)); } psl_free(psl); psl = (psl_ctx_t *) psl_builtin(); if (psl) { printf("builtin suffixes: %d\n", psl_suffix_count(psl)); printf("builtin exceptions: %d\n", psl_suffix_exception_count(psl)); printf("builtin wildcards: %d\n", psl_suffix_wildcard_count(psl)); printf("builtin filename: %s\n", psl_builtin_filename()); printf("builtin compile time: %ld (%s)\n", psl_builtin_compile_time(), time2str(psl_builtin_compile_time())); printf("builtin file time: %ld (%s)\n", psl_builtin_file_time(), time2str(psl_builtin_file_time())); printf("builtin SHA1 file hash: %s\n", psl_builtin_sha1sum()); } else printf("No builtin PSL data available\n"); } psl_free(psl); return 0; }
static void test_psl(void) { FILE *fp; const psl_ctx_t *psl; const char *p; char buf[256], domain[128], expected_regdom[128], semicolon[2]; char lbuf[258]; int er_is_null, d_is_null; unsigned it; psl = psl_builtin(); printf("have %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl)); /* special check with NULL values */ test(NULL, NULL, NULL); /* special check with NULL psl context */ test(NULL, "www.example.com", NULL); /* special check with NULL psl context and TLD */ test(NULL, "com", NULL); /* Norwegian with uppercase oe */ #ifdef WITH_LIBICU test(psl, "www.\303\230yer.no", "www.\303\270yer.no"); #endif /* Norwegian with lowercase oe */ test(psl, "www.\303\270yer.no", "www.\303\270yer.no"); /* Norwegian with lowercase oe, encoded as ISO-8859-15 */ test_iso(psl, "www.\370yer.no", "www.\303\270yer.no"); /* Testing special code paths of psl_str_to_utf8lower() */ for (it = 254; it <= 257; it++) { memset(lbuf, 'a', it); lbuf[it] = 0; lbuf[0] = '\370'; test_iso(psl, lbuf, NULL); lbuf[0] = '\303'; lbuf[1] = '\270'; test(psl, lbuf, NULL); } /* special check with NULL psl context and TLD */ test(psl, "whoever.forgot.his.name", "whoever.forgot.his.name"); /* special check with NULL psl context and TLD */ test(psl, "forgot.his.name", NULL); /* special check with NULL psl context and TLD */ test(psl, "his.name", "his.name"); if ((fp = fopen(PSL_TESTFILE, "r"))) { while ((fgets(buf, sizeof(buf), fp))) { /* advance over ASCII white space */ for (p = buf; *p == ' ' || *p == '\t' || *p == '\r' || *p == '\n'; p++) ; if (!*p || (*p == '/' && p[1] == '/')) continue; /* ignore comments and blank lines */ er_is_null = 0; d_is_null = 0; if (sscanf(p, "checkPublicSuffix ( '%127[^']' , '%127[^']' ) %1[;]", domain, expected_regdom, semicolon) != 3) { if (sscanf(p, "checkPublicSuffix ( '%127[^']' , null ) %1[;]", domain, semicolon) == 2) { er_is_null = 1; } else if (sscanf(p, "checkPublicSuffix ( null , '%127[^']' ) %1[;]", expected_regdom, semicolon) == 2) { d_is_null = 1; } else if (sscanf(p, "checkPublicSuffix ( null , null ) %1[;]", semicolon) == 1) { d_is_null = 1; er_is_null = 1; } else if (sscanf(p, "%127s %127s", domain, expected_regdom) == 2) { if (!strcmp(domain, "null")) d_is_null = 1; if (!strcmp(expected_regdom, "null")) er_is_null = 1; } else { failed++; printf("Malformed line from '" PSL_TESTFILE "': %s", buf); continue; } } test(psl, d_is_null ? NULL : domain, er_is_null ? NULL : expected_regdom); } fclose(fp); } else { printf("Failed to open %s\n", PSL_TESTFILE); failed++; } }
static void test_psl(void) { /* punycode generation: idn ?? */ /* octal code generation: echo -n "??" | od -b */ static const struct test_data { const char *domain; int result; } test_data[] = { { "www.example.com", 0 }, { "com.ar", 1 }, { "www.com.ar", 0 }, { "cc.ar.us", 1 }, { ".cc.ar.us", 1 }, { "www.cc.ar.us", 0 }, { "www.ck", 0 }, /* exception from *.ck */ { "abc.www.ck", 0 }, { "xxx.ck", 1 }, { "www.xxx.ck", 0 }, { "\345\225\206\346\240\207", 1 }, /* xn--czr694b or ?? */ { "www.\345\225\206\346\240\207", 0 }, /* some special test follow ('name' and 'forgot.his.name' are public, but e.g. his.name is not) */ { "name", 1 }, { ".name", 1 }, { "his.name", 0 }, { ".his.name", 0 }, { "forgot.his.name", 1 }, { ".forgot.his.name", 1 }, { "whoever.his.name", 0 }, { "whoever.forgot.his.name", 0 }, { ".", 1 }, /* special case */ { "", 1 }, /* special case */ { NULL, 1 }, /* special case */ { "adfhoweirh", 1 }, /* unknown TLD */ }; unsigned it; int result, ver; psl_ctx_t *psl; psl = psl_load_file(PSL_FILE); printf("loaded %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl)); for (it = 0; it < countof(test_data); it++) { const struct test_data *t = &test_data[it]; result = psl_is_public_suffix(psl, t->domain); if (result == t->result) { ok++; } else { failed++; printf("psl_is_public_suffix(%s)=%d (expected %d)\n", t->domain, result, t->result); } } /* do some checks to cover more code paths in libpsl */ psl_is_public_suffix(NULL, "xxx"); if ((ver = psl_check_version_number(0)) == 0) { printf("psl_check_version_number(0) is 0\n"); failed++; } else { if (((result = psl_check_version_number(ver)) != ver)) { printf("psl_check_version_number(%06X) is %06X\n", ver, result); failed++; } if (((result = psl_check_version_number(ver - 1)) != 0)) { printf("psl_check_version_number(%06X) is %06X\n", ver - 1, result); failed++; } if (((result = psl_check_version_number(ver + 1)) != ver)) { printf("psl_check_version_number(%06X) is %06X\n", ver, result); failed++; } } psl_str_to_utf8lower("www.example.com", "utf-8", "en", NULL); psl_str_to_utf8lower(NULL, "utf-8", "en", NULL); { char *lower = NULL; psl_str_to_utf8lower("www.example.com", NULL, "de", &lower); free(lower); lower = NULL; psl_str_to_utf8lower("\374bel.de", NULL, "de", &lower); free(lower); lower = NULL; psl_str_to_utf8lower("\374bel.de", "iso-8859-1", NULL, &lower); free(lower); lower = NULL; psl_str_to_utf8lower(NULL, "utf-8", "en", &lower); free(lower); lower = NULL; } psl_get_version(); psl_dist_filename(); psl_builtin_filename(); psl_builtin_outdated(); psl_builtin_file_time(); psl_builtin_sha1sum(); psl_suffix_wildcard_count(NULL); psl_suffix_wildcard_count(psl); psl_suffix_wildcard_count(psl_builtin()); psl_suffix_count(NULL); psl_suffix_exception_count(NULL); psl_load_file(NULL); psl_load_fp(NULL); psl_registrable_domain(NULL, ""); psl_registrable_domain(psl, NULL); psl_registrable_domain(psl, "www.example.com"); psl_unregistrable_domain(NULL, ""); psl_unregistrable_domain(psl, NULL); psl_is_public_suffix2(NULL, "", PSL_TYPE_ANY); psl_is_public_suffix2(psl, NULL, PSL_TYPE_ANY); psl_free(psl); }