LLVMFuzzerTestOneInput:
   43|    281|{
   44|    281|#ifdef HAVE_FMEMOPEN
   45|    281|	FILE *fp;
   46|    281|	psl_ctx_t *psl;
   47|    281|	char *in = (char *) malloc(size + 16);
   48|       |
   49|    281|	assert(in != NULL);
   50|       |
   51|       |	/* create a valid DAFSA input file */
   52|      0|	memcpy(in, ".DAFSA@PSL_0   \n", 16);
   53|    281|	memcpy(in + 16, data, size);
   54|       |
   55|    281|	fp = fmemopen(in, size + 16, "r");
   56|    281|	assert(fp != NULL);
   57|       |
   58|      0|	psl = psl_load_fp(fp);
   59|       |
   60|    281|	psl_is_public_suffix(NULL, NULL);
   61|    281|	psl_is_public_suffix(psl, ".ü.com");
   62|    281|	psl_suffix_wildcard_count(psl);
   63|    281|	psl_suffix_exception_count(psl);
   64|    281|	psl_suffix_count(psl);
   65|       |
   66|    281|	psl_free(psl);
   67|    281|	fclose(fp);
   68|       |
   69|    281|	psl = psl_latest(NULL);
   70|    281|	psl_free(psl);
   71|       |
   72|    281|	free(in);
   73|    281|#endif
   74|       |
   75|    281|	return 0;
   76|    281|}

LookupStringInFixedSet:
  200|    556|{
  201|    556|	const unsigned char* pos = graph;
  202|    556|	const unsigned char* end = graph + length;
  203|    556|	const unsigned char* offset = pos;
  204|    556|	const char* key_end = key + key_length;
  205|    556|	const char* multibyte_start = 0;
  206|       |
  207|  20.7k|	while (GetNextOffset(&pos, end, &offset)) {
  ------------------
  |  Branch (207:9): [True: 20.3k, False: 447]
  ------------------
  208|       |		/*char <char>+ end_char offsets
  209|       |		 * char <char>+ return value
  210|       |		 * char end_char offsets
  211|       |		 * char return value
  212|       |		 * end_char offsets
  213|       |		 * return_value
  214|       |		 */
  215|  20.3k|		int did_consume = 0;
  216|       |
  217|  20.3k|		if (key != key_end && !IsEOL(offset, end)) {
  ------------------
  |  Branch (217:7): [True: 13.3k, False: 7.03k]
  |  Branch (217:25): [True: 12.1k, False: 1.13k]
  ------------------
  218|       |			/* Leading <char> is not a match. Don't dive into this child */
  219|  12.1k|			if (!IsMatch(offset, end, key, multibyte_start))
  ------------------
  |  Branch (219:8): [True: 11.9k, False: 179]
  ------------------
  220|  11.9k|				continue;
  221|    179|			did_consume = 1;
  222|    179|			NextPos(&offset, &key, &multibyte_start);
  223|       |			/* Possible matches at this point:
  224|       |			 * <char>+ end_char offsets
  225|       |			 * <char>+ return value
  226|       |			 * end_char offsets
  227|       |			 * return value
  228|       |			 */
  229|       |
  230|       |			/* Remove all remaining <char> nodes possible */
  231|    361|			while (!IsEOL(offset, end) && key != key_end) {
  ------------------
  |  Branch (231:11): [True: 239, False: 122]
  |  Branch (231:34): [True: 231, False: 8]
  ------------------
  232|    231|				if (!IsMatch(offset, end, key, multibyte_start))
  ------------------
  |  Branch (232:9): [True: 49, False: 182]
  ------------------
  233|     49|					return -1;
  234|    182|				NextPos(&offset, &key, &multibyte_start);
  235|    182|			}
  236|    179|		}
  237|       |		/* Possible matches at this point:
  238|       |		 * end_char offsets
  239|       |		 * return_value
  240|       |		 * If one or more <char> elements were consumed, a failure
  241|       |		 * to match is terminal. Otherwise, try the next node.
  242|       |		 */
  243|  8.30k|		if (key == key_end) {
  ------------------
  |  Branch (243:7): [True: 7.05k, False: 1.24k]
  ------------------
  244|  7.05k|			int return_value;
  245|       |
  246|  7.05k|			if (GetReturnValue(offset, end, multibyte_start, &return_value))
  ------------------
  |  Branch (246:8): [True: 14, False: 7.04k]
  ------------------
  247|     14|				return return_value;
  248|       |			/* The DAFSA guarantees that if the first char is a match, all
  249|       |			 * remaining char elements MUST match if the key is truly present.
  250|       |			 */
  251|  7.04k|			if (did_consume)
  ------------------
  |  Branch (251:8): [True: 11, False: 7.03k]
  ------------------
  252|     11|				return -1;
  253|  7.03k|			continue;
  254|  7.04k|		}
  255|  1.24k|		if (!IsEndCharMatch(offset, end, key, multibyte_start)) {
  ------------------
  |  Branch (255:7): [True: 1.10k, False: 139]
  ------------------
  256|  1.10k|			if (did_consume)
  ------------------
  |  Branch (256:8): [True: 35, False: 1.07k]
  ------------------
  257|     35|				return -1; /* Unexpected */
  258|  1.07k|			continue;
  259|  1.10k|		}
  260|    139|		NextPos(&offset, &key, &multibyte_start);
  261|    139|		pos = offset; /* Dive into child */
  262|    139|	}
  263|       |
  264|    447|	return -1; /* No match */
  265|    556|}
GetUtfMode:
  271|    281|{
  272|    281|	return length > 0 && graph[length - 1] < 0x80;
  ------------------
  |  Branch (272:9): [True: 281, False: 0]
  |  Branch (272:23): [True: 212, False: 69]
  ------------------
  273|    281|}
lookup_string_in_fixed_set.c:GetNextOffset:
   62|  20.7k|{
   63|  20.7k|	size_t bytes_consumed;
   64|       |
   65|  20.7k|	if (*pos == end)
  ------------------
  |  Branch (65:6): [True: 211, False: 20.5k]
  ------------------
   66|    211|		return 0;
   67|       |
   68|       |	/* When reading an offset the byte array must always contain at least
   69|       |	 * three more bytes to consume. First the offset to read, then a node
   70|       |	 * to skip over and finally a destination node. No object can be smaller
   71|       |	 * than one byte. */
   72|  20.5k|	CHECK_LT(*pos + 2, end);
  ------------------
  |  |   10|  20.5k|#define CHECK_LT(a, b) if ((a) >= b) return 0
  |  |  ------------------
  |  |  |  Branch (10:28): [True: 236, False: 20.3k]
  |  |  ------------------
  ------------------
   73|  20.3k|	switch (**pos & 0x60) {
   74|    271|	case 0x60: /* Read three byte offset */
  ------------------
  |  Branch (74:2): [True: 271, False: 20.0k]
  ------------------
   75|    271|		*offset += (((*pos)[0] & 0x1F) << 16) | ((*pos)[1] << 8) | (*pos)[2];
   76|    271|		bytes_consumed = 3;
   77|    271|		break;
   78|    655|	case 0x40: /* Read two byte offset */
  ------------------
  |  Branch (78:2): [True: 655, False: 19.6k]
  ------------------
   79|    655|		*offset += (((*pos)[0] & 0x1F) << 8) | (*pos)[1];
   80|    655|		bytes_consumed = 2;
   81|    655|		break;
   82|  19.4k|	default:
  ------------------
  |  Branch (82:2): [True: 19.4k, False: 926]
  ------------------
   83|  19.4k|		*offset += (*pos)[0] & 0x3F;
   84|  19.4k|		bytes_consumed = 1;
   85|  20.3k|	}
   86|  20.3k|	if ((**pos & 0x80) != 0) {
  ------------------
  |  Branch (86:6): [True: 280, False: 20.0k]
  ------------------
   87|    280|		*pos = end;
   88|  20.0k|	} else {
   89|  20.0k|		*pos += bytes_consumed;
   90|  20.0k|	}
   91|  20.3k|	return 1;
   92|  20.3k|}
