2014-03-26 22:27:31 +01:00
|
|
|
/*
|
2018-02-22 10:03:37 +01:00
|
|
|
* Copyright(c) 2014-2018 Tim Ruehsen
|
2014-03-26 22:27:31 +01:00
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
* This file is part of the test suite of libpsl.
|
|
|
|
*
|
|
|
|
* Test psl_registered_domain() for all entries in test_psl.dat
|
|
|
|
*
|
|
|
|
* Changelog
|
|
|
|
* 26.03.2014 Tim Ruehsen created
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2014-10-28 15:41:35 +01:00
|
|
|
#ifdef HAVE_ALLOCA_H
|
|
|
|
# include <alloca.h>
|
|
|
|
#endif
|
2014-03-26 22:27:31 +01:00
|
|
|
|
|
|
|
#include <libpsl.h>
|
|
|
|
|
|
|
|
static int
|
|
|
|
ok,
|
|
|
|
failed;
|
|
|
|
|
2016-09-23 11:12:52 +02:00
|
|
|
static void testx(const psl_ctx_t *psl, const char *domain, const char *encoding, const char *lang, const char *expected_result)
|
2014-03-27 12:32:35 +01:00
|
|
|
{
|
2014-03-27 21:29:17 +01:00
|
|
|
const char *result;
|
2016-12-05 16:28:39 +01:00
|
|
|
char *lower = NULL;
|
2016-09-23 11:12:52 +02:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
/* just to cover special code paths for valgrind checking */
|
|
|
|
psl_str_to_utf8lower(domain, encoding, lang, NULL);
|
2014-03-27 21:29:17 +01:00
|
|
|
|
2016-09-23 11:12:52 +02:00
|
|
|
if ((rc = psl_str_to_utf8lower(domain, encoding, lang, &lower)) == PSL_SUCCESS)
|
2014-06-17 17:14:02 +02:00
|
|
|
domain = lower;
|
2016-09-23 11:12:52 +02:00
|
|
|
/* non-ASCII domains fail here if no runtime IDN library is configured, so skip it */
|
|
|
|
#if defined(WITH_LIBIDN) || defined(WITH_LIBIDN2) || defined(WITH_LIBICU)
|
|
|
|
else if (domain) {
|
|
|
|
/* if we do not runtime support, test failure have to be skipped */
|
|
|
|
failed++;
|
|
|
|
printf("psl_str_to_utf8lower(%s)=%d\n", domain ? domain : "NULL", rc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
2014-03-27 21:29:17 +01:00
|
|
|
|
|
|
|
result = psl_registrable_domain(psl, domain);
|
2014-03-27 12:32:35 +01:00
|
|
|
|
|
|
|
if ((result && expected_result && !strcmp(result, expected_result)) || (!result && !expected_result)) {
|
|
|
|
ok++;
|
|
|
|
} else {
|
|
|
|
failed++;
|
|
|
|
printf("psl_registrable_domain(%s)=%s (expected %s)\n",
|
2015-08-14 00:02:11 +02:00
|
|
|
domain ? domain : "NULL", result ? result : "NULL", expected_result ? expected_result : "NULL");
|
2014-03-27 12:32:35 +01:00
|
|
|
}
|
2014-06-18 12:25:06 +02:00
|
|
|
|
2017-08-29 19:32:47 +02:00
|
|
|
psl_free_string(lower);
|
2014-03-27 12:32:35 +01:00
|
|
|
}
|
|
|
|
|
2016-09-23 11:12:52 +02:00
|
|
|
static void test(const psl_ctx_t *psl, const char *domain, const char *expected_result)
|
|
|
|
{
|
|
|
|
testx(psl, domain, "utf-8", "en", expected_result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_iso(const psl_ctx_t *psl, const char *domain, const char *expected_result)
|
|
|
|
{
|
|
|
|
/* makes only sense with a runtime IDN library configured */
|
|
|
|
#if defined(WITH_LIBIDN) || defined(WITH_LIBIDN2) || defined(WITH_LIBICU)
|
|
|
|
testx(psl, domain, "iso-8859-15", "de", expected_result);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-03-26 22:27:31 +01:00
|
|
|
static void test_psl(void)
|
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
const psl_ctx_t *psl;
|
2015-08-14 12:27:11 +02:00
|
|
|
const char *p;
|
2015-08-14 00:02:11 +02:00
|
|
|
char buf[256], domain[128], expected_regdom[128], semicolon[2];
|
2016-09-23 11:12:52 +02:00
|
|
|
char lbuf[258];
|
2015-08-14 00:02:11 +02:00
|
|
|
int er_is_null, d_is_null;
|
2016-09-23 11:12:52 +02:00
|
|
|
unsigned it;
|
2014-03-26 22:27:31 +01:00
|
|
|
|
|
|
|
psl = psl_builtin();
|
|
|
|
|
|
|
|
printf("have %d suffixes and %d exceptions\n", psl_suffix_count(psl), psl_suffix_exception_count(psl));
|
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* special check with NULL values */
|
2014-03-27 12:32:35 +01:00
|
|
|
test(NULL, NULL, NULL);
|
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* special check with NULL psl context */
|
2014-03-27 12:32:35 +01:00
|
|
|
test(NULL, "www.example.com", NULL);
|
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* special check with NULL psl context and TLD */
|
2014-03-27 12:32:35 +01:00
|
|
|
test(NULL, "com", NULL);
|
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* Norwegian with uppercase oe */
|
2014-06-18 15:20:48 +02:00
|
|
|
#ifdef WITH_LIBICU
|
2014-03-27 21:29:17 +01:00
|
|
|
test(psl, "www.\303\230yer.no", "www.\303\270yer.no");
|
2014-06-18 15:20:48 +02:00
|
|
|
#endif
|
2014-03-27 12:32:35 +01:00
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* Norwegian with lowercase oe */
|
2014-03-27 12:32:35 +01:00
|
|
|
test(psl, "www.\303\270yer.no", "www.\303\270yer.no");
|
|
|
|
|
2016-09-23 11:12:52 +02:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* special check with NULL psl context and TLD */
|
2014-04-16 10:53:59 +02:00
|
|
|
test(psl, "whoever.forgot.his.name", "whoever.forgot.his.name");
|
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* special check with NULL psl context and TLD */
|
2014-04-16 10:53:59 +02:00
|
|
|
test(psl, "forgot.his.name", NULL);
|
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
/* special check with NULL psl context and TLD */
|
2014-04-16 10:53:59 +02:00
|
|
|
test(psl, "his.name", "his.name");
|
|
|
|
|
2014-04-13 16:43:03 +02:00
|
|
|
if ((fp = fopen(PSL_TESTFILE, "r"))) {
|
2014-03-26 22:27:31 +01:00
|
|
|
while ((fgets(buf, sizeof(buf), fp))) {
|
2015-08-14 12:27:11 +02:00
|
|
|
/* advance over ASCII white space */
|
|
|
|
for (p = buf; *p == ' ' || *p == '\t' || *p == '\r' || *p == '\n'; p++)
|
|
|
|
;
|
|
|
|
|
|
|
|
if (!*p || (*p == '/' && p[1] == '/'))
|
2015-08-14 00:02:11 +02:00
|
|
|
continue; /* ignore comments and blank lines */
|
2015-08-14 12:27:11 +02:00
|
|
|
|
2015-08-14 00:02:11 +02:00
|
|
|
er_is_null = 0;
|
|
|
|
d_is_null = 0;
|
2015-08-14 12:27:11 +02:00
|
|
|
|
|
|
|
if (sscanf(p, "checkPublicSuffix ( '%127[^']' , '%127[^']' ) %1[;]", domain, expected_regdom, semicolon) != 3) {
|
|
|
|
if (sscanf(p, "checkPublicSuffix ( '%127[^']' , null ) %1[;]", domain, semicolon) == 2) {
|
2015-08-14 00:02:11 +02:00
|
|
|
er_is_null = 1;
|
2015-08-14 12:27:11 +02:00
|
|
|
} else if (sscanf(p, "checkPublicSuffix ( null , '%127[^']' ) %1[;]", expected_regdom, semicolon) == 2) {
|
2015-08-14 00:02:11 +02:00
|
|
|
d_is_null = 1;
|
2015-08-14 12:27:11 +02:00
|
|
|
} else if (sscanf(p, "checkPublicSuffix ( null , null ) %1[;]", semicolon) == 1) {
|
2015-08-14 00:02:11 +02:00
|
|
|
d_is_null = 1;
|
|
|
|
er_is_null = 1;
|
2016-02-20 15:06:48 +01:00
|
|
|
} 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;
|
2015-08-14 00:02:11 +02:00
|
|
|
} else {
|
|
|
|
failed++;
|
2015-08-14 12:27:11 +02:00
|
|
|
printf("Malformed line from '" PSL_TESTFILE "': %s", buf);
|
2014-03-26 22:27:31 +01:00
|
|
|
continue;
|
2015-08-14 00:02:11 +02:00
|
|
|
}
|
2014-03-26 22:27:31 +01:00
|
|
|
}
|
|
|
|
|
2015-08-14 00:02:11 +02:00
|
|
|
test(psl, d_is_null ? NULL : domain, er_is_null ? NULL : expected_regdom);
|
2014-03-26 22:27:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
} else {
|
2014-04-13 16:43:03 +02:00
|
|
|
printf("Failed to open %s\n", PSL_TESTFILE);
|
2014-03-26 22:27:31 +01:00
|
|
|
failed++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, const char * const *argv)
|
|
|
|
{
|
2014-05-12 12:20:59 +02:00
|
|
|
/* if VALGRIND testing is enabled, we have to call ourselves with valgrind checking */
|
2014-03-26 22:27:31 +01:00
|
|
|
if (argc == 1) {
|
|
|
|
const char *valgrind = getenv("TESTS_VALGRIND");
|
|
|
|
|
|
|
|
if (valgrind && *valgrind) {
|
2014-05-12 12:20:59 +02:00
|
|
|
size_t cmdsize = strlen(valgrind) + strlen(argv[0]) + 32;
|
|
|
|
char *cmd = alloca(cmdsize);
|
2014-03-26 22:27:31 +01:00
|
|
|
|
2014-05-12 12:20:59 +02:00
|
|
|
snprintf(cmd, cmdsize, "TESTS_VALGRIND="" %s %s", valgrind, argv[0]);
|
2014-03-26 22:27:31 +01:00
|
|
|
return system(cmd) != 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test_psl();
|
2014-03-30 17:02:56 +02:00
|
|
|
|
2014-03-26 22:27:31 +01:00
|
|
|
if (failed) {
|
|
|
|
printf("Summary: %d out of %d tests failed\n", failed, ok + failed);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("Summary: All %d tests passed\n", ok + failed);
|
|
|
|
return 0;
|
|
|
|
}
|