changed code to C89 standard

This commit is contained in:
Tim Ruehsen 2014-05-12 12:20:59 +02:00
parent 2919a702be
commit 1efb6b75f4
9 changed files with 171 additions and 145 deletions

View File

@ -41,42 +41,46 @@ extern "C" {
typedef struct _psl_ctx_st psl_ctx_t; typedef struct _psl_ctx_st psl_ctx_t;
/* frees PSL context */
void void
psl_free(psl_ctx_t *psl); psl_free(psl_ctx_t *psl);
/* loads PSL data from file */
psl_ctx_t * psl_ctx_t *
psl_load_file(const char *fname); psl_load_file(const char *fname);
/* loads PSL data from FILE pointer */
psl_ctx_t * psl_ctx_t *
psl_load_fp(FILE *fp); psl_load_fp(FILE *fp);
/* retrieves builtin PSL data */
const psl_ctx_t * const psl_ctx_t *
psl_builtin(void); psl_builtin(void);
// checks wether domain is a public suffix or not /* checks wether domain is a public suffix or not */
int int
psl_is_public_suffix(const psl_ctx_t *psl, const char *domain); psl_is_public_suffix(const psl_ctx_t *psl, const char *domain);
// checks wether cookie_domain is acceptable for domain or not /* checks wether cookie_domain is acceptable for domain or not */
int int
psl_is_cookie_domain_acceptable(const psl_ctx_t *psl, const char *hostname, const char *cookie_domain); psl_is_cookie_domain_acceptable(const psl_ctx_t *psl, const char *hostname, const char *cookie_domain);
// returns the longest unregistrable domain within 'domain' or NULL if none found /* returns the longest unregistrable domain within 'domain' or NULL if none found */
const char * const char *
psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain); psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain);
// returns the shortest possible registrable domain part or NULL if domain is not registrable at all /* returns the shortest possible registrable domain part or NULL if domain is not registrable at all */
const char * const char *
psl_registrable_domain(const psl_ctx_t *psl, const char *domain); psl_registrable_domain(const psl_ctx_t *psl, const char *domain);
// does not include exceptions /* does not include exceptions */
int int
psl_suffix_count(const psl_ctx_t *psl); psl_suffix_count(const psl_ctx_t *psl);
// just counts exceptions /* just counts exceptions */
int int
psl_suffix_exception_count(const psl_ctx_t *psl); psl_suffix_exception_count(const psl_ctx_t *psl);
// returns compilation time /* returns compilation time */
time_t time_t
psl_builtin_compile_time(void); psl_builtin_compile_time(void);
// returns mtime of PSL source file /* returns mtime of PSL source file */
time_t time_t
psl_builtin_file_time(void); psl_builtin_file_time(void);
// returns SHA1 checksum (hex-encoded, lowercase) of PSL source file /* returns SHA1 checksum (hex-encoded, lowercase) of PSL source file */
const char * const char *
psl_builtin_sha1sum(void); psl_builtin_sha1sum(void);
// returns file name of PSL source file /* returns file name of PSL source file */
const char * const char *
psl_builtin_filename(void); psl_builtin_filename(void);

View File