lookup_string_in_fixed_set.c:IsEOL:
   99|  13.6k|{
  100|  13.6k|	CHECK_LT(offset, end);
  ------------------
  |  |   10|  13.6k|#define CHECK_LT(a, b) if ((a) >= b) return 0
  |  |  ------------------
  |  |  |  Branch (10:28): [True: 8.47k, False: 5.19k]
  |  |  ------------------
  ------------------
  101|  5.19k|	return(*offset & 0x80) != 0;
  102|  13.6k|}
lookup_string_in_fixed_set.c:IsMatch:
  142|  12.4k|{
  143|  12.4k|	CHECK_LT(offset, end);
  ------------------
  |  |   10|  12.4k|#define CHECK_LT(a, b) if ((a) >= b) return 0
  |  |  ------------------
  |  |  |  Branch (10:28): [True: 8.47k, False: 3.93k]
  |  |  ------------------
  ------------------
  144|  3.93k|	return IsMatchUnchecked(*offset, key, multibyte_start);
  145|  12.4k|}
lookup_string_in_fixed_set.c:IsMatchUnchecked:
  112|  5.17k|{
  113|  5.17k|	if (multibyte_start) {
  ------------------
  |  Branch (113:6): [True: 943, False: 4.23k]
  ------------------
  114|       |		/* Multibyte matching mode. */
  115|    943|		if (multibyte_start == key) {
  ------------------
  |  Branch (115:7): [True: 519, False: 424]
  ------------------
  116|       |			/* Match leading byte, which will also match the sequence length. */
  117|    519|			return (matcher ^ 0x80) == (const unsigned char)*key;
  118|    519|		} else {
  119|       |			/* Match following bytes. */
  120|    424|			return (matcher ^ 0xC0) == (const unsigned char)*key;
  121|    424|		}
  122|    943|	}
  123|       |	/* If key points at a leading byte in a multibyte sequence, but we are not yet
  124|       |	 * in multibyte mode, then the dafsa should contain a special byte to indicate
  125|       |	 * a mode switch. */
  126|  4.23k|	if (GetMultibyteLength(*key)) {
  ------------------
  |  Branch (126:6): [True: 1.73k, False: 2.50k]
  ------------------
  127|  1.73k|		return matcher == 0x1F;
  128|  1.73k|	}
  129|       |	/* Normal matching of a single byte character. */
  130|  2.50k|	return matcher == (const unsigned char)*key;
  131|  4.23k|}
lookup_string_in_fixed_set.c:GetMultibyteLength:
   24|  4.73k|static int GetMultibyteLength(char c) {
   25|  4.73k|	return multibyte_length_table[((unsigned char)c) >> 4];
   26|  4.73k|}
lookup_string_in_fixed_set.c:NextPos:
   34|    500|{
   35|    500|	++*pos;
   36|    500|	if (*multibyte_start) {
  ------------------
  |  Branch (36:6): [True: 78, False: 422]
  ------------------
   37|       |		/* Advance key to next byte in multibyte sequence. */
   38|     78|		++*key;
   39|       |		/* Reset multibyte_start if last byte in multibyte sequence was consumed. */
   40|     78|		if (*key - *multibyte_start == GetMultibyteLength(**multibyte_start))
  ------------------
  |  Branch (40:7): [True: 24, False: 54]
  ------------------
   41|     24|			*multibyte_start = 0;
   42|    422|	} else {
   43|    422|		if (GetMultibyteLength(**key)) {
  ------------------
  |  Branch (43:7): [True: 104, False: 318]
  ------------------
   44|       |			/* Multibyte prefix was matched in the dafsa, start matching multibyte
   45|       |			 * content in next round. */
   46|    104|			*multibyte_start = *key;
   47|    318|		} else {
   48|       |			/* Advance key as a single byte character was matched. */
   49|    318|			++*key;
   50|    318|		}
   51|    422|	}
   52|    500|}
lookup_string_in_fixed_set.c:GetReturnValue:
  170|  7.05k|{
  171|  7.05k|	CHECK_LT(offset, end);
  ------------------
  |  |   10|  7.05k|#define CHECK_LT(a, b) if ((a) >= b) return 0
  |  |  ------------------
  |  |  |  Branch (10:28): [True: 215, False: 6.84k]
  |  |  ------------------
  ------------------
  172|  6.84k|	if (!multibyte_start && (*offset & 0xE0) == 0x80) {
  ------------------
  |  Branch (172:6): [True: 6.84k, False: 0]
  |  Branch (172:26): [True: 14, False: 6.82k]
  ------------------
  173|     14|		*return_value = *offset & 0x0F;
  174|     14|		return 1;
  175|     14|	}
  176|  6.82k|	return 0;
  177|  6.84k|}
lookup_string_in_fixed_set.c:IsEndCharMatch:
  156|  1.24k|{
  157|  1.24k|	CHECK_LT(offset, end);
  ------------------
  |  |   10|  1.24k|#define CHECK_LT(a, b) if ((a) >= b) return 0
  |  |  ------------------
  |  |  |  Branch (10:28): [True: 0, False: 1.24k]
  |  |  ------------------
  ------------------
  158|  1.24k|	return IsMatchUnchecked(*offset ^ 0x80, key, multibyte_start);
  159|  1.24k|}

psl_is_public_suffix:
  991|    562|{
  992|    562|	if (!psl || !domain)
  ------------------
  |  Branch (992:6): [True: 281, False: 281]
  |  Branch (992:14): [True: 0, False: 281]
  ------------------
  993|    281|		return 1;
  994|       |
  995|    281|	return is_public_suffix(psl, domain, PSL_TYPE_ANY);
  ------------------
  |  |   68|    281|#define PSL_TYPE_ANY          (PSL_TYPE_ICANN | PSL_TYPE_PRIVATE)
  |  |  ------------------
  |  |  |  |   65|    281|#define PSL_TYPE_ICANN        (1<<0)
  |  |  ------------------
  |  |               #define PSL_TYPE_ANY          (PSL_TYPE_ICANN | PSL_TYPE_PRIVATE)
  |  |  ------------------
  |  |  |  |   66|    281|#define PSL_TYPE_PRIVATE      (1<<1)
  |  |  ------------------
  ------------------
  996|    562|}
psl_load_fp:
 1185|    281|{
 1186|    281|	psl_ctx_t *psl;
 1187|    281|	psl_entry_t suffix, *suffixp;
 1188|    281|	char buf[256], *linep, *p;
 1189|    281|	int type = 0, is_dafsa;
 1190|    281|	psl_idna_t *idna;
 1191|       |
 1192|    281|	if (!fp)
  ------------------
  |  Branch (1192:6): [True: 0, False: 281]
  ------------------
 1193|      0|		return NULL;
 1194|       |
 1195|    281|	if (!(psl = calloc(1, sizeof(psl_ctx_t))))
  ------------------
  |  Branch (1195:6): [True: 0, False: 281]
  ------------------
 1196|      0|		return NULL;
 1197|       |
 1198|       |	/* read first line to allow ASCII / DAFSA detection */
 1199|    281|	if (!(linep = fgets(buf, sizeof(buf) - 1, fp)))
  ------------------
  |  Branch (1199:6): [True: 0, False: 281]
  ------------------
 1200|      0|		goto fail;
 1201|       |
 1202|    281|	is_dafsa = strlen(buf) == 16 && !strncmp(buf, ".DAFSA@PSL_", 11);
  ------------------
  |  Branch (1202:13): [True: 281, False: 0]
  |  Branch (1202:34): [True: 281, False: 0]
  ------------------
 1203|       |
 1204|    281|	if (is_dafsa) {
  ------------------
  |  Branch (1204:6): [True: 281, False: 0]
  ------------------
 1205|    281|		void *m;
 1206|    281|		size_t size = 65536, n, len = 0;
 1207|    281|		int version = atoi(buf + 11);
 1208|       |
 1209|    281|		if (version != 0)
  ------------------
  |  Branch (1209:7): [True: 0, False: 281]
  ------------------
 1210|      0|			goto fail;
 1211|       |
 1212|    281|		if (!(psl->dafsa = malloc(size)))
  ------------------
  |  Branch (1212:7): [True: 0, False: 281]
  ------------------
 1213|      0|			goto fail;
 1214|       |
 1215|    281|		memcpy(psl->dafsa, buf, len);
 1216|       |
 1217|    596|		while ((n = fread(psl->dafsa + len, 1, size - len, fp)) > 0) {
  ------------------
  |  Branch (1217:10): [True: 315, False: 281]
  ------------------
 1218|    315|			len += n;
 1219|    315|			if (len >= size) {
  ------------------
  |  Branch (1219:8): [True: 40, False: 275]
  ------------------
 1220|     40|				if (!(m = realloc(psl->dafsa, size *= 2)))
  ------------------
  |  Branch (1220:9): [True: 0, False: 40]
  ------------------
 1221|      0|					goto fail;
 1222|     40|				psl->dafsa = m;
 1223|     40|			}
 1224|    315|		}
 1225|       |
 1226|       |		/* release unused memory */
 1227|    281|		if ((m = realloc(psl->dafsa, len)))
  ------------------
  |  Branch (1227:7): [True: 281, False: 0]
  ------------------
 1228|    281|			psl->dafsa = m;
 1229|      0|		else if (!len)
  ------------------
  |  Branch (1229:12): [True: 0, False: 0]
  ------------------
 1230|      0|			psl->dafsa = NULL; /* realloc() just free'd psl->dafsa */
 1231|       |
 1232|    281|		psl->dafsa_size = len;
 1233|    281|		psl->utf8 = !!GetUtfMode(psl->dafsa, len);
 1234|       |
 1235|    281|		return psl;
 1236|    281|	}
 1237|       |
 1238|      0|	idna = psl_idna_open();
 1239|       |
 1240|       |	/*
 1241|       |	 *  as of 02.11.2012, the list at https://publicsuffix.org/list/ contains ~6000 rules and 40 exceptions.
 1242|       |	 *  as of 19.02.2014, the list at https://publicsuffix.org/list/ contains ~6500 rules and 19 exceptions.
 1243|       |	 *  as of 07.10.2018, the list at https://publicsuffix.org/list/ contains ~8600 rules and 8 exceptions.
 1244|       |	 */
 1245|      0|	psl->suffixes = vector_alloc(8*1024, suffix_compare_array);
 1246|      0|	psl->utf8 = 1; /* we put UTF-8 and punycode rules in the lookup vector */
 1247|       |
 1248|      0|	do {
 1249|      0|		while (isspace_ascii(*linep)) linep++; /* ignore leading whitespace */
  ------------------
  |  Branch (1249:10): [True: 0, False: 0]
  ------------------
 1250|      0|		if (!*linep) continue; /* skip empty lines */
  ------------------
  |  Branch (1250:7): [True: 0, False: 0]
  ------------------
 1251|       |
 1252|      0|		if (*linep == '/' && linep[1] == '/') {
  ------------------
  |  Branch (1252:7): [True: 0, False: 0]
  |  Branch (1252:24): [True: 0, False: 0]
  ------------------
 1253|      0|			if (!type) {
  ------------------
  |  Branch (1253:8): [True: 0, False: 0]
  ------------------
 1254|      0|				if (strstr(linep + 2, "===BEGIN ICANN DOMAINS==="))
  ------------------
  |  Branch (1254:9): [True: 0, False: 0]
  ------------------
 1255|      0|					type = PRIV_PSL_FLAG_ICANN;
  ------------------
  |  |  126|      0|#define PRIV_PSL_FLAG_ICANN     (1<<2) /* entry of ICANN section */
  ------------------
 1256|      0|				else if (!type && strstr(linep + 2, "===BEGIN PRIVATE DOMAINS==="))
  ------------------
  |  Branch (1256:14): [True: 0, False: 0]
  |  Branch (1256:23): [True: 0, False: 0]
  ------------------
 1257|      0|					type = PRIV_PSL_FLAG_PRIVATE;
  ------------------
  |  |  127|      0|#define PRIV_PSL_FLAG_PRIVATE   (1<<3) /* entry of PRIVATE section */
  ------------------
 1258|      0|			}
 1259|      0|			else if (type == PRIV_PSL_FLAG_ICANN && strstr(linep + 2, "===END ICANN DOMAINS==="))
  ------------------
  |  |  126|      0|#define PRIV_PSL_FLAG_ICANN     (1<<2) /* entry of ICANN section */
  ------------------
  |  Branch (1259:13): [True: 0, False: 0]
  |  Branch (1259:44): [True: 0, False: 0]
  ------------------
 1260|      0|				type = 0;
 1261|      0|			else if (type == PRIV_PSL_FLAG_PRIVATE && strstr(linep + 2, "===END PRIVATE DOMAINS==="))
  ------------------
  |  |  127|      0|#define PRIV_PSL_FLAG_PRIVATE   (1<<3) /* entry of PRIVATE section */
  ------------------
  |  Branch (1261:13): [True: 0, False: 0]
  |  Branch (1261:46): [True: 0, False: 0]
  ------------------
 1262|      0|				type = 0;
 1263|       |
 1264|      0|			continue; /* skip comments */
 1265|      0|		}
 1266|       |
 1267|       |		/* parse suffix rule */
 1268|      0|		for (p = linep; *linep && !isspace_ascii(*linep);) linep++;
  ------------------
  |  Branch (1268:19): [True: 0, False: 0]
  |  Branch (1268:29): [True: 0, False: 0]
  ------------------
 1269|      0|		*linep = 0;
 1270|       |
 1271|      0|		if (*p == '!') {
  ------------------
  |  Branch (1271:7): [True: 0, False: 0]
  ------------------
 1272|      0|			p++;
 1273|      0|			suffix.flags = PRIV_PSL_FLAG_EXCEPTION | type;
  ------------------
  |  |  124|      0|#define PRIV_PSL_FLAG_EXCEPTION (1<<0)
  ------------------
 1274|      0|			psl->nexceptions++;
 1275|      0|		} else if (*p == '*') {
  ------------------
  |  Branch (1275:14): [True: 0, False: 0]
  ------------------
 1276|      0|			if (*++p != '.') {
  ------------------
  |  Branch (1276:8): [True: 0, False: 0]
  ------------------
 1277|       |				/* fprintf(stderr, "Unsupported kind of rule (ignored): %s\n", p - 1); */
 1278|      0|				continue;
 1279|      0|			}
 1280|      0|			p++;
 1281|       |			/* wildcard *.foo.bar implicitly make foo.bar a public suffix */
 1282|      0|			suffix.flags = PRIV_PSL_FLAG_WILDCARD | PRIV_PSL_FLAG_PLAIN | type;
  ------------------
  |  |  125|      0|#define PRIV_PSL_FLAG_WILDCARD  (1<<1)
  ------------------
              			suffix.flags = PRIV_PSL_FLAG_WILDCARD | PRIV_PSL_FLAG_PLAIN | type;
  ------------------
  |  |  128|      0|#define PRIV_PSL_FLAG_PLAIN     (1<<4) /* just used for PSL syntax checking */
  ------------------
 1283|      0|			psl->nwildcards++;
 1284|      0|			psl->nsuffixes++;
 1285|      0|		} else {
 1286|      0|			suffix.flags = PRIV_PSL_FLAG_PLAIN | type;
  ------------------
  |  |  128|      0|#define PRIV_PSL_FLAG_PLAIN     (1<<4) /* just used for PSL syntax checking */
  ------------------
 1287|      0|			psl->nsuffixes++;
 1288|      0|		}
 1289|       |
 1290|      0|		if (suffix_init(&suffix, p, linep - p) == 0) {
  ------------------
  |  Branch (1290:7): [True: 0, False: 0]
  ------------------
 1291|      0|			int index;
 1292|       |
 1293|      0|			if ((index = vector_find(psl->suffixes, &suffix)) >= 0) {
  ------------------
  |  Branch (1293:8): [True: 0, False: 0]
  ------------------
 1294|       |				/* Found existing entry:
 1295|       |				 * Combination of exception and plain rule is ambiguous
 1296|       |				 * !foo.bar
 1297|       |				 * foo.bar
 1298|       |				 *
 1299|       |				 * Allowed:
 1300|       |				 * !foo.bar + *.foo.bar
 1301|       |				 * foo.bar + *.foo.bar
 1302|       |				 *
 1303|       |				 * We do not check here, let's do it later.
 1304|       |				 */
 1305|       |
 1306|      0|				suffixp = vector_get(psl->suffixes, index);
 1307|      0|				suffixp->flags |= suffix.flags;
 1308|      0|			} else {
 1309|       |				/* New entry */
 1310|      0|				suffixp = vector_get(psl->suffixes, vector_add(psl->suffixes, &suffix));
 1311|      0|			}
 1312|       |
 1313|      0|			if (suffixp) {
  ------------------
  |  Branch (1313:8): [True: 0, False: 0]
  ------------------
 1314|      0|				suffixp->label = suffixp->label_buf; /* set label to changed address */
 1315|      0|				add_punycode_if_needed(idna, psl->suffixes, suffixp);
 1316|      0|			}
 1317|      0|		}
 1318|      0|	} while ((linep = fgets(buf, sizeof(buf), fp)));
  ------------------
  |  Branch (1318:11): [True: 0, False: 0]
  ------------------
 1319|       |
 1320|      0|	vector_sort(psl->suffixes);
 1321|       |
 1322|      0|	psl_idna_close(idna);
 1323|       |
 1324|      0|	return psl;
 1325|       |
 1326|      0|fail:
 1327|      0|	psl_free(psl);
 1328|      0|	return NULL;
 1329|    281|}