@ -28,7 +28,7 @@
* *
*/ */
// need _GNU_SOURCE for qsort_r() /* need _GNU_SOURCE for qsort_r() */
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
# define _GNU_SOURCE # define _GNU_SOURCE
#endif #endif
@ -73,19 +73,19 @@ typedef struct {
unsigned short unsigned short
length; length;
unsigned char unsigned char
nlabels, // number of labels nlabels, /* number of labels */
wildcard; // this is a wildcard rule (e.g. *.sapporo.jp) wildcard; /* this is a wildcard rule (e.g. *.sapporo.jp) */
} _psl_entry_t; } _psl_entry_t;
// stripped down version libmget vector routines /* stripped down version libmget vector routines */
typedef struct { typedef struct {
int int
(*cmp)(const _psl_entry_t *, const _psl_entry_t *); // comparison function (*cmp)(const _psl_entry_t *, const _psl_entry_t *); /* comparison function */
_psl_entry_t _psl_entry_t
**entry; // pointer to array of pointers to elements **entry; /* pointer to array of pointers to elements */
int int
max, // allocated elements max, /* allocated elements */
cur; // number of elements in use cur; /* number of elements in use */
} _psl_vector_t; } _psl_vector_t;
struct _psl_ctx_st { struct _psl_ctx_st {
@ -94,10 +94,10 @@ struct _psl_ctx_st {
*suffix_exceptions; *suffix_exceptions;
}; };
// include the PSL data compiled by 'psl2c' /* include the PSL data compiled by 'psl2c' */
#include "suffixes.c" #include "suffixes.c"
// references to this PSL will result in lookups to built-in data /* references to this PSL will result in lookups to built-in data */
static const psl_ctx_t static const psl_ctx_t
_builtin_psl; _builtin_psl;
@ -140,14 +140,14 @@ static _psl_entry_t *_vector_get(const _psl_vector_t *v, int pos)
return v->entry[pos]; return v->entry[pos];
} }
// the entries must be sorted by /* the entries must be sorted by */
static int _vector_find(const _psl_vector_t *v, const _psl_entry_t *elem) static int _vector_find(const _psl_vector_t *v, const _psl_entry_t *elem)
{ {
if (v) { if (v) {
int l, r, m; int l, r, m;
int res; int res;
// binary search for element (exact match) /* binary search for element (exact match) */
for (l = 0, r = v->cur - 1; l <= r;) { for (l = 0, r = v->cur - 1; l <= r;) {
m = (l + r) / 2; m = (l + r) / 2;
if ((res = v->cmp(elem, v->entry[m])) > 0) l = m + 1; if ((res = v->cmp(elem, v->entry[m])) > 0) l = m + 1;
@ -156,7 +156,7 @@ static int _vector_find(const _psl_vector_t *v, const _psl_entry_t *elem)
} }
} }
return -1; // not found return -1; /* not found */
} }
static int _vector_add(_psl_vector_t *v, const _psl_entry_t *elem) static int _vector_add(_psl_vector_t *v, const _psl_entry_t *elem)
@ -188,22 +188,21 @@ static void _vector_sort(_psl_vector_t *v)
qsort_r(v->entry, v->cur, sizeof(_psl_vector_t *), _compare, v); qsort_r(v->entry, v->cur, sizeof(_psl_vector_t *), _compare, v);
} }
static inline int _vector_size(_psl_vector_t *v) static int _vector_size(_psl_vector_t *v)
{ {
return v ? v->cur : 0; return v ? v->cur : 0;
} }
// by this kind of sorting, we can easily see if a domain matches or not /* by this kind of sorting, we can easily see if a domain matches or not */
static int _suffix_compare(const _psl_entry_t *s1, const _psl_entry_t *s2) static int _suffix_compare(const _psl_entry_t *s1, const _psl_entry_t *s2)
{ {
int n; int n;
if ((n = s2->nlabels - s1->nlabels)) if ((n = s2->nlabels - s1->nlabels))
return n; // most labels first return n; /* most labels first */
if ((n = s1->length - s2->length)) if ((n = s1->length - s2->length))
return n; // shorter rules first return n; /* shorter rules first */
return strcmp(s1->label, s2->label ? s2->label : s2->label_buf); return strcmp(s1->label, s2->label ? s2->label : s2->label_buf);
} }
@ -217,14 +216,14 @@ static int _suffix_init(_psl_entry_t *suffix, const char *rule, size_t length)
if (length >= sizeof(suffix->label_buf) - 1) { if (length >= sizeof(suffix->label_buf) - 1) {
suffix->nlabels = 0; suffix->nlabels = 0;
// fprintf(stderr, _("Suffix rule too long (%zd, ignored): %s\n"), length, rule); /* fprintf(stderr, _("Suffix rule too long (%zd, ignored): %s\n"), length, rule); */
return -1; return -1;
} }
if (*rule == '*') { if (*rule == '*') {
if (*++rule != '.') { if (*++rule != '.') {
suffix->nlabels = 0; suffix->nlabels = 0;
// fprintf(stderr, _("Unsupported kind of rule (ignored): %s\n"), rule); /* fprintf(stderr, _("Unsupported kind of rule (ignored): %s\n"), rule); */
return -2; return -2;
} }
rule++; rule++;
@ -273,7 +272,7 @@ int psl_is_public_suffix(const psl_ctx_t *psl, const char *domain)
if (!psl || !domain) if (!psl || !domain)
return 1; return 1;
// this function should be called without leading dots, just make sure /* this function should be called without leading dots, just make sure */
suffix.label = domain + (*domain == '.'); suffix.label = domain + (*domain == '.');
suffix.length = strlen(suffix.label); suffix.length = strlen(suffix.label);
suffix.wildcard = 0; suffix.wildcard = 0;
@ -283,7 +282,7 @@ int psl_is_public_suffix(const psl_ctx_t *psl, const char *domain)
if (*p == '.') if (*p == '.')
suffix.nlabels++; suffix.nlabels++;
// if domain has enough labels, it is public /* if domain has enough labels, it is public */
if (psl == &_builtin_psl) if (psl == &_builtin_psl)
rule = &suffixes[0]; rule = &suffixes[0];
else else
@ -298,10 +297,10 @@ int psl_is_public_suffix(const psl_ctx_t *psl, const char *domain)
rule = _vector_get(psl->suffixes, _vector_find(psl->suffixes, &suffix)); rule = _vector_get(psl->suffixes, _vector_find(psl->suffixes, &suffix));
if (rule) { if (rule) {
// definitely a match, no matter if the found rule is a wildcard or not /* definitely a match, no matter if the found rule is a wildcard or not */
return 1; return 1;
} else if (suffix.nlabels == 1) { } else if (suffix.nlabels == 1) {
// unknown TLD, this is the prevailing '*' match /* unknown TLD, this is the prevailing '*' match */
return 1; return 1;
} }
@ -320,17 +319,17 @@ int psl_is_public_suffix(const psl_ctx_t *psl, const char *domain)
if (rule) { if (rule) {
if (rule->wildcard) { if (rule->wildcard) {
// now that we matched a wildcard, we have to check for an exception /* now that we matched a wildcard, we have to check for an exception */
suffix.label = label_bak; suffix.label = label_bak;
suffix.length = length_bak; suffix.length = length_bak;
suffix.nlabels++; suffix.nlabels++;
if (psl == &_builtin_psl) { if (psl == &_builtin_psl) {
if (bsearch(&suffix, suffix_exceptions, countof(suffix_exceptions), sizeof(suffix_exceptions[0]), (int(*)(const void *, const void *))_suffix_compare)) if (bsearch(&suffix, suffix_exceptions, countof(suffix_exceptions), sizeof(suffix_exceptions[0]), (int(*)(const void *, const void *))_suffix_compare))
return 0; // found an exception, so 'domain' is not a public suffix return 0; /* found an exception, so 'domain' is not a public suffix */
} else { } else {
if (_vector_get(psl->suffix_exceptions, _vector_find(psl->suffix_exceptions, &suffix)) != 0) if (_vector_get(psl->suffix_exceptions, _vector_find(psl->suffix_exceptions, &suffix)) != 0)
return 0; // found an exception, so 'domain' is not a public suffix return 0; /* found an exception, so 'domain' is not a public suffix */
} }
return 1; return 1;
@ -362,14 +361,16 @@ const char *psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain)
if (!psl || !domain) if (!psl || !domain)
return NULL; return NULL;
// We check from left to right to catch special PSL entries like 'forgot.his.name': /*
// 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not. * We check from left to right to catch special PSL entries like 'forgot.his.name':
* 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not.
*/
while (!psl_is_public_suffix(psl, domain)) { while (!psl_is_public_suffix(psl, domain)) {
if ((domain = strchr(domain, '.'))) if ((domain = strchr(domain, '.')))
domain++; domain++;
else else
break; // prevent endless loop if psl_is_public_suffix() is broken. break; /* prevent endless loop if psl_is_public_suffix() is broken. */
} }
return domain; return domain;
@ -398,15 +399,17 @@ const char *psl_registrable_domain(const psl_ctx_t *psl, const char *domain)
if (!psl || !domain || *domain == '.') if (!psl || !domain || *domain == '.')
return NULL; return NULL;
// We check from left to right to catch special PSL entries like 'forgot.his.name': /*
// 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not. * We check from left to right to catch special PSL entries like 'forgot.his.name':
* 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not.
*/
while (!psl_is_public_suffix(psl, domain)) { while (!psl_is_public_suffix(psl, domain)) {
if ((p = strchr(domain, '.'))) { if ((p = strchr(domain, '.'))) {
regdom = domain; regdom = domain;
domain = p + 1; domain = p + 1;
} else } else
break; // prevent endless loop if psl_is_public_suffix() is broken. break; /* prevent endless loop if psl_is_public_suffix() is broken. */
} }
return regdom; return regdom;
@ -473,24 +476,26 @@ psl_ctx_t *psl_load_fp(FILE *fp)
if (!(psl = calloc(1, sizeof(psl_ctx_t)))) if (!(psl = calloc(1, sizeof(psl_ctx_t))))
return NULL; return NULL;
// as of 02.11.2012, the list at http://publicsuffix.org/list/ contains ~6000 rules and 40 exceptions. /*
// as of 19.02.2014, the list at http://publicsuffix.org/list/ contains ~6500 rules and 19 exceptions. * as of 02.11.2012, the list at http://publicsuffix.org/list/ contains ~6000 rules and 40 exceptions.
* as of 19.02.2014, the list at http://publicsuffix.org/list/ contains ~6500 rules and 19 exceptions.
*/
psl->suffixes = _vector_alloc(8*1024, _suffix_compare); psl->suffixes = _vector_alloc(8*1024, _suffix_compare);
psl->suffix_exceptions = _vector_alloc(64, _suffix_compare); psl->suffix_exceptions = _vector_alloc(64, _suffix_compare);
while ((linep = fgets(buf, sizeof(buf), fp))) { while ((linep = fgets(buf, sizeof(buf), fp))) {
while (isspace(*linep)) linep++; // ignore leading whitespace while (isspace(*linep)) linep++; /* ignore leading whitespace */
if (!*linep) continue; // skip empty lines if (!*linep) continue; /* skip empty lines */
if (*linep == '/' && linep[1] == '/') if (*linep == '/' && linep[1] == '/')
continue; // skip comments continue; /* skip comments */
// parse suffix rule /* parse suffix rule */
for (p = linep; *linep && !isspace(*linep);) linep++; for (p = linep; *linep && !isspace(*linep);) linep++;
*linep = 0; *linep = 0;
if (*p == '!') { if (*p == '!') {
// add to exceptions /* add to exceptions */
if (_suffix_init(&suffix, p + 1, linep - p - 1) == 0) if (_suffix_init(&suffix, p + 1, linep - p - 1) == 0)
suffixp = _vector_get(psl->suffix_exceptions, _vector_add(psl->suffix_exceptions, &suffix)); suffixp = _vector_get(psl->suffix_exceptions, _vector_add(psl->suffix_exceptions, &suffix));
else else
@ -503,7 +508,7 @@ psl_ctx_t *psl_load_fp(FILE *fp)
} }
if (suffixp) if (suffixp)
suffixp->label = suffixp->label_buf; // set label to changed address suffixp->label = suffixp->label_buf; /* set label to changed address */
nsuffixes++;; nsuffixes++;;
} }
@ -697,17 +702,17 @@ int psl_is_cookie_domain_acceptable(const psl_ctx_t *psl, const char *hostname,
cookie_domain++; cookie_domain++;
if (!strcmp(hostname, cookie_domain)) if (!strcmp(hostname, cookie_domain))
return 1; // an exact match is acceptable (and pretty common) return 1; /* an exact match is acceptable (and pretty common) */
cookie_domain_length = strlen(cookie_domain); cookie_domain_length = strlen(cookie_domain);
hostname_length = strlen(hostname); hostname_length = strlen(hostname);
if (cookie_domain_length >= hostname_length) if (cookie_domain_length >= hostname_length)
return 0; // cookie_domain is too long return 0; /* cookie_domain is too long */
p = hostname + hostname_length - cookie_domain_length; p = hostname + hostname_length - cookie_domain_length;
if (!strcmp(p, cookie_domain) && p[-1] == '.') { if (!strcmp(p, cookie_domain) && p[-1] == '.') {
// OK, cookie_domain matches, but it must be longer than the longest public suffix in 'hostname' /* OK, cookie_domain matches, but it must be longer than the longest public suffix in 'hostname' */
if (!(p = psl_unregistrable_domain(psl, hostname))) if (!(p = psl_unregistrable_domain(psl, hostname)))
return 1; return 1;

View File

@ -39,9 +39,11 @@
#include <ctype.h> #include <ctype.h>
#include <sys/stat.h> #include <sys/stat.h>
//#ifdef WITH_LIBIDN2 /*
//# include <idn2.h> #ifdef WITH_LIBIDN2
//#endif # include <idn2.h>
#endif
*/
#ifdef WITH_BUILTIN #ifdef WITH_BUILTIN
@ -55,19 +57,19 @@ typedef struct {
unsigned short unsigned short
length; length;
unsigned char unsigned char
nlabels, // number of labels nlabels, /* number of labels */
wildcard; // this is a wildcard rule (e.g. *.sapporo.jp) wildcard; /* this is a wildcard rule (e.g. *.sapporo.jp) */
} _psl_entry_t; } _psl_entry_t;
// stripped down version libmget vector routines /* stripped down version libmget vector routines */
typedef struct { typedef struct {
int int
(*cmp)(const _psl_entry_t *, const _psl_entry_t *); // comparison function (*cmp)(const _psl_entry_t *, const _psl_entry_t *); /* comparison function */
_psl_entry_t _psl_entry_t
**entry; // pointer to array of pointers to elements **entry; /* pointer to array of pointers to elements */
int int
max, // allocated elements max, /* allocated elements */
cur; // number of elements in use cur; /* number of elements in use */
} _psl_vector_t; } _psl_vector_t;
struct _psl_ctx_st { struct _psl_ctx_st {
@ -144,17 +146,17 @@ static void _vector_sort(_psl_vector_t *v)
qsort_r(v->entry, v->cur, sizeof(_psl_vector_t *), _compare, v); qsort_r(v->entry, v->cur, sizeof(_psl_vector_t *), _compare, v);
} }
// by this kind of sorting, we can easily see if a domain matches or not (match = supercookie !) /* by this kind of sorting, we can easily see if a domain matches or not (match = supercookie !) */
static int _suffix_compare(const _psl_entry_t *s1, const _psl_entry_t *s2) static int _suffix_compare(const _psl_entry_t *s1, const _psl_entry_t *s2)
{ {
int n; int n;
if ((n = s2->nlabels - s1->nlabels)) if ((n = s2->nlabels - s1->nlabels))
return n; // most labels first return n; /* most labels first */
if ((n = s1->length - s2->length)) if ((n = s1->length - s2->length))
return n; // shorter rules first return n; /* shorter rules first */
return strcmp(s1->label, s2->label); return strcmp(s1->label, s2->label);
} }
@ -168,7 +170,7 @@ static void _suffix_init(_psl_entry_t *suffix, const char *rule, size_t length)
if (length >= sizeof(suffix->label_buf) - 1) { if (length >= sizeof(suffix->label_buf) - 1) {
suffix->nlabels = 0; suffix->nlabels = 0;
fprintf(stderr, "Suffix rule too long (%zd, ignored): %s\n", length, rule); fprintf(stderr, "Suffix rule too long (%d, ignored): %s\n", (int) length, rule);
return; return;
} }
@ -222,24 +224,26 @@ psl_ctx_t *psl_load_fp(FILE *fp)
if (!(psl = calloc(1, sizeof(psl_ctx_t)))) if (!(psl = calloc(1, sizeof(psl_ctx_t))))
return NULL; return NULL;
// as of 02.11.2012, the list at http://publicsuffix.org/list/ contains ~6000 rules and 40 exceptions. /*
// as of 19.02.2014, the list at http://publicsuffix.org/list/ contains ~6500 rules and 19 exceptions. * as of 02.11.2012, the list at http://publicsuffix.org/list/ contains ~6000 rules and 40 exceptions.
* as of 19.02.2014, the list at http://publicsuffix.org/list/ contains ~6500 rules and 19 exceptions.
*/
psl->suffixes = _vector_alloc(8*1024, _suffix_compare); psl->suffixes = _vector_alloc(8*1024, _suffix_compare);
psl->suffix_exceptions = _vector_alloc(64, _suffix_compare); psl->suffix_exceptions = _vector_alloc(64, _suffix_compare);
while ((linep = fgets(buf, sizeof(buf), fp))) { while ((linep = fgets(buf, sizeof(buf), fp))) {
while (isspace(*linep)) linep++; // ignore leading whitespace while (isspace(*linep)) linep++; /* ignore leading whitespace */
if (!*linep) continue; // skip empty lines if (!*linep) continue; /* skip empty lines */
if (*linep == '/' && linep[1] == '/') if (*linep == '/' && linep[1] == '/')
continue; // skip comments continue; /* skip comments */
// parse suffix rule /* parse suffix rule */
for (p = linep; *linep && !isspace(*linep);) linep++; for (p = linep; *linep && !isspace(*linep);) linep++;
*linep = 0; *linep = 0;
if (*p == '!') { if (*p == '!') {
// add to exceptions /* add to exceptions */
_suffix_init(&suffix, p + 1, linep - p - 1); _suffix_init(&suffix, p + 1, linep - p - 1);
suffixp = _vector_get(psl->suffix_exceptions, _vector_add(psl->suffix_exceptions, &suffix)); suffixp = _vector_get(psl->suffix_exceptions, _vector_add(psl->suffix_exceptions, &suffix));
} else { } else {
@ -248,7 +252,7 @@ psl_ctx_t *psl_load_fp(FILE *fp)
} }
if (suffixp) if (suffixp)
suffixp->label = suffixp->label_buf; // set label to changed address suffixp->label = suffixp->label_buf; /* set label to changed address */
nsuffixes++;; nsuffixes++;;
} }
@ -263,14 +267,14 @@ static void _print_psl_entries(FILE *fpout, const _psl_vector_t *v, const char *
{ {
int it; int it;
fprintf(fpout, "// automatically generated by psl2c\n"); fprintf(fpout, "/* automatically generated by psl2c */\n");
fprintf(fpout, "static _psl_entry_t %s[] = {\n", varname); fprintf(fpout, "static _psl_entry_t %s[] = {\n", varname);
for (it = 0; it < v->cur; it++) { for (it = 0; it < v->cur; it++) {
_psl_entry_t *e = _vector_get(v, it); _psl_entry_t *e = _vector_get(v, it);
fprintf(fpout, "\t{ \"%s\", NULL, %hd, %hhd, %hhd },\n", fprintf(fpout, "\t{ \"%s\", NULL, %hd, %d, %d },\n",
e->label_buf, e->length, e->nlabels, e->wildcard); e->label_buf, e->length, (int) e->nlabels, (int) e->wildcard);
} }
fprintf(fpout, "};\n"); fprintf(fpout, "};\n");
@ -296,14 +300,14 @@ static void _add_punycode_if_needed(_psl_vector_t *v)
{ {
int it, n; int it, n;
// do not use 'it < v->cur' since v->cur is changed by _vector_add() ! /* do not use 'it < v->cur' since v->cur is changed by _vector_add() ! */
for (it = 0, n = v->cur; it < n; it++) { for (it = 0, n = v->cur; it < n; it++) {
_psl_entry_t *e = _vector_get(v, it); _psl_entry_t *e = _vector_get(v, it);
if (_str_needs_encoding(e->label_buf)) { if (_str_needs_encoding(e->label_buf)) {
_psl_entry_t suffix, *suffixp; _psl_entry_t suffix, *suffixp;
// the following lines will have GPL3+ license issues /* the following lines will have GPL3+ license issues */
/* char *asc = NULL; /* char *asc = NULL;
int rc; int rc;
@ -317,17 +321,17 @@ static void _add_punycode_if_needed(_psl_vector_t *v)
fprintf(stderr, "toASCII(%s) failed (%d): %s\n", e->label_buf, rc, idn2_strerror(rc)); fprintf(stderr, "toASCII(%s) failed (%d): %s\n", e->label_buf, rc, idn2_strerror(rc));
*/ */
// this is much slower than the libidn2 API but should have no license issues /* this is much slower than the libidn2 API but should have no license issues */
FILE *pp; FILE *pp;
char cmd[16 + strlen(e->label_buf)], lookupname[64] = ""; char cmd[16 + sizeof(e->label_buf)], lookupname[64] = "";
snprintf(cmd, sizeof(cmd), "idn2 '%s'", e->label_buf); snprintf(cmd, sizeof(cmd), "idn2 '%s'", e->label_buf);
if ((pp = popen(cmd, "r"))) { if ((pp = popen(cmd, "r"))) {
if (fscanf(pp, "%63s", lookupname) >= 1 && strcmp(e->label_buf, lookupname)) { if (fscanf(pp, "%63s", lookupname) >= 1 && strcmp(e->label_buf, lookupname)) {
// fprintf(stderr, "idn2 '%s' -> '%s'\n", e->label_buf, lookupname); /* fprintf(stderr, "idn2 '%s' -> '%s'\n", e->label_buf, lookupname); */
_suffix_init(&suffix, lookupname, strlen(lookupname)); _suffix_init(&suffix, lookupname, strlen(lookupname));
suffix.wildcard = e->wildcard; suffix.wildcard = e->wildcard;
suffixp = _vector_get(v, _vector_add(v, &suffix)); suffixp = _vector_get(v, _vector_add(v, &suffix));
suffixp->label = suffixp->label_buf; // set label to changed address suffixp->label = suffixp->label_buf; /* set label to changed address */
} }
pclose(pp); pclose(pp);
} else } else
@ -337,7 +341,7 @@ static void _add_punycode_if_needed(_psl_vector_t *v)
_vector_sort(v); _vector_sort(v);
} }
#endif // WITH_BUILTIN #endif /* WITH_BUILTIN */
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
@ -361,7 +365,7 @@ int main(int argc, const char **argv)
if ((fpout = fopen(argv[2], "w"))) { if ((fpout = fopen(argv[2], "w"))) {
FILE *pp; FILE *pp;
struct stat st; struct stat st;
char cmd[16 + strlen(argv[1])], checksum[64] = ""; char *cmd, checksum[64] = "";
_add_punycode_if_needed(psl->suffixes); _add_punycode_if_needed(psl->suffixes);
_add_punycode_if_needed(psl->suffix_exceptions); _add_punycode_if_needed(psl->suffix_exceptions);
@ -369,11 +373,14 @@ int main(int argc, const char **argv)
_print_psl_entries(fpout, psl->suffixes, "suffixes"); _print_psl_entries(fpout, psl->suffixes, "suffixes");
_print_psl_entries(fpout, psl->suffix_exceptions, "suffix_exceptions"); _print_psl_entries(fpout, psl->suffix_exceptions, "suffix_exceptions");
snprintf(cmd, sizeof(cmd), "sha1sum %s", argv[1]); if ((cmd = malloc(16 + strlen(argv[1])))) {
if ((pp = popen(cmd, "r"))) { snprintf(cmd, 16 + strlen(argv[1]), "sha1sum %s", argv[1]);
if (fscanf(pp, "%63[0-9a-zA-Z]", checksum) < 1) if ((pp = popen(cmd, "r"))) {
*checksum = 0; if (fscanf(pp, "%63[0-9a-zA-Z]", checksum) < 1)
pclose(pp); *checksum = 0;
pclose(pp);
}
free(cmd);
} }
if (stat(argv[1], &st) != 0) if (stat(argv[1], &st) != 0)
@ -407,7 +414,7 @@ int main(int argc, const char **argv)
ret = 3; ret = 3;
} }
#endif // WITH_BUILTIN #endif /* WITH_BUILTIN */
return ret; return ret;
} }

View File

@ -35,6 +35,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <alloca.h>
#include <libpsl.h> #include <libpsl.h>
@ -46,8 +47,6 @@ static int
static void test_psl(void) static void test_psl(void)
{ {
// punycode generation: idn 商标
// octal code generation: echo -n "商标" | od -b
static const struct test_data { static const struct test_data {
const char const char
*request_domain, *request_domain,
@ -65,10 +64,10 @@ static void test_psl(void)
{ "www.his.name", "name", 0 }, { "www.his.name", "name", 0 },
{ "www.example.com", "www.example.com", 1 }, { "www.example.com", "www.example.com", 1 },
{ "www.example.com", "example.com", 1 }, { "www.example.com", "example.com", 1 },
{ "www.example.com", "com", 0 }, // not accepted by normalization (PSL rule 'com') { "www.example.com", "com", 0 }, /* not accepted by normalization (PSL rule 'com') */
{ "www.example.com", "example.org", 0 }, { "www.example.com", "example.org", 0 },
{ "www.sa.gov.au", "sa.gov.au", 0 }, // not accepted by normalization (PSL rule '*.ar') { "www.sa.gov.au", "sa.gov.au", 0 }, /* not accepted by normalization (PSL rule '*.ar') */
{ "www.educ.ar", "educ.ar", 1 }, // PSL exception rule '!educ.ar' { "www.educ.ar", "educ.ar", 1 }, /* PSL exception rule '!educ.ar' */
}; };
unsigned it; unsigned it;
psl_ctx_t *psl; psl_ctx_t *psl;
@ -95,14 +94,15 @@ static void test_psl(void)
int main(int argc, const char * const *argv) int main(int argc, const char * const *argv)
{ {
// if VALGRIND testing is enabled, we have to call ourselves with valgrind checking /* if VALGRIND testing is enabled, we have to call ourselves with valgrind checking */
if (argc == 1) { if (argc == 1) {
const char *valgrind = getenv("TESTS_VALGRIND"); const char *valgrind = getenv("TESTS_VALGRIND");
if (valgrind && *valgrind) { if (valgrind && *valgrind) {
char cmd[strlen(valgrind)+strlen(argv[0])+32]; size_t cmdsize = strlen(valgrind) + strlen(argv[0]) + 32;
char *cmd = alloca(cmdsize);
snprintf(cmd, sizeof(cmd), "TESTS_VALGRIND="" %s %s", valgrind, argv[0]); snprintf(cmd, cmdsize, "TESTS_VALGRIND="" %s %s", valgrind, argv[0]);
return system(cmd) != 0; return system(cmd) != 0;
} }
} }

View File

@ -36,6 +36,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <alloca.h>
#include <libpsl.h> #include <libpsl.h>
@ -50,23 +51,23 @@ static void test_psl(void)
int result; int result;
char buf[256], domain[64], *linep, *p; char buf[256], domain[64], *linep, *p;
psl = psl_load_file(PSL_FILE); // PSL_FILE can be set by ./configure --with-psl-file=[PATH] 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)); printf("loaded %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl));
if ((fp = fopen(PSL_FILE, "r"))) { if ((fp = fopen(PSL_FILE, "r"))) {
while ((linep = fgets(buf, sizeof(buf), fp))) { while ((linep = fgets(buf, sizeof(buf), fp))) {
while (isspace(*linep)) linep++; // ignore leading whitespace while (isspace(*linep)) linep++; /* ignore leading whitespace */
if (!*linep) continue; // skip empty lines if (!*linep) continue; /* skip empty lines */
if (*linep == '/' && linep[1] == '/') if (*linep == '/' && linep[1] == '/')
continue; // skip comments continue; /* skip comments */
// parse suffix rule /* parse suffix rule */
for (p = linep; *linep && !isspace(*linep);) linep++; for (p = linep; *linep && !isspace(*linep);) linep++;
*linep = 0; *linep = 0;
if (*p == '!') { // an exception to a wildcard, e.g. !www.ck (wildcard is *.ck) if (*p == '!') { /* an exception to a wildcard, e.g. !www.ck (wildcard is *.ck) */
if ((result = psl_is_public_suffix(psl, p + 1))) { if ((result = psl_is_public_suffix(psl, p + 1))) {
failed++; failed++;
printf("psl_is_public_suffix(%s)=%d (expected 0)\n", p, result); printf("psl_is_public_suffix(%s)=%d (expected 0)\n", p, result);
@ -77,7 +78,7 @@ static void test_psl(void)
printf("psl_is_public_suffix(%s)=%d (expected 1)\n", strchr(p, '.') + 1, result); printf("psl_is_public_suffix(%s)=%d (expected 1)\n", strchr(p, '.') + 1, result);
} else ok++; } else ok++;
} }
else if (*p == '*') { // a wildcard, e.g. *.ck else if (*p == '*') { /* a wildcard, e.g. *.ck */
if (!(result = psl_is_public_suffix(psl, p + 1))) { if (!(result = psl_is_public_suffix(psl, p + 1))) {
failed++; failed++;
printf("psl_is_public_suffix(%s)=%d (expected 1)\n", p + 1, result); printf("psl_is_public_suffix(%s)=%d (expected 1)\n", p + 1, result);
@ -114,14 +115,15 @@ static void test_psl(void)
int main(int argc, const char * const *argv) int main(int argc, const char * const *argv)
{ {
// if VALGRIND testing is enabled, we have to call ourselves with valgrind checking /* if VALGRIND testing is enabled, we have to call ourselves with valgrind checking */
if (argc == 1) { if (argc == 1) {
const char *valgrind = getenv("TESTS_VALGRIND"); const char *valgrind = getenv("TESTS_VALGRIND");
if (valgrind && *valgrind) { if (valgrind && *valgrind) {
char cmd[strlen(valgrind) + strlen(argv[0]) + 32]; size_t cmdsize = strlen(valgrind) + strlen(argv[0]) + 32;
char *cmd = alloca(cmdsize);
snprintf(cmd, sizeof(cmd), "TESTS_VALGRIND="" %s %s", valgrind, argv[0]); snprintf(cmd, cmdsize, "TESTS_VALGRIND="" %s %s", valgrind, argv[0]);
return system(cmd) != 0; return system(cmd) != 0;
} }
} }

View File

@ -35,6 +35,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <alloca.h>
#include <libpsl.h> #include <libpsl.h>
@ -46,8 +47,8 @@ static int
static void test_psl(void) static void test_psl(void)
{ {
// punycode generation: idn 商标 /* punycode generation: idn 商标 */
// octal code generation: echo -n "商标" | od -b /* octal code generation: echo -n "商标" | od -b */
static const struct test_data { static const struct test_data {
const char const char
*domain; *domain;
@ -60,15 +61,15 @@ static void test_psl(void)
{ "cc.ar.us", 1 }, { "cc.ar.us", 1 },
{ ".cc.ar.us", 1 }, { ".cc.ar.us", 1 },
{ "www.cc.ar.us", 0 }, { "www.cc.ar.us", 0 },
{ "www.ck", 0 }, // exception from *.ck { "www.ck", 0 }, /* exception from *.ck */
{ "abc.www.ck", 0 }, { "abc.www.ck", 0 },
{ "xxx.ck", 1 }, { "xxx.ck", 1 },
{ "www.xxx.ck", 0 }, { "www.xxx.ck", 0 },
{ "\345\225\206\346\240\207", 1 }, // xn--czr694b oder 商标 { "\345\225\206\346\240\207", 1 }, /* xn--czr694b oder 商标 */
{ "www.\345\225\206\346\240\207", 0 }, { "www.\345\225\206\346\240\207", 0 },
{ "xn--czr694b", 1 }, { "xn--czr694b", 1 },
{ "www.xn--czr694b", 0 }, { "www.xn--czr694b", 0 },
// some special test follow ('name' and 'forgot.his.name' are public, but e.g. his.name is not) /* some special test follow ('name' and 'forgot.his.name' are public, but e.g. his.name is not) */
{ "name", 1 }, { "name", 1 },
{ ".name", 1 }, { ".name", 1 },
{ "his.name", 0 }, { "his.name", 0 },
@ -109,14 +110,15 @@ static void test_psl(void)
int main(int argc, const char * const *argv) int main(int argc, const char * const *argv)
{ {
// if VALGRIND testing is enabled, we have to call ourselves with valgrind checking /* if VALGRIND testing is enabled, we have to call ourselves with valgrind checking */
if (argc == 1) { if (argc == 1) {
const char *valgrind = getenv("TESTS_VALGRIND"); const char *valgrind = getenv("TESTS_VALGRIND");
if (valgrind && *valgrind) { if (valgrind && *valgrind) {
char cmd[strlen(valgrind)+strlen(argv[0])+32]; size_t cmdsize = strlen(valgrind) + strlen(argv[0]) + 32;
char *cmd = alloca(cmdsize);
snprintf(cmd, sizeof(cmd), "TESTS_VALGRIND="" %s %s", valgrind, argv[0]); snprintf(cmd, cmdsize, "TESTS_VALGRIND="" %s %s", valgrind, argv[0]);
return system(cmd) != 0; return system(cmd) != 0;
} }
} }

View File

@ -35,6 +35,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <alloca.h>
#include <libpsl.h> #include <libpsl.h>
@ -46,8 +47,8 @@ static int
static void test_psl(void) static void test_psl(void)
{ {
// punycode generation: idn 商标 /* punycode generation: idn 商标 */
// octal code generation: echo -n "商标" | od -b /* octal code generation: echo -n "商标" | od -b */
static const struct test_data { static const struct test_data {
const char const char
*domain; *domain;
@ -60,13 +61,13 @@ static void test_psl(void)
{ "cc.ar.us", 1 }, { "cc.ar.us", 1 },
{ ".cc.ar.us", 1 }, { ".cc.ar.us", 1 },
{ "www.cc.ar.us", 0 }, { "www.cc.ar.us", 0 },
{ "www.ck", 0 }, // exception from *.ck { "www.ck", 0 }, /* exception from *.ck */
{ "abc.www.ck", 0 }, { "abc.www.ck", 0 },
{ "xxx.ck", 1 }, { "xxx.ck", 1 },
{ "www.xxx.ck", 0 }, { "www.xxx.ck", 0 },
{ "\345\225\206\346\240\207", 1 }, // xn--czr694b oder 商标 { "\345\225\206\346\240\207", 1 }, /* xn--czr694b oder 商标 */
{ "www.\345\225\206\346\240\207", 0 }, { "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) /* some special test follow ('name' and 'forgot.his.name' are public, but e.g. his.name is not) */
{ "name", 1 }, { "name", 1 },
{ ".name", 1 }, { ".name", 1 },
{ "his.name", 0 }, { "his.name", 0 },
@ -100,14 +101,15 @@ static void test_psl(void)
int main(int argc, const char * const *argv) int main(int argc, const char * const *argv)
{ {
// if VALGRIND testing is enabled, we have to call ourselves with valgrind checking /* if VALGRIND testing is enabled, we have to call ourselves with valgrind checking */
if (argc == 1) { if (argc == 1) {
const char *valgrind = getenv("TESTS_VALGRIND"); const char *valgrind = getenv("TESTS_VALGRIND");
if (valgrind && *valgrind) { if (valgrind && *valgrind) {
char cmd[strlen(valgrind)+strlen(argv[0])+32]; size_t cmdsize = strlen(valgrind) + strlen(argv[0]) + 32;
char *cmd = alloca(cmdsize);
snprintf(cmd, sizeof(cmd), "TESTS_VALGRIND="" %s %s", valgrind, argv[0]); snprintf(cmd, cmdsize, "TESTS_VALGRIND="" %s %s", valgrind, argv[0]);
return system(cmd) != 0; return system(cmd) != 0;
} }
} }

View File

@ -36,6 +36,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <alloca.h>
#include <libpsl.h> #include <libpsl.h>
@ -48,7 +49,7 @@ static void test(const psl_ctx_t *psl, const char *domain, const char *expected_
const char *result; const char *result;
char lookupname[128]; char lookupname[128];
// check if there might be some utf-8 characters /* check if there might be some utf-8 characters */
if (domain) { if (domain) {
int utf8; int utf8;
const char *p; const char *p;
@ -57,13 +58,14 @@ static void test(const psl_ctx_t *psl, const char *domain, const char *expected_
if (*p < 0) if (*p < 0)
utf8 = 1; utf8 = 1;
// if we found utf-8, make sure to convert domain correctly to lowercase /* if we found utf-8, make sure to convert domain correctly to lowercase */
// does it work, if we are not in a utf-8 env ? /* does it work, if we are not in a utf-8 env ? */
if (utf8) { if (utf8) {
FILE *pp; FILE *pp;
char cmd[48 + strlen(domain)]; size_t cmdsize = 48 + strlen(domain);
char *cmd = alloca(cmdsize);
snprintf(cmd, sizeof(cmd), "echo -n '%s' | sed -e 's/./\\L\\0/g'", domain); snprintf(cmd, cmdsize, "echo -n '%s' | sed -e 's/./\\L\\0/g'", domain);
if ((pp = popen(cmd, "r"))) { if ((pp = popen(cmd, "r"))) {
if (fscanf(pp, "%127s", lookupname) >= 1) if (fscanf(pp, "%127s", lookupname) >= 1)
domain = lookupname; domain = lookupname;
@ -93,28 +95,28 @@ static void test_psl(void)
printf("have %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl)); printf("have %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl));
// special check with NULL values /* special check with NULL values */
test(NULL, NULL, NULL); test(NULL, NULL, NULL);
// special check with NULL psl context /* special check with NULL psl context */
test(NULL, "www.example.com", NULL); test(NULL, "www.example.com", NULL);
// special check with NULL psl context and TLD /* special check with NULL psl context and TLD */
test(NULL, "com", NULL); test(NULL, "com", NULL);
// Norwegian with uppercase oe /* Norwegian with uppercase oe */
test(psl, "www.\303\230yer.no", "www.\303\270yer.no"); test(psl, "www.\303\230yer.no", "www.\303\270yer.no");
// Norwegian with lowercase oe /* Norwegian with lowercase oe */
test(psl, "www.\303\270yer.no", "www.\303\270yer.no"); test(psl, "www.\303\270yer.no", "www.\303\270yer.no");
// special check with NULL psl context and TLD /* special check with NULL psl context and TLD */
test(psl, "whoever.forgot.his.name", "whoever.forgot.his.name"); test(psl, "whoever.forgot.his.name", "whoever.forgot.his.name");
// special check with NULL psl context and TLD /* special check with NULL psl context and TLD */
test(psl, "forgot.his.name", NULL); test(psl, "forgot.his.name", NULL);
// special check with NULL psl context and TLD /* special check with NULL psl context and TLD */
test(psl, "his.name", "his.name"); test(psl, "his.name", "his.name");
if ((fp = fopen(PSL_TESTFILE, "r"))) { if ((fp = fopen(PSL_TESTFILE, "r"))) {
@ -124,7 +126,7 @@ static void test_psl(void)
continue; continue;
} }
// we have to lowercase the domain - the PSL API just takes lowercase /* we have to lowercase the domain - the PSL API just takes lowercase */
for (p = domain; *p; p++) for (p = domain; *p; p++)
if (*p > 0 && isupper(*p)) if (*p > 0 && isupper(*p))
*p = tolower(*p); *p = tolower(*p);
@ -144,14 +146,15 @@ static void test_psl(void)
int main(int argc, const char * const *argv) int main(int argc, const char * const *argv)
{ {
// if VALGRIND testing is enabled, we have to call ourselves with valgrind checking /* if VALGRIND testing is enabled, we have to call ourselves with valgrind checking */
if (argc == 1) { if (argc == 1) {
const char *valgrind = getenv("TESTS_VALGRIND"); const char *valgrind = getenv("TESTS_VALGRIND");
if (valgrind && *valgrind) { if (valgrind && *valgrind) {
char cmd[strlen(valgrind) + strlen(argv[0]) + 32]; size_t cmdsize = strlen(valgrind) + strlen(argv[0]) + 32;
char *cmd = alloca(cmdsize);
snprintf(cmd, sizeof(cmd), "TESTS_VALGRIND="" %s %s", valgrind, argv[0]); snprintf(cmd, cmdsize, "TESTS_VALGRIND="" %s %s", valgrind, argv[0]);
return system(cmd) != 0; return system(cmd) != 0;
} }
} }

View File

@ -54,12 +54,13 @@ static void usage(int err)
exit(err); exit(err);
} }
/* RFC 2822-compliant date format */
static const char *time2str(time_t t) static const char *time2str(time_t t)
{ {
static char buf[64]; static char buf[64];
struct tm *tp = localtime(&t); struct tm *tp = localtime(&t);
strftime(buf, sizeof(buf), "%a, %d %b %Y %T %z", tp); strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %Z", tp);
return buf; return buf;
} }