psl_free:
 1341|    562|{
 1342|    562|	if (psl && psl != &builtin_psl) {
  ------------------
  |  Branch (1342:6): [True: 281, False: 281]
  |  Branch (1342:13): [True: 281, False: 0]
  ------------------
 1343|    281|		vector_free(&psl->suffixes);
 1344|    281|		free(psl->dafsa);
 1345|    281|		free(psl);
 1346|    281|	}
 1347|    562|}
psl_builtin:
 1366|    281|{
 1367|       |#ifdef ENABLE_BUILTIN
 1368|       |	return &builtin_psl;
 1369|       |#else
 1370|    281|	return NULL;
 1371|    281|#endif
 1372|    281|}
psl_suffix_count:
 1389|    281|{
 1390|    281|	if (psl == &builtin_psl)
  ------------------
  |  Branch (1390:6): [True: 0, False: 281]
  ------------------
 1391|      0|		return _psl_nsuffixes;
 1392|    281|	else if (psl)
  ------------------
  |  Branch (1392:11): [True: 281, False: 0]
  ------------------
 1393|    281|		return psl->dafsa ? -1 : psl->nsuffixes;
  ------------------
  |  Branch (1393:10): [True: 281, False: 0]
  ------------------
 1394|      0|	else
 1395|      0|		return -1;
 1396|    281|}
psl_suffix_exception_count:
 1412|    281|{
 1413|    281|	if (psl == &builtin_psl)
  ------------------
  |  Branch (1413:6): [True: 0, False: 281]
  ------------------
 1414|      0|		return _psl_nexceptions;
 1415|    281|	else if (psl)
  ------------------
  |  Branch (1415:11): [True: 281, False: 0]
  ------------------
 1416|    281|		return psl->dafsa ? -1 : psl->nexceptions;
  ------------------
  |  Branch (1416:10): [True: 281, False: 0]
  ------------------
 1417|      0|	else
 1418|      0|		return -1;
 1419|    281|}
psl_suffix_wildcard_count:
 1435|    281|{
 1436|    281|	if (psl == &builtin_psl)
  ------------------
  |  Branch (1436:6): [True: 0, False: 281]
  ------------------
 1437|      0|		return _psl_nwildcards;
 1438|    281|	else if (psl)
  ------------------
  |  Branch (1438:11): [True: 281, False: 0]
  ------------------
 1439|    281|		return psl->dafsa ? -1 : psl->nwildcards;
  ------------------
  |  Branch (1439:10): [True: 281, False: 0]
  ------------------
 1440|      0|	else
 1441|      0|		return -1;
 1442|    281|}
psl_latest:
 1935|    281|{
 1936|    281|	psl_ctx_t *psl;
 1937|    281|	const char *psl_fname[3];
 1938|    281|	time_t psl_mtime[3];
 1939|    281|	int it, ntimes;
 1940|       |
 1941|    281|	psl_fname[0] = NULL; /* silence gcc 6.2 false warning */
 1942|       |
 1943|       |	/* create array of PSL files reverse sorted by mtime (latest first) */
 1944|    281|	ntimes = insert_file(fname, psl_fname, psl_mtime, 0);
 1945|    281|	ntimes = insert_file(_psl_dist_filename, psl_fname, psl_mtime, ntimes);
 1946|    281|	ntimes = insert_file(_psl_filename, psl_fname, psl_mtime, ntimes);
 1947|       |
 1948|       |	/* load PSL data from the latest file, falling back to the second recent, ... */
 1949|    281|	for (psl = NULL, it = 0; it < ntimes; it++) {
  ------------------
  |  Branch (1949:27): [True: 0, False: 281]
  ------------------
 1950|      0|		if (psl_mtime[it] > _psl_file_time)
  ------------------
  |  Branch (1950:7): [True: 0, False: 0]
  ------------------
 1951|      0|			if ((psl = psl_load_file(psl_fname[it])))
  ------------------
  |  Branch (1951:8): [True: 0, False: 0]
  ------------------
 1952|      0|				break;
 1953|      0|	}
 1954|       |
 1955|       |	/* if file loading failed or there is no file newer than the builtin data,
 1956|       |	 * then return the builtin data. */
 1957|    281|	return psl ? psl : (psl_ctx_t *) psl_builtin();
  ------------------
  |  Branch (1957:9): [True: 0, False: 281]
  ------------------
 1958|    281|}
psl.c:is_public_suffix:
  827|    281|{
  828|    281|	psl_entry_t suffix;
  829|    281|	const char *p;
  830|    281|	char *punycode = NULL;
  831|    281|	int need_conversion = 0;
  832|       |
  833|       |	/* this function should be called without leading dots, just make sure */
  834|    281|	if (*domain == '.')
  ------------------
  |  Branch (834:6): [True: 281, False: 0]
  ------------------
  835|    281|		domain++;
  836|       |
  837|    281|	suffix.nlabels = 1;
  838|       |
  839|  1.96k|	for (p = domain; *p; p++) {
  ------------------
  |  Branch (839:19): [True: 1.68k, False: 281]
  ------------------
  840|  1.68k|		if (*p == '.') {
  ------------------
  |  Branch (840:7): [True: 281, False: 1.40k]
  ------------------
  841|    281|			if (suffix.nlabels == 255) // weird input, avoid 8bit overflow
  ------------------
  |  Branch (841:8): [True: 0, False: 281]
  ------------------
  842|      0|				return 0;
  843|    281|			suffix.nlabels++;
  844|    281|		}
  845|  1.40k|		else if (*((unsigned char *)p) >= 128)
  ------------------
  |  Branch (845:12): [True: 562, False: 843]
  ------------------
  846|    562|			need_conversion = 1; /* in case domain is non-ascii we need a toASCII conversion */
  847|  1.68k|	}
  848|       |
  849|    281|	if (suffix.nlabels == 1) {
  ------------------
  |  Branch (849:6): [True: 0, False: 281]
  ------------------
  850|       |		/* TLD, this is the prevailing '*' match. If type excludes the '*' rule, continue.
  851|       |		 */
  852|      0|		if (!(type & PSL_TYPE_NO_STAR_RULE))
  ------------------
  |  |   67|      0|#define PSL_TYPE_NO_STAR_RULE (1<<2)
  ------------------
  |  Branch (852:7): [True: 0, False: 0]
  ------------------
  853|      0|			return 1;
  854|      0|	}
  855|       |
  856|    281|	type &= ~PSL_TYPE_NO_STAR_RULE;
  ------------------
  |  |   67|    281|#define PSL_TYPE_NO_STAR_RULE (1<<2)
  ------------------
  857|       |
  858|    281|	if (psl->utf8 || psl == &builtin_psl)
  ------------------
  |  Branch (858:6): [True: 212, False: 69]
  |  Branch (858:19): [True: 0, False: 69]
  ------------------
  859|    212|		need_conversion = 0;
  860|       |
  861|    281|	if (need_conversion) {
  ------------------
  |  Branch (861:6): [True: 69, False: 212]
  ------------------
  862|     69|		psl_idna_t *idna = psl_idna_open();
  863|       |
  864|     69|		if (psl_idna_toASCII(idna, domain, &punycode) == 0) {
  ------------------
  |  Branch (864:7): [True: 69, False: 0]
  ------------------
  865|     69|			suffix.label = punycode;
  866|     69|			suffix.length = strlen(punycode);
  867|     69|		} else {
  868|       |			/* fallback */
  869|       |
  870|      0|			suffix.label = domain;
  871|      0|			suffix.length = p - suffix.label;
  872|      0|		}
  873|       |
  874|     69|		psl_idna_close(idna);
  875|    212|	} else {
  876|    212|		suffix.label = domain;
  877|    212|		suffix.length = p - suffix.label;
  878|    212|	}
  879|       |
  880|    281|	if (psl == &builtin_psl || psl->dafsa) {
  ------------------
  |  Branch (880:6): [True: 0, False: 281]
  |  Branch (880:29): [True: 281, False: 0]
  ------------------
  881|    281|		size_t dafsa_size = psl == &builtin_psl ? sizeof(kDafsa) : psl->dafsa_size;
  ------------------
  |  Branch (881:23): [True: 0, False: 281]
  ------------------
  882|    281|		const unsigned char *dafsa = psl == &builtin_psl ? kDafsa : psl->dafsa;
  ------------------
  |  Branch (882:32): [True: 0, False: 281]
  ------------------
  883|    281|		int rc = LookupStringInFixedSet(dafsa, dafsa_size, suffix.label, suffix.length);
  884|    281|		if (rc != -1) {
  ------------------
  |  Branch (884:7): [True: 6, False: 275]
  ------------------
  885|       |			/* check for correct rule type */
  886|      6|			if (type == PSL_TYPE_ICANN && !(rc & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |   65|     12|#define PSL_TYPE_ICANN        (1<<0)
  ------------------
              			if (type == PSL_TYPE_ICANN && !(rc & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |  126|      0|#define PRIV_PSL_FLAG_ICANN     (1<<2) /* entry of ICANN section */
  ------------------
  |  Branch (886:8): [True: 0, False: 6]
  |  Branch (886:34): [True: 0, False: 0]
  ------------------
  887|      0|				goto suffix_no;
  888|      6|			else if (type == PSL_TYPE_PRIVATE && !(rc & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |   66|     12|#define PSL_TYPE_PRIVATE      (1<<1)
  ------------------
              			else if (type == PSL_TYPE_PRIVATE && !(rc & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |  127|      0|#define PRIV_PSL_FLAG_PRIVATE   (1<<3) /* entry of PRIVATE section */
  ------------------
  |  Branch (888:13): [True: 0, False: 6]
  |  Branch (888:41): [True: 0, False: 0]
  ------------------
  889|      0|				goto suffix_no;
  890|       |
  891|      6|			if (rc & PRIV_PSL_FLAG_EXCEPTION)
  ------------------
  |  |  124|      6|#define PRIV_PSL_FLAG_EXCEPTION (1<<0)
  ------------------
  |  Branch (891:8): [True: 4, False: 2]
  ------------------
  892|      4|				goto suffix_no;
  893|       |
  894|       |			/* wildcard *.foo.bar implicitly make foo.bar a public suffix */
  895|       |			/* definitely a match, no matter if the found rule is a wildcard or not */
  896|      2|			goto suffix_yes;
  897|      6|		}
  898|    275|		if ((suffix.label = strchr(suffix.label, '.'))) {
  ------------------
  |  Branch (898:7): [True: 275, False: 0]
  ------------------
  899|    275|			suffix.label++;
  900|    275|			suffix.length = strlen(suffix.label);
  901|    275|			suffix.nlabels--;
  902|       |
  903|    275|			rc = LookupStringInFixedSet(dafsa, dafsa_size, suffix.label, suffix.length);
  904|    275|			if (rc != -1) {
  ------------------
  |  Branch (904:8): [True: 8, False: 267]
  ------------------
  905|       |				/* check for correct rule type */
  906|      8|				if (type == PSL_TYPE_ICANN && !(rc & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |   65|     16|#define PSL_TYPE_ICANN        (1<<0)
  ------------------
              				if (type == PSL_TYPE_ICANN && !(rc & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |  126|      0|#define PRIV_PSL_FLAG_ICANN     (1<<2) /* entry of ICANN section */
  ------------------
  |  Branch (906:9): [True: 0, False: 8]
  |  Branch (906:35): [True: 0, False: 0]
  ------------------
  907|      0|					goto suffix_no;
  908|      8|				else if (type == PSL_TYPE_PRIVATE && !(rc & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |   66|     16|#define PSL_TYPE_PRIVATE      (1<<1)
  ------------------
              				else if (type == PSL_TYPE_PRIVATE && !(rc & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |  127|      0|#define PRIV_PSL_FLAG_PRIVATE   (1<<3) /* entry of PRIVATE section */
  ------------------
  |  Branch (908:14): [True: 0, False: 8]
  |  Branch (908:42): [True: 0, False: 0]
  ------------------
  909|      0|					goto suffix_no;
  910|       |
  911|      8|				if (rc & PRIV_PSL_FLAG_WILDCARD)
  ------------------
  |  |  125|      8|#define PRIV_PSL_FLAG_WILDCARD  (1<<1)
  ------------------
  |  Branch (911:9): [True: 5, False: 3]
  ------------------
  912|      5|					goto suffix_yes;
  913|      8|			}
  914|    275|		}
  915|    275|	} else {
  916|      0|		psl_entry_t *rule = vector_get(psl->suffixes, 0);
  917|       |
  918|      0|		if (!rule || rule->nlabels < suffix.nlabels - 1)
  ------------------
  |  Branch (918:7): [True: 0, False: 0]
  |  Branch (918:16): [True: 0, False: 0]
  ------------------
  919|      0|			goto suffix_no;
  920|       |
  921|      0|		rule = vector_get(psl->suffixes, vector_find(psl->suffixes, &suffix));
  922|       |
  923|      0|		if (rule) {
  ------------------
  |  Branch (923:7): [True: 0, False: 0]
  ------------------
  924|       |			/* check for correct rule type */
  925|      0|			if (type == PSL_TYPE_ICANN && !(rule->flags & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |   65|      0|#define PSL_TYPE_ICANN        (1<<0)
  ------------------
              			if (type == PSL_TYPE_ICANN && !(rule->flags & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |  126|      0|#define PRIV_PSL_FLAG_ICANN     (1<<2) /* entry of ICANN section */
  ------------------
  |  Branch (925:8): [True: 0, False: 0]
  |  Branch (925:34): [True: 0, False: 0]
  ------------------
  926|      0|				goto suffix_no;
  927|      0|			else if (type == PSL_TYPE_PRIVATE && !(rule->flags & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |   66|      0|#define PSL_TYPE_PRIVATE      (1<<1)
  ------------------
              			else if (type == PSL_TYPE_PRIVATE && !(rule->flags & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |  127|      0|#define PRIV_PSL_FLAG_PRIVATE   (1<<3) /* entry of PRIVATE section */
  ------------------
  |  Branch (927:13): [True: 0, False: 0]
  |  Branch (927:41): [True: 0, False: 0]
  ------------------
  928|      0|				goto suffix_no;
  929|       |
  930|      0|			if (rule->flags & PRIV_PSL_FLAG_EXCEPTION)
  ------------------
  |  |  124|      0|#define PRIV_PSL_FLAG_EXCEPTION (1<<0)
  ------------------
  |  Branch (930:8): [True: 0, False: 0]
  ------------------
  931|      0|				goto suffix_no;
  932|       |
  933|       |			/* wildcard *.foo.bar implicitly make foo.bar a public suffix */
  934|       |			/* definitely a match, no matter if the found rule is a wildcard or not */
  935|      0|			goto suffix_yes;
  936|      0|		}
  937|       |
  938|      0|		if ((suffix.label = strchr(suffix.label, '.'))) {
  ------------------
  |  Branch (938:7): [True: 0, False: 0]
  ------------------
  939|      0|			suffix.label++;
  940|      0|			suffix.length = strlen(suffix.label);
  941|      0|			suffix.nlabels--;
  942|       |
  943|      0|			rule = vector_get(psl->suffixes, vector_find(psl->suffixes, &suffix));
  944|       |
  945|      0|			if (rule) {
  ------------------
  |  Branch (945:8): [True: 0, False: 0]
  ------------------
  946|       |				/* check for correct rule type */
  947|      0|				if (type == PSL_TYPE_ICANN && !(rule->flags & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |   65|      0|#define PSL_TYPE_ICANN        (1<<0)
  ------------------
              				if (type == PSL_TYPE_ICANN && !(rule->flags & PRIV_PSL_FLAG_ICANN))
  ------------------
  |  |  126|      0|#define PRIV_PSL_FLAG_ICANN     (1<<2) /* entry of ICANN section */
  ------------------
  |  Branch (947:9): [True: 0, False: 0]
  |  Branch (947:35): [True: 0, False: 0]
  ------------------
  948|      0|					goto suffix_no;
  949|      0|				else if (type == PSL_TYPE_PRIVATE && !(rule->flags & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |   66|      0|#define PSL_TYPE_PRIVATE      (1<<1)
  ------------------
              				else if (type == PSL_TYPE_PRIVATE && !(rule->flags & PRIV_PSL_FLAG_PRIVATE))
  ------------------
  |  |  127|      0|#define PRIV_PSL_FLAG_PRIVATE   (1<<3) /* entry of PRIVATE section */
  ------------------
  |  Branch (949:14): [True: 0, False: 0]
  |  Branch (949:42): [True: 0, False: 0]
  ------------------
  950|      0|					goto suffix_no;
  951|       |
  952|      0|				if (rule->flags & PRIV_PSL_FLAG_WILDCARD)
  ------------------
  |  |  125|      0|#define PRIV_PSL_FLAG_WILDCARD  (1<<1)
  ------------------
  |  Branch (952:9): [True: 0, False: 0]
  ------------------
  953|      0|					goto suffix_yes;
  954|      0|			}
  955|      0|		}
  956|      0|	}
  957|       |
  958|    274|suffix_no:
  959|    274|	if (punycode)
  ------------------
  |  Branch (959:6): [True: 66, False: 208]
  ------------------
  960|     66|		free(punycode);
  961|    274|	return 0;
  962|       |
  963|      7|suffix_yes:
  964|      7|	if (punycode)
  ------------------
  |  Branch (964:6): [True: 3, False: 4]
  ------------------
  965|      3|		free(punycode);
  966|      7|	return 1;
  967|    281|}
psl.c:psl_idna_toASCII:
  680|     69|{
  681|     69|	int ret = -1;
  682|       |
  683|       |#if defined(WITH_LIBICU)
  684|       |	/* IDNA2008 UTS#46 punycode conversion */
  685|       |	if (idna) {
  686|       |		char lookupname_buf[128] = "", *lookupname = lookupname_buf;
  687|       |		UErrorCode status = 0;
  688|       |		UIDNAInfo info = UIDNA_INFO_INITIALIZER;
  689|       |		UChar utf16_dst[128], utf16_src_buf[128];
  690|       |		UChar *utf16_src = utf16_src_buf;
  691|       |		int32_t utf16_src_length, bytes_written;
  692|       |		int32_t utf16_dst_length;
  693|       |
  694|       |		u_strFromUTF8(utf16_src, countof(utf16_src_buf), &utf16_src_length, utf8, -1, &status);
  695|       |		if (!U_SUCCESS(status)) goto cleanup; /* UTF-8 to UTF-16 conversion failed */
  696|       |
  697|       |		if (utf16_src_length >= (int) countof(utf16_src_buf)) {
  698|       |			utf16_src = malloc((utf16_src_length + 1) * sizeof(UChar));
  699|       |			if (!utf16_src) goto cleanup;
  700|       |
  701|       |			u_strFromUTF8(utf16_src, utf16_src_length, NULL, utf8, -1, &status);
  702|       |			if (!U_SUCCESS(status)) goto cleanup; /* UTF-8 to UTF-16 conversion failed */
  703|       |
  704|       |			utf16_src[utf16_src_length] = 0; /* u_strFromUTF8() doesn't 0-terminate if dest is filled up */
  705|       |		}
  706|       |
  707|       |		utf16_dst_length = uidna_nameToASCII((UIDNA *)idna, utf16_src, utf16_src_length, utf16_dst, countof(utf16_dst), &info, &status);
  708|       |		if (!U_SUCCESS(status)) goto cleanup; /* to ASCII conversion failed */
  709|       |
  710|       |		u_strToUTF8(lookupname, sizeof(lookupname_buf), &bytes_written, utf16_dst, utf16_dst_length, &status);
  711|       |		if (!U_SUCCESS(status)) goto cleanup; /* UTF-16 to UTF-8 conversion failed */
  712|       |
  713|       |		if (bytes_written >= (int) sizeof(lookupname_buf)) {
  714|       |			lookupname = malloc(bytes_written + 1);
  715|       |			if (!lookupname) goto cleanup;
  716|       |
  717|       |			u_strToUTF8(lookupname, bytes_written, NULL, utf16_dst, utf16_dst_length, &status);
  718|       |			if (!U_SUCCESS(status)) goto cleanup; /* UTF-16 to UTF-8 conversion failed */
  719|       |
  720|       |			lookupname[bytes_written] = 0; /* u_strToUTF8() doesn't 0-terminate if dest is filled up */
  721|       |		} else {
  722|       |			if (!(lookupname = strdup(lookupname)))
  723|       |				goto cleanup;
  724|       |		}
  725|       |
  726|       |		if (ascii) {
  727|       |			*ascii = lookupname;
  728|       |			lookupname = NULL;
  729|       |		}
  730|       |
  731|       |		ret = 0;
  732|       |
  733|       |cleanup:
  734|       |		if (lookupname != lookupname_buf)
  735|       |			free(lookupname);
  736|       |		if (utf16_src != utf16_src_buf)
  737|       |			free(utf16_src);
  738|       |	}
  739|       |#elif defined(WITH_LIBIDN2)
  740|       |#if IDN2_VERSION_NUMBER >= 0x00140000
  741|       |	int rc;
  742|       |
  743|       |	/* IDN2_TRANSITIONAL automatically converts to lowercase
  744|       |	 * IDN2_NFC_INPUT converts to NFC before toASCII conversion
  745|       |	 * Since IDN2_TRANSITIONAL implicitly does NFC conversion, we don't need
  746|       |	 * the additional IDN2_NFC_INPUT. But just for the unlikely case that the linked
  747|       |	 * library is not matching the headers when building and it doesn't support TR46,
  748|       |	 * we provide IDN2_NFC_INPUT. */
  749|       |
  750|       |	if ((rc = idn2_lookup_u8((uint8_t *)utf8, (uint8_t **)ascii, IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL)) == IDN2_OK)
  751|       |		ret = 0;
  752|       |	/* else
  753|       |		fprintf(stderr, "toASCII(%s) failed (%d): %s\n", lower, rc, idn2_strerror(rc)); */
  754|       |#else
  755|       |	int rc;
  756|       |	uint8_t *lower;
  757|       |	size_t len = u8_strlen((uint8_t *)utf8) + 1;
  758|       |
  759|       |	/* we need a conversion to lowercase */
  760|       |	if (!(lower = u8_tolower((uint8_t *)utf8, len, 0, UNINORM_NFKC, NULL, &len))) {
  761|       |		/* fprintf(stderr, "u8_tolower(%s) failed (%d)\n", utf8, errno); */
  762|       |		return -1;
  763|       |	}
  764|       |
  765|       |	if ((rc = idn2_lookup_u8(lower, (uint8_t **)ascii, 0)) == IDN2_OK) {
  766|       |		ret = 0;
  767|       |	} /* else
  768|       |		fprintf(stderr, "toASCII(%s) failed (%d): %s\n", lower, rc, idn2_strerror(rc)); */
  769|       |
  770|       |	free(lower);
  771|       |#endif
  772|       |#elif defined(WITH_LIBIDN)
  773|       |	int rc;
  774|       |
  775|       |	if (!utf8_is_valid(utf8)) {
  776|       |		/* fprintf(stderr, "Invalid UTF-8 sequence not converted: '%s'\n", utf8); */
  777|       |		return -1;
  778|       |	}
  779|       |
  780|       |	/* idna_to_ascii_8z() automatically converts UTF-8 to lowercase */
  781|       |
  782|       |	if ((rc = idna_to_ascii_8z(utf8, ascii, IDNA_USE_STD3_ASCII_RULES)) == IDNA_SUCCESS) {
  783|       |		ret = 0;
  784|       |	} /* else
  785|       |		fprintf(stderr, "toASCII failed (%d): %s\n", rc, idna_strerror(rc)); */
  786|       |#else
  787|     69|	char lookupname[128];
  788|       |
  789|     69|	if (domain_to_punycode(utf8, lookupname, sizeof(lookupname)) == 0) {
  ------------------
  |  Branch (789:6): [True: 69, False: 0]
  ------------------
  790|     69|		if (ascii)
  ------------------
  |  Branch (790:7): [True: 69, False: 0]
  ------------------
  791|     69|			if ((*ascii = strdup(lookupname)))
  ------------------
  |  Branch (791:8): [True: 69, False: 0]
  ------------------
  792|     69|				ret = 0;
  793|     69|	}
  794|     69|#endif
  795|       |
  796|     69|	return ret;
  797|     69|}
psl.c:domain_to_punycode:
  566|     69|{
  567|     69|	size_t outlen = 0, labellen;
  568|     69|	punycode_uint input[256];
  569|     69|	const char *label, *e;
  570|       |
  571|    207|	for (e = label = domain; e;) {
  ------------------
  |  Branch (571:27): [True: 138, False: 69]
  ------------------
  572|    138|		e = strchr(label, '.');
  573|    138|		labellen = e ? (size_t) (e - label) : strlen(label);
  ------------------
  |  Branch (573:14): [True: 69, False: 69]
  ------------------
  574|       |
  575|    138|		if (mem_is_ascii(label, labellen)) {
  ------------------
  |  Branch (575:7): [True: 69, False: 69]
  ------------------
  576|     69|			if (outlen + labellen + (e != NULL) >= outsize)
  ------------------
  |  Branch (576:8): [True: 0, False: 69]
  ------------------
  577|      0|				return 1;
  578|       |
  579|     69|			memcpy(out + outlen, label, labellen);
  580|     69|			outlen += labellen;
  581|     69|		} else {
  582|     69|			ssize_t inputlen = 0;
  583|       |
  584|     69|			if (outlen + labellen + (e != NULL) + 4 >= outsize)
  ------------------
  |  Branch (584:8): [True: 0, False: 69]
  ------------------
  585|      0|				return 1;
  586|       |
  587|     69|			if ((inputlen = utf8_to_utf32(label, labellen, input, countof(input))) < 0)
  ------------------
  |  |  122|     69|#define countof(a) (sizeof(a)/sizeof(*(a)))
  ------------------
  |  Branch (587:8): [True: 0, False: 69]
  ------------------
  588|      0|				return 1;
  589|       |
  590|     69|			memcpy(out + outlen, "xn--", 4);
  591|     69|			outlen += 4;
  592|       |
  593|     69|			labellen = outsize - outlen - (e != NULL) - 1; // -1 to leave space for the trailing \0
  594|     69|			if (punycode_encode(inputlen, input, &labellen, out + outlen))
  ------------------
  |  Branch (594:8): [True: 0, False: 69]
  ------------------
  595|      0|				return 1;
  596|     69|			outlen += labellen;
  597|     69|		}
  598|       |
  599|    138|		if (e) {
  ------------------
  |  Branch (599:7): [True: 69, False: 69]
  ------------------
  600|     69|			label = e + 1;
  601|     69|			out[outlen++] = '.';
  602|     69|		}
  603|    138|		out[outlen] = 0;
  604|    138|	}
  605|       |
  606|     69|	return 0;
  607|     69|}
psl.c:mem_is_ascii:
  557|    138|{
  558|    345|	for (; n; n--) /* 'while(n--)' generates unsigned integer overflow on n = 0 */
  ------------------
  |  Branch (558:9): [True: 276, False: 69]
  ------------------
  559|    276|		if (*((unsigned char *)s++) >= 128)
  ------------------
  |  Branch (559:7): [True: 69, False: 207]
  ------------------
  560|     69|			return 0;
  561|       |
  562|     69|	return 1;
  563|    138|}
psl.c:utf8_to_utf32:
  516|     69|{
  517|     69|	size_t n = 0;
  518|     69|	const unsigned char *s = (void *)in;
  519|     69|	const unsigned char *e = (void *)(in + inlen);
  520|       |
  521|     69|	if (!outlen)
  ------------------
  |  Branch (521:6): [True: 0, False: 69]
  ------------------
  522|      0|		return -1;
  523|       |
  524|     69|	outlen--;
  525|       |
  526|    138|	while (n < outlen) {
  ------------------
  |  Branch (526:9): [True: 138, False: 0]
  ------------------
  527|    138|		size_t inleft = e - s;
  528|       |
  529|    138|		if (inleft >= 1 && (*s & 0x80) == 0) { /* 0xxxxxxx ASCII char */
  ------------------
  |  Branch (529:7): [True: 69, False: 69]
  |  Branch (529:22): [True: 0, False: 69]
  ------------------
  530|      0|			out[n++] = *s;
  531|      0|			s++;
  532|    138|		} else if (inleft >= 2 && (*s & 0xE0) == 0xC0) /* 110xxxxx 10xxxxxx */ {
  ------------------
  |  Branch (532:14): [True: 69, False: 69]
  |  Branch (532:29): [True: 69, False: 0]
  ------------------
  533|     69|			if ((s[1] & 0xC0) != 0x80)
  ------------------
  |  Branch (533:8): [True: 0, False: 69]
  ------------------
  534|      0|				return -1;
  535|     69|			out[n++] = ((*s & 0x1F) << 6) | (s[1] & 0x3F);
  536|     69|			s += 2;
  537|     69|		} else if (inleft >= 3 && (*s & 0xF0) == 0xE0) /* 1110xxxx 10xxxxxx 10xxxxxx */ {
  ------------------
  |  Branch (537:14): [True: 0, False: 69]
  |  Branch (537:29): [True: 0, False: 0]
  ------------------
  538|      0|			if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80)
  ------------------
  |  Branch (538:8): [True: 0, False: 0]
  |  Branch (538:33): [True: 0, False: 0]
  ------------------
  539|      0|				return -1;
  540|      0|			out[n++] = ((*s & 0x0F) << 12) | ((s[1] & 0x3F) << 6) | (s[2] & 0x3F);
  541|      0|			s += 3;
  542|     69|		} else if (inleft >= 4 && (*s & 0xF8) == 0xF0) /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ {
  ------------------
  |  Branch (542:14): [True: 0, False: 69]
  |  Branch (542:29): [True: 0, False: 0]
  ------------------
  543|      0|			if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80 || (s[3] & 0xC0) != 0x80)
  ------------------
  |  Branch (543:8): [True: 0, False: 0]
  |  Branch (543:33): [True: 0, False: 0]
  |  Branch (543:58): [True: 0, False: 0]
  ------------------
  544|      0|				return -1;
  545|      0|			out[n++] = ((*s & 0x07) << 18) | ((s[1] & 0x3F) << 12) | ((s[1] & 0x3F) << 6) | (s[2] & 0x3F);
  546|      0|			s += 4;
  547|     69|		} else if (!inleft) {
  ------------------
  |  Branch (547:14): [True: 69, False: 0]
  ------------------
  548|     69|			break;
  549|     69|		} else
  550|      0|			return -1;
  551|    138|	}
  552|       |
  553|     69|	return n;
  554|     69|}
psl.c:punycode_encode:
  417|     69|{
  418|     69|	punycode_uint input_length, n, delta, h, b, bias, j, m, q, k, t;
  419|     69|	size_t out, max_out;
  420|       |
  421|       |	/* The Punycode spec assumes that the input length is the same type */
  422|       |	/* of integer as a code point, so we need to convert the size_t to  */
  423|       |	/* a punycode_uint, which could overflow.                           */
  424|       |
  425|     69|	if (input_length_orig > maxint)
  ------------------
  |  Branch (425:6): [True: 0, False: 69]
  ------------------
  426|      0|		return punycode_overflow;
  427|       |
  428|     69|	input_length = (punycode_uint) input_length_orig;
  429|       |
  430|       |	/* Initialize the state: */
  431|       |
  432|     69|	n = initial_n;
  433|     69|	delta = 0;
  434|     69|	out = 0;
  435|     69|	max_out = *output_length;
  436|     69|	bias = initial_bias;
  437|       |
  438|       |	/* Handle the basic code points: */
  439|    138|	for (j = 0; j < input_length; ++j) {
  ------------------
  |  Branch (439:14): [True: 69, False: 69]
  ------------------
  440|     69|		if (input[j] < 0x80) {
  ------------------
  |  Branch (440:7): [True: 0, False: 69]
  ------------------
  441|      0|			if (max_out - out < 2)
  ------------------
  |  Branch (441:8): [True: 0, False: 0]
  ------------------
  442|      0|				return punycode_big_output;
  443|      0|			output[out++] = (char) input[j];
  444|      0|		}
  445|       |		/* else if (input[j] < n) return punycode_bad_input; */
  446|       |		/* (not needed for Punycode with unsigned code points) */
  447|     69|	}
  448|       |
  449|     69|	h = b = (punycode_uint) out;
  450|       |	/* cannot overflow because out <= input_length <= maxint */
  451|       |
  452|       |	/* h is the number of code points that have been handled, b is the  */
  453|       |	/* number of basic code points, and out is the number of ASCII code */
  454|       |	/* points that have been output.                                    */
  455|       |
  456|     69|	if (b > 0)
  ------------------
  |  Branch (456:6): [True: 0, False: 69]
  ------------------
  457|      0|		output[out++] = delimiter;
  458|       |
  459|       |	/* Main encoding loop: */
  460|       |
  461|    138|	while (h < input_length) {
  ------------------
  |  Branch (461:9): [True: 69, False: 69]
  ------------------
  462|       |		/* All non-basic code points < n have been     */
  463|       |		/* handled already.  Find the next larger one: */
  464|       |
  465|    138|		for (m = maxint, j = 0; j < input_length; ++j) {
  ------------------
  |  Branch (465:27): [True: 69, False: 69]
  ------------------
  466|       |			/* if (basic(input[j])) continue; */
  467|       |			/* (not needed for Punycode) */
  468|     69|			if (input[j] >= n && input[j] < m)
  ------------------
  |  Branch (468:8): [True: 69, False: 0]
  |  Branch (468:25): [True: 69, False: 0]
  ------------------
  469|     69|				m = input[j];
  470|     69|		}
  471|       |
  472|       |		/* Increase delta enough to advance the decoder's    */
  473|       |		/* <n,i> state to <m,0>, but guard against overflow: */
  474|       |
  475|     69|		if (m - n > (maxint - delta) / (h + 1))
  ------------------
  |  Branch (475:7): [True: 0, False: 69]
  ------------------
  476|      0|			return punycode_overflow;
  477|     69|		delta += (m - n) * (h + 1);
  478|     69|		n = m;
  479|       |
  480|    138|		for (j = 0; j < input_length; ++j) {
  ------------------
  |  Branch (480:15): [True: 69, False: 69]
  ------------------
  481|       |			/* Punycode does not need to check whether input[j] is basic: */
  482|     69|			if (input[j] < n /* || basic(input[j]) */) {
  ------------------
  |  Branch (482:8): [True: 0, False: 69]
  ------------------
  483|      0|				if (++delta == 0)
  ------------------
  |  Branch (483:9): [True: 0, False: 0]
  ------------------
  484|      0|					return punycode_overflow;
  485|      0|			}
  486|       |
  487|     69|			if (input[j] == n) {
  ------------------
  |  Branch (487:8): [True: 69, False: 0]
  ------------------
  488|       |				/* Represent delta as a generalized variable-length integer: */
  489|       |
  490|    207|				for (q = delta, k = base;; k += base) {
  491|    207|					if (out >= max_out)
  ------------------
  |  Branch (491:10): [True: 0, False: 207]
  ------------------
  492|      0|						return punycode_big_output;
  493|    207|					t = k <= bias /* + tmin */ ? tmin : /* +tmin not needed */
  ------------------
  |  Branch (493:10): [True: 138, False: 69]
  ------------------
  494|    207|						k >= bias + tmax ? tmax : k - bias;
  ------------------
  |  Branch (494:7): [True: 69, False: 0]
  ------------------
  495|    207|					if (q < t)
  ------------------
  |  Branch (495:10): [True: 69, False: 138]
  ------------------
  496|     69|						break;
  497|    138|					output[out++] = encode_digit(t + (q - t) % (base - t));
  498|    138|					q = (q - t) / (base - t);
  499|    138|				}
  500|       |
  501|     69|				output[out++] = encode_digit(q);
  502|     69|				bias = adapt(delta, h + 1, h == b);
  503|     69|				delta = 0;
  504|     69|				++h;
  505|     69|			}
  506|     69|		}
  507|       |
  508|     69|		++delta, ++n;
  509|     69|	}
  510|       |
  511|     69|	*output_length = out;
  512|     69|	return punycode_success;
  513|     69|}
psl.c:encode_digit:
  389|    207|{
  390|    207|	return d + 22 + 75 * (d < 26);
  391|       |	/*  0..25 map to ASCII a..z or A..Z */
  392|       |	/* 26..35 map to ASCII 0..9         */
  393|    207|}
psl.c:adapt:
  398|     69|{
  399|     69|	punycode_uint k;
  400|       |
  401|     69|	delta = firsttime ? delta / damp : delta >> 1;
  ------------------
  |  Branch (401:10): [True: 69, False: 0]
  ------------------
  402|       |	/* delta >> 1 is a faster way of doing delta / 2 */
  403|     69|	delta += delta / numpoints;
  404|       |
  405|     69|	for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base) {
  ------------------
  |  Branch (405:14): [True: 0, False: 69]
  ------------------
  406|      0|		delta /= base - tmin;
  407|      0|	}
  408|       |
  409|     69|	return k + (base - tmin + 1) * delta / (delta + skew);
  410|     69|}
psl.c:psl_idna_open:
  663|     69|{
  664|       |#if defined(WITH_LIBICU)
  665|       |	UErrorCode status = 0;
  666|       |	return (void *)uidna_openUTS46(UIDNA_USE_STD3_RULES | UIDNA_NONTRANSITIONAL_TO_ASCII, &status);
  667|       |#endif
  668|     69|	return NULL;
  669|     69|}
psl.c:psl_idna_close:
  672|     69|{
  673|       |#if defined(WITH_LIBICU)
  674|       |	if (idna)
  675|       |		uidna_close((UIDNA *)idna);
  676|       |#endif
  677|     69|}
psl.c:vector_free:
  209|    281|{
  210|    281|	if (v && *v) {
  ------------------
  |  Branch (210:6): [True: 281, False: 0]
  |  Branch (210:11): [True: 0, False: 281]
  ------------------
  211|      0|		if ((*v)->entry) {
  ------------------
  |  Branch (211:7): [True: 0, False: 0]
  ------------------
  212|      0|			int it;
  213|       |
  214|      0|			for (it = 0; it < (*v)->cur; it++)
  ------------------
  |  Branch (214:17): [True: 0, False: 0]
  ------------------
  215|      0|				free((*v)->entry[it]);
  216|       |
  217|      0|			free((*v)->entry);
  218|      0|		}
  219|      0|		free(*v);
  220|      0|	}
  221|    281|}
psl.c:insert_file:
 1895|    843|{
 1896|    843|	struct stat st;
 1897|    843|	int it;
 1898|       |
 1899|    843|	if (fname && *fname && stat(fname, &st) == 0 && st.st_mtime > _psl_file_time) {
  ------------------
  |  Branch (1899:6): [True: 562, False: 281]
  |  Branch (1899:15): [True: 0, False: 562]
  |  Branch (1899:25): [True: 0, False: 0]
  |  Branch (1899:50): [True: 0, False: 0]
  ------------------
 1900|       |		/* add file name and mtime to end of array */
 1901|      0|		psl_fname[n] = fname;
 1902|      0|		psl_mtime[n++] = st.st_mtime;
 1903|       |
 1904|       |		/* move the new entry to it's correct position */
 1905|      0|		for (it = n - 2; it >= 0 && st.st_mtime > psl_mtime[it]; it--) {
  ------------------
  |  Branch (1905:20): [True: 0, False: 0]
  |  Branch (1905:31): [True: 0, False: 0]
  ------------------
 1906|      0|			psl_fname[it + 1] = psl_fname[it];
 1907|      0|			psl_mtime[it + 1] = psl_mtime[it];
 1908|      0|			psl_fname[it] = fname;
 1909|      0|			psl_mtime[it] = st.st_mtime;
 1910|      0|		}
 1911|      0|	}
 1912|       |
 1913|    843|	return n;
 1914|    843|}

