summaryrefslogtreecommitdiffstats
path: root/lib/isc/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/isc/tests/Atffile33
-rw-r--r--lib/isc/tests/Kyuafile32
-rw-r--r--lib/isc/tests/Makefile.in177
-rw-r--r--lib/isc/tests/aes_test.c294
-rw-r--r--lib/isc/tests/atomic_test.c354
-rw-r--r--lib/isc/tests/buffer_test.c203
-rw-r--r--lib/isc/tests/counter_test.c64
-rw-r--r--lib/isc/tests/errno_test.c105
-rw-r--r--lib/isc/tests/file_test.c136
-rw-r--r--lib/isc/tests/hash_test.c2038
-rw-r--r--lib/isc/tests/heap_test.c87
-rw-r--r--lib/isc/tests/ht_test.c362
-rw-r--r--lib/isc/tests/inet_ntop_test.c62
-rw-r--r--lib/isc/tests/isctest.c194
-rw-r--r--lib/isc/tests/isctest.h64
-rw-r--r--lib/isc/tests/lex_test.c111
-rw-r--r--lib/isc/tests/mem_test.c272
-rw-r--r--lib/isc/tests/netaddr_test.c157
-rw-r--r--lib/isc/tests/parse_test.c64
-rw-r--r--lib/isc/tests/pool_test.c179
-rw-r--r--lib/isc/tests/print_test.c184
-rw-r--r--lib/isc/tests/queue_test.c137
-rw-r--r--lib/isc/tests/radix_test.c89
-rw-r--r--lib/isc/tests/random_test.c670
-rw-r--r--lib/isc/tests/regex_test.c1121
-rw-r--r--lib/isc/tests/result_test.c56
-rw-r--r--lib/isc/tests/safe_test.c112
-rw-r--r--lib/isc/tests/sockaddr_test.c166
-rw-r--r--lib/isc/tests/socket_test.c923
-rw-r--r--lib/isc/tests/symtab_test.c140
-rw-r--r--lib/isc/tests/task_test.c1474
-rw-r--r--lib/isc/tests/taskpool_test.c204
-rw-r--r--lib/isc/tests/testdata/file/keep0
-rw-r--r--lib/isc/tests/time_test.c46
-rw-r--r--lib/isc/tests/timer_test.c593
35 files changed, 10903 insertions, 0 deletions
diff --git a/lib/isc/tests/Atffile b/lib/isc/tests/Atffile
new file mode 100644
index 0000000..8681844
--- /dev/null
+++ b/lib/isc/tests/Atffile
@@ -0,0 +1,33 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = bind9
+
+tp: aes_test
+tp: atomic_test
+tp: buffer_test
+tp: counter_test
+tp: errno_test
+tp: file_test
+tp: hash_test
+tp: heap_test
+tp: ht_test
+tp: inet_ntop_test
+tp: lex_test
+tp: mem_test
+tp: netaddr_test
+tp: parse_test
+tp: pool_test
+tp: print_test
+tp: queue_test
+tp: radix_test
+tp: random_test
+tp: regex_test
+tp: result_test
+tp: safe_test
+tp: sockaddr_test
+tp: socket_test
+tp: symtab_test
+tp: task_test
+tp: taskpool_test
+tp: time_test
+tp: timer_test
diff --git a/lib/isc/tests/Kyuafile b/lib/isc/tests/Kyuafile
new file mode 100644
index 0000000..1c510c1
--- /dev/null
+++ b/lib/isc/tests/Kyuafile
@@ -0,0 +1,32 @@
+syntax(2)
+test_suite('bind9')
+
+atf_test_program{name='aes_test'}
+atf_test_program{name='atomic_test'}
+atf_test_program{name='buffer_test'}
+atf_test_program{name='counter_test'}
+atf_test_program{name='errno_test'}
+atf_test_program{name='file_test'}
+atf_test_program{name='hash_test'}
+atf_test_program{name='heap_test'}
+atf_test_program{name='ht_test'}
+atf_test_program{name='inet_ntop_test'}
+atf_test_program{name='lex_test'}
+atf_test_program{name='mem_test'}
+atf_test_program{name='netaddr_test'}
+atf_test_program{name='parse_test'}
+atf_test_program{name='pool_test'}
+atf_test_program{name='print_test'}
+atf_test_program{name='queue_test'}
+atf_test_program{name='radix_test'}
+atf_test_program{name='random_test'}
+atf_test_program{name='regex_test'}
+atf_test_program{name='result_test'}
+atf_test_program{name='safe_test'}
+atf_test_program{name='sockaddr_test'}
+atf_test_program{name='socket_test'}
+atf_test_program{name='symtab_test'}
+atf_test_program{name='task_test'}
+atf_test_program{name='taskpool_test'}
+atf_test_program{name='time_test'}
+atf_test_program{name='timer_test'}
diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in
new file mode 100644
index 0000000..add8068
--- /dev/null
+++ b/lib/isc/tests/Makefile.in
@@ -0,0 +1,177 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+# Attempt to disable parallel processing.
+.NOTPARALLEL:
+.NO_PARALLEL:
+
+VERSION=@BIND9_VERSION@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. -Iinclude ${ISC_INCLUDES} @ISC_OPENSSL_INC@
+CDEFINES = @CRYPTO@ -DTESTS="\"${top_builddir}/lib/isc/tests/\""
+
+ISCLIBS = ../libisc.@A@ @ISC_OPENSSL_LIBS@
+ISCDEPLIBS = ../libisc.@A@
+
+LIBS = @LIBS@ @ATFLIBS@
+
+OBJS = isctest.@O@
+SRCS = isctest.c aes_test.c atomic_test.c buffer_test.c \
+ counter_test.c errno_test.c file_test.c hash_test.c \
+ heap_test.c ht_test.c inet_ntop_test.c lex_test.c \
+ mem_test.c netaddr_test.c parse_test.c pool_test.c \
+ print_test.c queue_test.c radix_test.c random_test.c \
+ regex_test.c result_test.c safe_test.c sockaddr_test.c \
+ socket_test.c socket_test.c symtab_test.c task_test.c \
+ taskpool_test.c time_test.c timer_test.c
+
+SUBDIRS =
+TARGETS = aes_test@EXEEXT@ atomic_test@EXEEXT@ buffer_test@EXEEXT@ \
+ counter_test@EXEEXT@ errno_test@EXEEXT@ file_test@EXEEXT@ \
+ hash_test@EXEEXT@ heap_test@EXEEXT@ ht_test@EXEEXT@ \
+ inet_ntop_test@EXEEXT@ lex_test@EXEEXT@ mem_test@EXEEXT@ \
+ netaddr_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \
+ print_test@EXEEXT@ queue_test@EXEEXT@ radix_test@EXEEXT@ \
+ random_test@EXEEXT@ regex_test@EXEEXT@ result_test@EXEEXT@ \
+ safe_test@EXEEXT@ sockaddr_test@EXEEXT@ socket_test@EXEEXT@ \
+ socket_test@EXEEXT@ symtab_test@EXEEXT@ task_test@EXEEXT@ \
+ taskpool_test@EXEEXT@ time_test@EXEEXT@ timer_test@EXEEXT@
+
+@BIND9_MAKE_RULES@
+
+atomic_test@EXEEXT@: atomic_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ atomic_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+aes_test@EXEEXT@: aes_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ aes_test.@O@ ${ISCLIBS} ${LIBS}
+
+buffer_test@EXEEXT@: buffer_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ buffer_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+counter_test@EXEEXT@: counter_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ counter_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+errno_test@EXEEXT@: errno_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ errno_test.@O@ ${ISCLIBS} ${LIBS}
+
+file_test@EXEEXT@: file_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ file_test.@O@ ${ISCLIBS} ${LIBS}
+
+hash_test@EXEEXT@: hash_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ hash_test.@O@ ${ISCLIBS} ${LIBS}
+
+heap_test@EXEEXT@: heap_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ heap_test.@O@ ${ISCLIBS} ${LIBS}
+
+ht_test@EXEEXT@: ht_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ ht_test.@O@ ${ISCLIBS} ${LIBS}
+
+inet_ntop_test.c.@O@: ${top_srcdir}/lib/isc/ntop_test.c
+inet_ntop_test@EXEEXT@: inet_ntop_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ inet_ntop_test.@O@ ${ISCLIBS} ${LIBS}
+
+lex_test@EXEEXT@: lex_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ lex_test.@O@ ${ISCLIBS} ${LIBS}
+
+parse_test@EXEEXT@: parse_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ parse_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+pool_test@EXEEXT@: pool_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ pool_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+print_test.@O@: ${top_srcdir}/lib/isc/print.c
+print_test@EXEEXT@: print_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ print_test.@O@ ${ISCLIBS} ${LIBS}
+
+queue_test@EXEEXT@: queue_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ queue_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+radix_test@EXEEXT@: radix_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ radix_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+random_test@EXEEXT@: random_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ random_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+regex_test@EXEEXT@: regex_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ regex_test.@O@ ${ISCLIBS} ${LIBS}
+
+mem_test@EXEEXT@: mem_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ mem_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+netaddr_test@EXEEXT@: netaddr_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ netaddr_test.@O@ ${ISCLIBS} ${LIBS}
+
+result_test@EXEEXT@: result_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ result_test.@O@ ${ISCLIBS} ${LIBS}
+
+safe_test@EXEEXT@: safe_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ safe_test.@O@ ${ISCLIBS} ${LIBS}
+
+sockaddr_test@EXEEXT@: sockaddr_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sockaddr_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+socket_test@EXEEXT@: socket_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ socket_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+symtab_test@EXEEXT@: symtab_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ symtab_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+task_test@EXEEXT@: task_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ task_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+taskpool_test@EXEEXT@: taskpool_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ taskpool_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+time_test@EXEEXT@: time_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ time_test.@O@ ${ISCLIBS} ${LIBS}
+
+timer_test@EXEEXT@: timer_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ timer_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+unit::
+ sh ${top_builddir}/unit/unittest.sh
+
+clean distclean::
+ rm -f ${TARGETS}
+ rm -f atf.out
diff --git a/lib/isc/tests/aes_test.c b/lib/isc/tests/aes_test.c
new file mode 100644
index 0000000..9c15b52
--- /dev/null
+++ b/lib/isc/tests/aes_test.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+
+/* ! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/aes.h>
+#include <isc/buffer.h>
+#include <isc/hex.h>
+#include <isc/platform.h>
+#include <isc/region.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_WANTAES
+
+/*
+ * Test data from NIST KAT
+ */
+
+isc_result_t
+tohexstr(unsigned char *d, char *out);
+
+size_t
+fromhexstr(const char *in, unsigned char *d);
+
+unsigned char plaintext[3 * ISC_AES_BLOCK_LENGTH];
+unsigned char ciphertext[ISC_AES_BLOCK_LENGTH];
+char str[2 * ISC_AES_BLOCK_LENGTH + 1];
+unsigned char key[ISC_AES256_KEYLENGTH + 1];
+size_t len;
+
+isc_result_t
+tohexstr(unsigned char *d, char *out) {
+ isc_buffer_t b;
+ isc_region_t r;
+
+ isc_buffer_init(&b, out, 2 * ISC_AES_BLOCK_LENGTH + 1);
+ r.base = d;
+ r.length = ISC_AES_BLOCK_LENGTH;
+ return (isc_hex_totext(&r, 0, "", &b));
+}
+
+size_t
+fromhexstr(const char *in, unsigned char *d)
+{
+ isc_buffer_t b;
+ isc_result_t ret;
+
+ isc_buffer_init(&b, d, ISC_AES256_KEYLENGTH + 1);
+ ret = isc_hex_decodestring(in, &b);
+ if (ret != ISC_R_SUCCESS)
+ return 0;
+ return isc_buffer_usedlength(&b);
+}
+
+typedef struct aes_testcase {
+ const char *key;
+ const char *input;
+ const char *result;
+} aes_testcase_t;
+
+
+ATF_TC(isc_aes128);
+ATF_TC_HEAD(isc_aes128, tc) {
+ atf_tc_set_md_var(tc, "descr", "AES 128 test vectors");
+}
+ATF_TC_BODY(isc_aes128, tc) {
+ UNUSED(tc);
+
+ aes_testcase_t testcases[] = {
+ /* Test 1 (KAT ECBVarTxt128 #3) */
+ {
+ "00000000000000000000000000000000",
+ "F0000000000000000000000000000000",
+ "96D9FD5CC4F07441727DF0F33E401A36"
+ },
+ /* Test 2 (KAT ECBVarTxt128 #123) */
+ {
+ "00000000000000000000000000000000",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "F9B0FDA0C4A898F5B9E6F661C4CE4D07"
+ },
+ /* Test 3 (KAT ECBVarKey128 #3) */
+ {
+ "F0000000000000000000000000000000",
+ "00000000000000000000000000000000",
+ "970014D634E2B7650777E8E84D03CCD8"
+ },
+ /* Test 4 (KAT ECBVarKey128 #123) */
+ {
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "00000000000000000000000000000000",
+ "41C78C135ED9E98C096640647265DA1E"
+ },
+ /* Test 5 (KAT ECBGFSbox128 #3) */
+ {
+ "00000000000000000000000000000000",
+ "6A118A874519E64E9963798A503F1D35",
+ "DC43BE40BE0E53712F7E2BF5CA707209"
+ },
+ /* Test 6 (KAT ECBKeySbox128 #3) */
+ {
+ "B6364AC4E1DE1E285EAF144A2415F7A0",
+ "00000000000000000000000000000000",
+ "5D9B05578FC944B3CF1CCF0E746CD581"
+ },
+ { NULL, NULL, NULL }
+ };
+
+ aes_testcase_t *testcase = testcases;
+
+ while (testcase->key != NULL) {
+ len = fromhexstr(testcase->key, key);
+ ATF_CHECK_EQ(len, ISC_AES128_KEYLENGTH);
+ len = fromhexstr(testcase->input, plaintext);
+ ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH);
+ isc_aes128_crypt(key, plaintext, ciphertext);
+ ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_aes192);
+ATF_TC_HEAD(isc_aes192, tc) {
+ atf_tc_set_md_var(tc, "descr", "AES 192 test vectors");
+}
+ATF_TC_BODY(isc_aes192, tc) {
+ UNUSED(tc);
+
+ aes_testcase_t testcases[] = {
+ /* Test 1 (KAT ECBVarTxt192 #3) */
+ {
+ "000000000000000000000000000000000000000000000000",
+ "F0000000000000000000000000000000",
+ "2A560364CE529EFC21788779568D5555"
+ },
+ /* Test 2 (KAT ECBVarTxt192 #123) */
+ {
+ "000000000000000000000000000000000000000000000000",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "2AABB999F43693175AF65C6C612C46FB"
+ },
+ /* Test 3 (KAT ECBVarKey192 #3) */
+ {
+ "F00000000000000000000000000000000000000000000000",
+ "00000000000000000000000000000000",
+ "180B09F267C45145DB2F826C2582D35C"
+ },
+ /* Test 4 (KAT ECBVarKey192 #187) */
+ {
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "00000000000000000000000000000000",
+ "EACF1E6C4224EFB38900B185AB1DFD42"
+ },
+ /* Test 5 (KAT ECBGFSbox192 #3) */
+ {
+ "000000000000000000000000000000000000000000000000",
+ "51719783D3185A535BD75ADC65071CE1",
+ "4F354592FF7C8847D2D0870CA9481B7C"
+ },
+ /* Test 6 (KAT ECBKeySbox192 #3) */
+ {
+ "CD62376D5EBB414917F0C78F05266433DC9192A1EC943300",
+ "00000000000000000000000000000000",
+ "7F6C25FF41858561BB62F36492E93C29"
+ },
+ { NULL, NULL, NULL }
+ };
+
+ aes_testcase_t *testcase = testcases;
+
+ while (testcase->key != NULL) {
+ len = fromhexstr(testcase->key, key);
+ ATF_CHECK_EQ(len, ISC_AES192_KEYLENGTH);
+ len = fromhexstr(testcase->input, plaintext);
+ ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH);
+ isc_aes192_crypt(key, plaintext, ciphertext);
+ ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_aes256);
+ATF_TC_HEAD(isc_aes256, tc) {
+ atf_tc_set_md_var(tc, "descr", "AES 256 test vectors");
+}
+ATF_TC_BODY(isc_aes256, tc) {
+ UNUSED(tc);
+
+ aes_testcase_t testcases[] = {
+ /* Test 1 (KAT ECBVarTxt256 #3) */
+ {
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "F0000000000000000000000000000000",
+ "7F2C5ECE07A98D8BEE13C51177395FF7"
+ },
+ /* Test 2 (KAT ECBVarTxt256 #123) */
+ {
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "7240E524BC51D8C4D440B1BE55D1062C"
+ },
+ /* Test 3 (KAT ECBVarKey256 #3) */
+ {
+ "F0000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "00000000000000000000000000000000",
+ "1C777679D50037C79491A94DA76A9A35"
+ },
+ /* Test 4 (KAT ECBVarKey256 #251) */
+ {
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "00000000000000000000000000000000",
+ "03720371A04962EAEA0A852E69972858"
+ },
+ /* Test 5 (KAT ECBGFSbox256 #3) */
+ {
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "8A560769D605868AD80D819BDBA03771",
+ "38F2C7AE10612415D27CA190D27DA8B4"
+ },
+ /* Test 6 (KAT ECBKeySbox256 #3) */
+ {
+ "984CA75F4EE8D706F46C2D98C0BF4A45"
+ "F5B00D791C2DFEB191B5ED8E420FD627",
+ "00000000000000000000000000000000",
+ "4307456A9E67813B452E15FA8FFFE398"
+ },
+ { NULL, NULL, NULL }
+ };
+
+ aes_testcase_t *testcase = testcases;
+
+ while (testcase->key != NULL) {
+ len = fromhexstr(testcase->key, key);
+ ATF_CHECK_EQ(len, ISC_AES256_KEYLENGTH);
+ len = fromhexstr(testcase->input, plaintext);
+ ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH);
+ isc_aes256_crypt(key, plaintext, ciphertext);
+ ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+#else
+ATF_TC(untested);
+ATF_TC_HEAD(untested, tc) {
+ atf_tc_set_md_var(tc, "descr", "skipping aes test");
+}
+ATF_TC_BODY(untested, tc) {
+ UNUSED(tc);
+ atf_tc_skip("AES not available");
+}
+#endif
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+#ifdef ISC_PLATFORM_WANTAES
+ ATF_TP_ADD_TC(tp, isc_aes128);
+ ATF_TP_ADD_TC(tp, isc_aes192);
+ ATF_TP_ADD_TC(tp, isc_aes256);
+#else
+ ATF_TP_ADD_TC(tp, untested);
+#endif
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/atomic_test.c b/lib/isc/tests/atomic_test.c
new file mode 100644
index 0000000..8013010
--- /dev/null
+++ b/lib/isc/tests/atomic_test.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#include <isc/atomic.h>
+#include <isc/print.h>
+#include <isc/result.h>
+
+#include "isctest.h"
+
+#define TASKS 32
+#define ITERATIONS 1000
+#define COUNTS_PER_ITERATION 1000
+#define INCREMENT_64 (int64_t)0x0000000010000000
+#define EXPECTED_COUNT_32 (TASKS * ITERATIONS * COUNTS_PER_ITERATION)
+#define EXPECTED_COUNT_64 (TASKS * ITERATIONS * COUNTS_PER_ITERATION * INCREMENT_64)
+
+typedef struct {
+ uint32_t iteration;
+} counter_t;
+
+counter_t counters[TASKS];
+
+#if defined(ISC_PLATFORM_HAVEXADD)
+static int32_t counter_32;
+
+static void
+do_xadd(isc_task_t *task, isc_event_t *ev) {
+ counter_t *state = (counter_t *)ev->ev_arg;
+ int i;
+
+ for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
+ isc_atomic_xadd(&counter_32, 1);
+ }
+
+ state->iteration++;
+ if (state->iteration < ITERATIONS) {
+ isc_task_send(task, &ev);
+ } else {
+ isc_event_free(&ev);
+ }
+}
+
+ATF_TC(atomic_xadd);
+ATF_TC_HEAD(atomic_xadd, tc) {
+ atf_tc_set_md_var(tc, "descr", "atomic XADD");
+}
+ATF_TC_BODY(atomic_xadd, tc) {
+ isc_result_t result;
+ isc_task_t *tasks[TASKS];
+ isc_event_t *event = NULL;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ memset(counters, 0, sizeof(counters));
+ counter_32 = 0;
+
+ /*
+ * Create our tasks, and allocate an event to get the counters going.
+ */
+ for (i = 0 ; i < TASKS ; i++) {
+ tasks[i] = NULL;
+ ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
+ ISC_R_SUCCESS);
+ event = isc_event_allocate(mctx, NULL, 1000, do_xadd,
+ &counters[i],
+ sizeof(struct isc_event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_sendanddetach(&tasks[i], &event);
+ }
+
+ isc_test_end();
+
+ printf("32-bit counter %d, expected %d\n",
+ counter_32, EXPECTED_COUNT_32);
+
+ ATF_CHECK_EQ(counter_32, EXPECTED_COUNT_32);
+ counter_32 = 0;
+}
+#endif
+
+#if defined(ISC_PLATFORM_HAVEXADDQ)
+static int64_t counter_64;
+
+static void
+do_xaddq(isc_task_t *task, isc_event_t *ev) {
+ counter_t *state = (counter_t *)ev->ev_arg;
+ int i;
+
+ for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
+ isc_atomic_xaddq(&counter_64, INCREMENT_64);
+ }
+
+ state->iteration++;
+ if (state->iteration < ITERATIONS) {
+ isc_task_send(task, &ev);
+ } else {
+ isc_event_free(&ev);
+ }
+}
+
+ATF_TC(atomic_xaddq);
+ATF_TC_HEAD(atomic_xaddq, tc) {
+ atf_tc_set_md_var(tc, "descr", "atomic XADDQ");
+}
+ATF_TC_BODY(atomic_xaddq, tc) {
+ isc_result_t result;
+ isc_task_t *tasks[TASKS];
+ isc_event_t *event = NULL;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ memset(counters, 0, sizeof(counters));
+ counter_64 = 0;
+
+ /*
+ * Create our tasks, and allocate an event to get the counters going.
+ */
+ for (i = 0 ; i < TASKS ; i++) {
+ tasks[i] = NULL;
+ ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
+ ISC_R_SUCCESS);
+ event = isc_event_allocate(mctx, NULL, 1000, do_xaddq,
+ &counters[i],
+ sizeof(struct isc_event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_sendanddetach(&tasks[i], &event);
+ }
+
+ isc_test_end();
+
+ printf("64-bit counter %" PRId64 ", "
+ "expected %" PRId64 "\n",
+ counter_64, EXPECTED_COUNT_64);
+
+ ATF_CHECK_EQ(counter_64, EXPECTED_COUNT_64);
+ counter_32 = 0;
+}
+#endif
+
+#if defined(ISC_PLATFORM_HAVEATOMICSTORE)
+static int32_t store_32;
+
+static void
+do_store(isc_task_t *task, isc_event_t *ev) {
+ counter_t *state = (counter_t *)ev->ev_arg;
+ int i;
+ uint32_t r;
+ uint32_t val;
+
+ r = random() % 256;
+ val = (r << 24) | (r << 16) | (r << 8) | r;
+
+ for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
+ isc_atomic_store(&store_32, val);
+ }
+
+ state->iteration++;
+ if (state->iteration < ITERATIONS) {
+ isc_task_send(task, &ev);
+ } else {
+ isc_event_free(&ev);
+ }
+}
+
+ATF_TC(atomic_store);
+ATF_TC_HEAD(atomic_store, tc) {
+ atf_tc_set_md_var(tc, "descr", "atomic STORE");
+}
+ATF_TC_BODY(atomic_store, tc) {
+ isc_result_t result;
+ isc_task_t *tasks[TASKS];
+ isc_event_t *event = NULL;
+ uint32_t val;
+ uint32_t r;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ memset(counters, 0, sizeof(counters));
+ store_32 = 0;
+
+ /*
+ * Create our tasks, and allocate an event to get the counters
+ * going.
+ */
+ for (i = 0 ; i < TASKS ; i++) {
+ tasks[i] = NULL;
+ ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
+ ISC_R_SUCCESS);
+ event = isc_event_allocate(mctx, NULL, 1000, do_store,
+ &counters[i],
+ sizeof(struct isc_event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_sendanddetach(&tasks[i], &event);
+ }
+
+ isc_test_end();
+
+ r = store_32 & 0xff;
+ val = (r << 24) | (r << 16) | (r << 8) | r;
+
+ printf("32-bit store 0x%x, expected 0x%x\n",
+ (uint32_t) store_32, val);
+
+ ATF_CHECK_EQ((uint32_t) store_32, val);
+ store_32 = 0;
+}
+#endif
+
+#if defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
+static int64_t store_64;
+
+static void
+do_storeq(isc_task_t *task, isc_event_t *ev) {
+ counter_t *state = (counter_t *)ev->ev_arg;
+ int i;
+ uint8_t r;
+ uint64_t val;
+
+ r = random() % 256;
+ val = (((uint64_t) r << 24) |
+ ((uint64_t) r << 16) |
+ ((uint64_t) r << 8) |
+ (uint64_t) r);
+ val |= ((uint64_t) val << 32);
+
+ for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
+ isc_atomic_storeq(&store_64, val);
+ }
+
+ state->iteration++;
+ if (state->iteration < ITERATIONS) {
+ isc_task_send(task, &ev);
+ } else {
+ isc_event_free(&ev);
+ }
+}
+
+ATF_TC(atomic_storeq);
+ATF_TC_HEAD(atomic_storeq, tc) {
+ atf_tc_set_md_var(tc, "descr", "atomic STOREQ");
+}
+ATF_TC_BODY(atomic_storeq, tc) {
+ isc_result_t result;
+ isc_task_t *tasks[TASKS];
+ isc_event_t *event = NULL;
+ uint64_t val;
+ uint32_t r;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ memset(counters, 0, sizeof(counters));
+ store_64 = 0;
+
+ /*
+ * Create our tasks, and allocate an event to get the counters
+ * going.
+ */
+ for (i = 0 ; i < TASKS ; i++) {
+ tasks[i] = NULL;
+ ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
+ ISC_R_SUCCESS);
+ event = isc_event_allocate(mctx, NULL, 1000, do_storeq,
+ &counters[i],
+ sizeof(struct isc_event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_sendanddetach(&tasks[i], &event);
+ }
+
+ isc_test_end();
+
+ r = store_64 & 0xff;
+ val = (((uint64_t) r << 24) |
+ ((uint64_t) r << 16) |
+ ((uint64_t) r << 8) |
+ (uint64_t) r);
+ val |= ((uint64_t) val << 32);
+
+ printf("64-bit store 0x%" PRIx64 ", "
+ "expected 0x%" PRIx64 "\n",
+ (uint64_t) store_64, val);
+
+ ATF_CHECK_EQ((uint64_t) store_64, val);
+ store_64 = 0;
+}
+#endif
+
+#if !defined(ISC_PLATFORM_HAVEXADD) && \
+ !defined(ISC_PLATFORM_HAVEXADDQ) && \
+ !defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
+ATF_TC(untested);
+ATF_TC_HEAD(untested, tc) {
+ atf_tc_set_md_var(tc, "descr", "skipping aes test");
+}
+ATF_TC_BODY(untested, tc) {
+ UNUSED(tc);
+ atf_tc_skip("AES not available");
+}
+#endif /* !HAVEXADD, !HAVEXADDQ, !HAVEATOMICSTOREQ */
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+#if defined(ISC_PLATFORM_HAVEXADD)
+ ATF_TP_ADD_TC(tp, atomic_xadd);
+#endif
+#if defined(ISC_PLATFORM_HAVEXADDQ)
+ ATF_TP_ADD_TC(tp, atomic_xaddq);
+#endif
+#ifdef ISC_PLATFORM_HAVEATOMICSTORE
+ ATF_TP_ADD_TC(tp, atomic_store);
+#endif
+#if defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
+ ATF_TP_ADD_TC(tp, atomic_storeq);
+#endif
+#if !defined(ISC_PLATFORM_HAVEXADD) && \
+ !defined(ISC_PLATFORM_HAVEXADDQ) && \
+ !defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
+ ATF_TP_ADD_TC(tp, untested);
+#endif
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/buffer_test.c b/lib/isc/tests/buffer_test.c
new file mode 100644
index 0000000..a2d76cc
--- /dev/null
+++ b/lib/isc/tests/buffer_test.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <atf-c.h>
+
+#include "isctest.h"
+
+#include <isc/buffer.h>
+#include <isc/result.h>
+
+ATF_TC(isc_buffer_reserve);
+ATF_TC_HEAD(isc_buffer_reserve, tc) {
+ atf_tc_set_md_var(tc, "descr", "reserve space in dynamic buffers");
+}
+
+ATF_TC_BODY(isc_buffer_reserve, tc) {
+ isc_result_t result;
+ isc_buffer_t *b;
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ b = NULL;
+ result = isc_buffer_allocate(mctx, &b, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_EQ(b->length, 1024);
+
+ /*
+ * 1024 bytes should already be available, so this call does
+ * nothing.
+ */
+ result = isc_buffer_reserve(&b, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(ISC_BUFFER_VALID(b));
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 1024);
+
+ /*
+ * This call should grow it to 2048 bytes as only 1024 bytes are
+ * available in the buffer.
+ */
+ result = isc_buffer_reserve(&b, 1025);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(ISC_BUFFER_VALID(b));
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 2048);
+
+ /*
+ * 2048 bytes should already be available, so this call does
+ * nothing.
+ */
+ result = isc_buffer_reserve(&b, 2000);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(ISC_BUFFER_VALID(b));
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 2048);
+
+ /*
+ * This call should grow it to 4096 bytes as only 2048 bytes are
+ * available in the buffer.
+ */
+ result = isc_buffer_reserve(&b, 3000);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(ISC_BUFFER_VALID(b));
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 4096);
+
+ /* Consume some of the buffer so we can run the next test. */
+ isc_buffer_add(b, 4096);
+
+ /*
+ * This call should fail and leave buffer untouched.
+ */
+ result = isc_buffer_reserve(&b, UINT_MAX);
+ ATF_CHECK_EQ(result, ISC_R_NOMEMORY);
+ ATF_CHECK(ISC_BUFFER_VALID(b));
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 4096);
+
+ isc_buffer_free(&b);
+
+ isc_test_end();
+}
+
+ATF_TC(isc_buffer_reallocate);
+ATF_TC_HEAD(isc_buffer_reallocate, tc) {
+ atf_tc_set_md_var(tc, "descr", "reallocate dynamic buffers");
+}
+
+ATF_TC_BODY(isc_buffer_reallocate, tc) {
+ isc_result_t result;
+ isc_buffer_t *b;
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ b = NULL;
+ result = isc_buffer_allocate(mctx, &b, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 1024);
+
+ result = isc_buffer_reallocate(&b, 512);
+ ATF_CHECK_EQ(result, ISC_R_NOSPACE);
+ ATF_CHECK(ISC_BUFFER_VALID(b));
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 1024);
+
+ result = isc_buffer_reallocate(&b, 1536);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(ISC_BUFFER_VALID(b));
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, 1536);
+
+ isc_buffer_free(&b);
+
+ isc_test_end();
+}
+
+ATF_TC(isc_buffer_dynamic);
+ATF_TC_HEAD(isc_buffer_dynamic, tc) {
+ atf_tc_set_md_var(tc, "descr", "dynamic buffer automatic reallocation");
+}
+
+ATF_TC_BODY(isc_buffer_dynamic, tc) {
+ isc_result_t result;
+ isc_buffer_t *b;
+ size_t last_length = 10;
+ int i;
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ b = NULL;
+ result = isc_buffer_allocate(mctx, &b, last_length);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(b != NULL);
+ ATF_CHECK_EQ(b->length, last_length);
+
+ isc_buffer_setautorealloc(b, true);
+
+ isc_buffer_putuint8(b, 1);
+
+ for (i = 0; i < 1000; i++) {
+ isc_buffer_putstr(b, "thisisa24charslongstring");
+ }
+ ATF_CHECK(b->length-last_length >= 1000*24);
+ last_length+=1000*24;
+
+ for (i = 0; i < 10000; i++) {
+ isc_buffer_putuint8(b, 1);
+ }
+
+ ATF_CHECK(b->length-last_length >= 10000*1);
+ last_length += 10000*1;
+
+ for (i = 0; i < 10000; i++) {
+ isc_buffer_putuint16(b, 1);
+ }
+
+ ATF_CHECK(b->length-last_length >= 10000*2);
+
+ last_length += 10000*2;
+ for (i = 0; i < 10000; i++) {
+ isc_buffer_putuint24(b, 1);
+ }
+ ATF_CHECK(b->length-last_length >= 10000*3);
+
+ last_length+=10000*3;
+
+ for (i = 0; i < 10000; i++) {
+ isc_buffer_putuint32(b, 1);
+ }
+ ATF_CHECK(b->length-last_length >= 10000*4);
+
+
+ isc_buffer_free(&b);
+
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_buffer_reserve);
+ ATF_TP_ADD_TC(tp, isc_buffer_reallocate);
+ ATF_TP_ADD_TC(tp, isc_buffer_dynamic);
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/counter_test.c b/lib/isc/tests/counter_test.c
new file mode 100644
index 0000000..ddcdae3
--- /dev/null
+++ b/lib/isc/tests/counter_test.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#include <isc/counter.h>
+#include <isc/result.h>
+
+#include "isctest.h"
+
+ATF_TC(isc_counter);
+ATF_TC_HEAD(isc_counter, tc) {
+ atf_tc_set_md_var(tc, "descr", "isc counter object");
+}
+ATF_TC_BODY(isc_counter, tc) {
+ isc_result_t result;
+ isc_counter_t *counter = NULL;
+ int i;
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_counter_create(mctx, 0, &counter);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ for (i = 0; i < 10; i++) {
+ result = isc_counter_increment(counter);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ }
+
+ ATF_CHECK_EQ(isc_counter_used(counter), 10);
+
+ isc_counter_setlimit(counter, 15);
+ for (i = 0; i < 10; i++) {
+ result = isc_counter_increment(counter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+
+ ATF_CHECK_EQ(isc_counter_used(counter), 15);
+
+ isc_counter_detach(&counter);
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_counter);
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/errno_test.c b/lib/isc/tests/errno_test.c
new file mode 100644
index 0000000..e45bdd8
--- /dev/null
+++ b/lib/isc/tests/errno_test.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <sys/errno.h>
+
+#include <atf-c.h>
+
+#include <isc/errno.h>
+#include <isc/result.h>
+
+typedef struct {
+ int err;
+ isc_result_t result;
+} testpair_t;
+
+testpair_t testpair[] = {
+ { EPERM, ISC_R_NOPERM },
+ { ENOENT, ISC_R_FILENOTFOUND },
+ { EIO, ISC_R_IOERROR },
+ { EBADF, ISC_R_INVALIDFILE },
+ { ENOMEM, ISC_R_NOMEMORY },
+ { EACCES, ISC_R_NOPERM },
+ { EEXIST, ISC_R_FILEEXISTS },
+ { ENOTDIR, ISC_R_INVALIDFILE },
+ { EINVAL, ISC_R_INVALIDFILE },
+ { ENFILE, ISC_R_TOOMANYOPENFILES },
+ { EMFILE, ISC_R_TOOMANYOPENFILES },
+ { EPIPE, ISC_R_CONNECTIONRESET },
+ { ENAMETOOLONG, ISC_R_INVALIDFILE },
+ { ELOOP, ISC_R_INVALIDFILE },
+#ifdef EOVERFLOW
+ { EOVERFLOW, ISC_R_RANGE },
+#endif
+#ifdef EAFNOSUPPORT
+ { EAFNOSUPPORT, ISC_R_FAMILYNOSUPPORT },
+#endif
+#ifdef EADDRINUSE
+ { EADDRINUSE, ISC_R_ADDRINUSE },
+#endif
+ { EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL },
+#ifdef ENETDOWN
+ { ENETDOWN, ISC_R_NETDOWN },
+#endif
+#ifdef ENETUNREACH
+ { ENETUNREACH, ISC_R_NETUNREACH },
+#endif
+#ifdef ECONNABORTED
+ { ECONNABORTED, ISC_R_CONNECTIONRESET },
+#endif
+#ifdef ECONNRESET
+ { ECONNRESET, ISC_R_CONNECTIONRESET },
+#endif
+#ifdef ENOBUFS
+ { ENOBUFS, ISC_R_NORESOURCES },
+#endif
+#ifdef ENOTCONN
+ { ENOTCONN, ISC_R_NOTCONNECTED },
+#endif
+#ifdef ETIMEDOUT
+ { ETIMEDOUT, ISC_R_TIMEDOUT },
+#endif
+ { ECONNREFUSED, ISC_R_CONNREFUSED },
+#ifdef EHOSTDOWN
+ { EHOSTDOWN, ISC_R_HOSTDOWN },
+#endif
+#ifdef EHOSTUNREACH
+ { EHOSTUNREACH, ISC_R_HOSTUNREACH },
+#endif
+ { 0, ISC_R_UNEXPECTED }
+};
+
+ATF_TC(isc_errno_toresult);
+ATF_TC_HEAD(isc_errno_toresult, tc) {
+ atf_tc_set_md_var(tc, "descr", "convert errno to ISC result");
+}
+ATF_TC_BODY(isc_errno_toresult, tc) {
+ isc_result_t result, expect;
+ size_t i;
+
+ for (i = 0; i < sizeof(testpair)/sizeof(testpair[0]); i++) {
+ result = isc_errno_toresult(testpair[i].err);
+ expect = testpair[i].result;
+ ATF_CHECK(result == expect);
+ }
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_errno_toresult);
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/file_test.c b/lib/isc/tests/file_test.c
new file mode 100644
index 0000000..3dadb52
--- /dev/null
+++ b/lib/isc/tests/file_test.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include <isc/file.h>
+#include <isc/result.h>
+
+ATF_TC(isc_file_sanitize);
+ATF_TC_HEAD(isc_file_sanitize, tc) {
+ atf_tc_set_md_var(tc, "descr", "sanitized filenames");
+}
+
+#define NAME "internal"
+#define SHA "3bed2cb3a3acf7b6a8ef408420cc682d5520e26976d354254f528c965612054f"
+#define TRUNC_SHA "3bed2cb3a3acf7b6"
+
+#define BAD1 "in/internal"
+#define BADHASH1 "8bbb97a888791399"
+
+#define BAD2 "Internal"
+#define BADHASH2 "2ea1842b445b0c81"
+
+#define F(x) "testdata/file/" x ".test"
+
+static void
+touch(const char *filename) {
+ int fd;
+
+ unlink(filename);
+ fd = creat(filename, 0644);
+ if (fd != -1)
+ close(fd);
+}
+
+ATF_TC_BODY(isc_file_sanitize, tc) {
+ isc_result_t result;
+ char buf[1024];
+
+ ATF_CHECK(chdir(TESTS) != -1);
+
+ result = isc_file_sanitize("testdata/file", NAME, "test", buf, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(strcmp(buf, F(NAME)) == 0);
+
+ touch(F(TRUNC_SHA));
+ result = isc_file_sanitize("testdata/file", NAME, "test", buf, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(strcmp(buf, F(TRUNC_SHA)) == 0);
+
+ touch(F(SHA));
+ result = isc_file_sanitize("testdata/file", NAME, "test", buf, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(strcmp(buf, F(SHA)) == 0);
+
+ result = isc_file_sanitize("testdata/file", BAD1, "test", buf, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(strcmp(buf, F(BADHASH1)) == 0);
+
+ result = isc_file_sanitize("testdata/file", BAD2, "test", buf, 1024);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK(strcmp(buf, F(BADHASH2)) == 0);
+
+ unlink(F(TRUNC_SHA));
+ unlink(F(SHA));
+}
+
+ATF_TC(isc_file_template);
+ATF_TC_HEAD(isc_file_template, tc) {
+ atf_tc_set_md_var(tc, "descr", "file template");
+}
+
+ATF_TC_BODY(isc_file_template, tc) {
+ isc_result_t result;
+ char buf[1024];
+
+ ATF_CHECK(chdir(TESTS) != -1);
+
+ result = isc_file_template("/absolute/path", "file-XXXXXXXX",
+ buf, sizeof(buf));
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(buf, "/absolute/file-XXXXXXXX");
+
+ result = isc_file_template("relative/path", "file-XXXXXXXX",
+ buf, sizeof(buf));
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(buf, "relative/file-XXXXXXXX");
+
+ result = isc_file_template("/trailing/slash/", "file-XXXXXXXX",
+ buf, sizeof(buf));
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(buf, "/trailing/slash/file-XXXXXXXX");
+
+ result = isc_file_template("relative/trailing/slash/", "file-XXXXXXXX",
+ buf, sizeof(buf));
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(buf, "relative/trailing/slash/file-XXXXXXXX");
+
+ result = isc_file_template("/", "file-XXXXXXXX", buf, sizeof(buf));
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(buf, "/file-XXXXXXXX");
+
+ result = isc_file_template("noslash", "file-XXXXXXXX",
+ buf, sizeof(buf));
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(buf, "file-XXXXXXXX");
+
+ result = isc_file_template(NULL, "file-XXXXXXXX", buf, sizeof(buf));
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(buf, "file-XXXXXXXX");
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_file_sanitize);
+ ATF_TP_ADD_TC(tp, isc_file_template);
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/hash_test.c b/lib/isc/tests/hash_test.c
new file mode 100644
index 0000000..8f12342
--- /dev/null
+++ b/lib/isc/tests/hash_test.c
@@ -0,0 +1,2038 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/* ! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/hash.h>
+
+#include <isc/crc64.h>
+#include <isc/hmacmd5.h>
+#include <isc/hmacsha.h>
+#include <isc/md5.h>
+#include <isc/sha1.h>
+#include <isc/util.h>
+#include <isc/print.h>
+#include <isc/string.h>
+
+#include <pk11/site.h>
+
+/*
+ * Test data from RFC6234
+ */
+
+unsigned char digest[ISC_SHA512_DIGESTLENGTH];
+unsigned char buffer[1024];
+const char *s;
+char str[2 * ISC_SHA512_DIGESTLENGTH + 3];
+unsigned char key[20];
+
+/*
+ * Precondition: a hexadecimal number in *d, the length of that number in len,
+ * and a pointer to a character array to put the output (*out).
+ * Postcondition: A String representation of the given hexadecimal number is
+ * placed into the array *out
+ *
+ * 'out' MUST point to an array of at least len * 2 + 1
+ *
+ * Return values: ISC_R_SUCCESS if the operation is sucessful
+ */
+static isc_result_t
+tohexstr(unsigned char *d, unsigned int len, char *out, size_t out_size) {
+ char c_ret[] = "AA";
+ unsigned int i;
+
+ out[0] = '\0';
+ strlcat(out, "0x", out_size);
+ for (i = 0; i < len; i++) {
+ snprintf(c_ret, sizeof(c_ret), "%02X", d[i]);
+ strlcat(out, c_ret, out_size);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+
+#define TEST_INPUT(x) (x), sizeof(x)-1
+
+typedef struct hash_testcase {
+ const char *input;
+ size_t input_len;
+ const char *result;
+ int repeats;
+} hash_testcase_t;
+
+typedef struct hash_test_key {
+ const char *key;
+ const int len;
+} hash_test_key_t;
+
+/* non-hmac tests */
+
+ATF_TC(isc_sha1);
+ATF_TC_HEAD(isc_sha1, tc) {
+ atf_tc_set_md_var(tc, "descr", "sha1 examples from RFC4634");
+}
+ATF_TC_BODY(isc_sha1, tc) {
+ isc_sha1_t sha1;
+ int i;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("abc"),
+ "0xA9993E364706816ABA3E25717850C26C9CD0D89D",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("abcdbcdecdefdefgefghfghighijhijkijk"
+ "ljklmklmnlmnomnopnopq"),
+ "0x84983E441C3BD26EBAAE4AA1F95129E5E54670F1",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("a") /* times 1000000 */,
+ "0x34AA973CD4C4DAA4F61EEB2BDBAD27316534016F",
+ 1000000
+ },
+ /* Test 4 -- exact multiple of 512 bits */
+ {
+ TEST_INPUT("01234567012345670123456701234567"),
+ "0xDEA356A2CDDD90C7A7ECEDC5EBB563934F460452",
+ 20 /* 20 times */
+ },
+#if 0
+ /* Test 5 -- optional feature, not implemented */
+ {
+ TEST_INPUT(""),
+ /* "extrabits": 0x98 , "numberextrabits": 5 */
+ "0x29826B003B906E660EFF4027CE98AF3531AC75BA",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("\x5e"),
+ "0x5E6F80A34A9798CAFC6A5DB96CC57BA4C4DB59C2",
+ 1
+ },
+#if 0
+ /* Test 7 -- optional feature, not implemented */
+ {
+ TEST_INPUT("\x49\xb2\xae\xc2\x59\x4b\xbe\x3a"
+ "\x3b\x11\x75\x42\xd9\x4a\xc8"),
+ /* "extrabits": 0x80, "numberextrabits": 3 */
+ "0x6239781E03729919C01955B3FFA8ACB60B988340", 1 },
+#endif
+ /* Test 8 */
+ {
+ TEST_INPUT("\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46"
+ "\xaa\x55\xfe\x75\x71\x46"),
+ "0x82ABFF6605DBE1C17DEF12A394FA22A82B544A35",
+ 1
+ },
+#if 0
+ /* Test 9 -- optional feature, not implemented */
+ {
+ TEST_INPUT("\x65\xf9\x32\x99\x5b\xa4\xce\x2c\xb1\xb4"
+ "\xa2\xe7\x1a\xe7\x02\x20\xaa\xce\xc8\x96"
+ "\x2d\xd4\x49\x9c\xbd\x7c\x88\x7a\x94\xea"
+ "\xaa\x10\x1e\xa5\xaa\xbc\x52\x9b\x4e\x7e"
+ "\x43\x66\x5a\x5a\xf2\xcd\x03\xfe\x67\x8e"
+ "\xa6\xa5\x00\x5b\xba\x3b\x08\x22\x04\xc2"
+ "\x8b\x91\x09\xf4\x69\xda\xc9\x2a\xaa\xb3"
+ "\xaa\x7c\x11\xa1\xb3\x2a"),
+ /* "extrabits": 0xE0 , "numberextrabits": 3 */
+ "0x8C5B2A5DDAE5A97FC7F9D85661C672ADBF7933D4",
+ 1
+ },
+#endif
+ /* Test 10 */
+ {
+ TEST_INPUT("\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b"
+ "\x4f\xba\x15\xa1\xd5\x9f\x3f\xd8\x4d\x22"
+ "\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e"
+ "\xd1\x15\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea"
+ "\xd2\x44\x21\xde\xd9\xc3\x25\x92\xbd\x57"
+ "\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a"
+ "\x84\xd0\xcf\x1f\x7b\xee\xad\x17\x13\xe2"
+ "\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04"
+ "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83"
+ "\x6f\xd5\x56\x2a\x56\xca\xb1\xa2\x8e\x81"
+ "\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8"
+ "\x6e\x3b\x33\xa1\x08\xb0\x53\x07\xc0\x0a"
+ "\xff\x14\xa7\x68\xed\x73\x50\x60\x6a\x0f"
+ "\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57"
+ "\x7f\x9b\x38\x80\x7c\x7d\x52\x3d\x6d\x79"
+ "\x2f\x6e\xbc\x24\xa4\xec\xf2\xb3\xa4\x27"
+ "\xcd\xbb\xfb"),
+ "0xCB0082C8F197D260991BA6A460E76E202BAD27B3",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ isc_sha1_init(&sha1);
+ for(i = 0; i < testcase->repeats; i++) {
+ isc_sha1_update(&sha1,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ }
+ isc_sha1_final(&sha1, digest);
+ tohexstr(digest, ISC_SHA1_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_sha224);
+ATF_TC_HEAD(isc_sha224, tc) {
+ atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634");
+}
+ATF_TC_BODY(isc_sha224, tc) {
+ isc_sha224_t sha224;
+ int i;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("abc"),
+ "0x23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7"
+ "E36C9DA7",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("abcdbcdecdefdefgefghfghighijhijkijklj"
+ "klmklmnlmnomnopnopq"),
+ "0x75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B"
+ "1952522525",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("a"),
+ "0x20794655980C91D8BBB4C1EA97618A4BF03F42581948B2"
+ "EE4EE7AD67",
+ 1000000
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("01234567012345670123456701234567"),
+ "0x567F69F168CD7844E65259CE658FE7AADFA25216E68ECA"
+ "0EB7AB8262",
+ 20
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("\x07"),
+ "0x00ECD5F138422B8AD74C9799FD826C531BAD2FCABC7450"
+ "BEE2AA8C2A",
+ 1
+ },
+#if 0
+ /* Test 7 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 8 */
+ {
+ TEST_INPUT("\x18\x80\x40\x05\xdd\x4f\xbd\x15\x56\x29"
+ "\x9d\x6f\x9d\x93\xdf\x62"),
+ "0xDF90D78AA78821C99B40BA4C966921ACCD8FFB1E98AC38"
+ "8E56191DB1",
+ 1
+ },
+#if 0
+ /* Test 9 */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 10 */
+ {
+ TEST_INPUT("\x55\xb2\x10\x07\x9c\x61\xb5\x3a\xdd\x52"
+ "\x06\x22\xd1\xac\x97\xd5\xcd\xbe\x8c\xb3"
+ "\x3a\xa0\xae\x34\x45\x17\xbe\xe4\xd7\xba"
+ "\x09\xab\xc8\x53\x3c\x52\x50\x88\x7a\x43"
+ "\xbe\xbb\xac\x90\x6c\x2e\x18\x37\xf2\x6b"
+ "\x36\xa5\x9a\xe3\xbe\x78\x14\xd5\x06\x89"
+ "\x6b\x71\x8b\x2a\x38\x3e\xcd\xac\x16\xb9"
+ "\x61\x25\x55\x3f\x41\x6f\xf3\x2c\x66\x74"
+ "\xc7\x45\x99\xa9\x00\x53\x86\xd9\xce\x11"
+ "\x12\x24\x5f\x48\xee\x47\x0d\x39\x6c\x1e"
+ "\xd6\x3b\x92\x67\x0c\xa5\x6e\xc8\x4d\xee"
+ "\xa8\x14\xb6\x13\x5e\xca\x54\x39\x2b\xde"
+ "\xdb\x94\x89\xbc\x9b\x87\x5a\x8b\xaf\x0d"
+ "\xc1\xae\x78\x57\x36\x91\x4a\xb7\xda\xa2"
+ "\x64\xbc\x07\x9d\x26\x9f\x2c\x0d\x7e\xdd"
+ "\xd8\x10\xa4\x26\x14\x5a\x07\x76\xf6\x7c"
+ "\x87\x82\x73"),
+ "0x0B31894EC8937AD9B91BDFBCBA294D9ADEFAA18E09305E"
+ "9F20D5C3A4",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ isc_sha224_init(&sha224);
+ for(i = 0; i < testcase->repeats; i++) {
+ isc_sha224_update(&sha224,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ }
+ isc_sha224_final(digest, &sha224);
+ /*
+ *API inconsistency BUG HERE
+ * in order to be consistant with the other isc_hash_final
+ * functions the call should be
+ * isc_sha224_final(&sha224, digest);
+ */
+ tohexstr(digest, ISC_SHA224_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_sha256);
+ATF_TC_HEAD(isc_sha256, tc) {
+ atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634");
+}
+ATF_TC_BODY(isc_sha256, tc) {
+ isc_sha256_t sha256;
+ int i;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("abc"),
+ "0xBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A"
+ "9CB410FF61F20015AD",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("abcdbcdecdefdefgefghfghighijhijkijkljk"
+ "lmklmnlmnomnopnopq"),
+ "0x248D6A61D20638B8E5C026930C3E6039A33CE45964FF21"
+ "67F6ECEDD419DB06C1",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("a"),
+ "0xCDC76E5C9914FB9281A1C7E284D73E67F1809A48A49720"
+ "0E046D39CCC7112CD0",
+ 1000000 },
+ /* Test 4 */
+ {
+ TEST_INPUT("01234567012345670123456701234567"),
+ "0x594847328451BDFA85056225462CC1D867D877FB388DF0"
+ "CE35F25AB5562BFBB5",
+ 20
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("\x19"),
+ "0x68AA2E2EE5DFF96E3355E6C7EE373E3D6A4E17F75F9518"
+ "D843709C0C9BC3E3D4",
+ 1
+ },
+#if 0
+ /* Test 7 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 8 */
+ {
+ TEST_INPUT("\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3"
+ "\x88\x7a\xb2\xcd\x68\x46\x52"),
+ "0x175EE69B02BA9B58E2B0A5FD13819CEA573F3940A94F82"
+ "5128CF4209BEABB4E8",
+ 1
+ },
+#if 0
+ /* Test 9 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 10 */
+ {
+ TEST_INPUT("\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1"
+ "\x2b\x20\x52\x7a\xfe\xf0\x4d\x8a\x05\x69"
+ "\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76"
+ "\x00\x00\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08"
+ "\x3a\xa3\x9d\x81\x0d\xb3\x10\x77\x7d\xab"
+ "\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32"
+ "\x5f\x8b\x23\x74\xde\x7a\x4b\x5a\x58\xcb"
+ "\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b"
+ "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65"
+ "\x92\xec\xed\xaa\x66\xca\x82\xa2\x9d\x0c"
+ "\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4"
+ "\xc0\xa4\x3f\x8d\x79\xa3\x0a\x16\x5c\xba"
+ "\xbe\x45\x2b\x77\x4b\x9c\x71\x09\xa9\x7d"
+ "\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc"
+ "\x10\x6a\xad\x5a\x9f\xdd\x30\x82\x57\x69"
+ "\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39"
+ "\x3d\x54\xd6"),
+ "0x97DBCA7DF46D62C8A422C941DD7E835B8AD3361763F7E9"
+ "B2D95F4F0DA6E1CCBC",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ isc_sha256_init(&sha256);
+ for(i = 0; i < testcase->repeats; i++) {
+ isc_sha256_update(&sha256,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ }
+ isc_sha256_final(digest, &sha256);
+ /*
+ *API inconsistency BUG HERE
+ * in order to be consistant with the other isc_hash_final
+ * functions the call should be
+ * isc_sha224_final(&sha224, digest);
+ */
+ tohexstr(digest, ISC_SHA256_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_sha384);
+ATF_TC_HEAD(isc_sha384, tc) {
+ atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634");
+}
+ATF_TC_BODY(isc_sha384, tc) {
+ isc_sha384_t sha384;
+ int i;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("abc"),
+ "0xCB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1"
+ "631A8B605A43FF5BED8086072BA1E7CC2358BAEC"
+ "A134C825A7",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("abcdefghbcdefghicdefghijdefghijkefghijkl"
+ "fghijklmghijklmnhijklmnoijklmnopjklmnopq"
+ "klmnopqrlmnopqrsmnopqrstnopqrstu"),
+ "0x09330C33F71147E83D192FC782CD1B4753111B173B3B05"
+ "D22FA08086E3B0F712FCC7C71A557E2DB966C3E9"
+ "FA91746039",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("a"),
+ "0x9D0E1809716474CB086E834E310A4A1CED149E9C00F248"
+ "527972CEC5704C2A5B07B8B3DC38ECC4EBAE97DD"
+ "D87F3D8985",
+ 1000000
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("01234567012345670123456701234567"),
+ "0x2FC64A4F500DDB6828F6A3430B8DD72A368EB7F3A8322A"
+ "70BC84275B9C0B3AB00D27A5CC3C2D224AA6B61A"
+ "0D79FB4596",
+ 20
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 6 */
+ { TEST_INPUT("\xb9"),
+ "0xBC8089A19007C0B14195F4ECC74094FEC64F01F9092928"
+ "2C2FB392881578208AD466828B1C6C283D2722CF"
+ "0AD1AB6938",
+ 1
+ },
+#if 0
+ /* Test 7 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 8 */
+ {
+ TEST_INPUT("\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1"
+ "\x0a\x7f\x4e\x08\x59\x17\x39"),
+ "0xC9A68443A005812256B8EC76B00516F0DBB74FAB26D665"
+ "913F194B6FFB0E91EA9967566B58109CBC675CC2"
+ "08E4C823F7",
+ 1
+ },
+#if 0
+ /* Test 9 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 10 */
+ {
+ TEST_INPUT("\x39\x96\x69\xe2\x8f\x6b\x9c\x6d\xbc\xbb"
+ "\x69\x12\xec\x10\xff\xcf\x74\x79\x03\x49"
+ "\xb7\xdc\x8f\xbe\x4a\x8e\x7b\x3b\x56\x21"
+ "\xdb\x0f\x3e\x7d\xc8\x7f\x82\x32\x64\xbb"
+ "\xe4\x0d\x18\x11\xc9\xea\x20\x61\xe1\xc8"
+ "\x4a\xd1\x0a\x23\xfa\xc1\x72\x7e\x72\x02"
+ "\xfc\x3f\x50\x42\xe6\xbf\x58\xcb\xa8\xa2"
+ "\x74\x6e\x1f\x64\xf9\xb9\xea\x35\x2c\x71"
+ "\x15\x07\x05\x3c\xf4\xe5\x33\x9d\x52\x86"
+ "\x5f\x25\xcc\x22\xb5\xe8\x77\x84\xa1\x2f"
+ "\xc9\x61\xd6\x6c\xb6\xe8\x95\x73\x19\x9a"
+ "\x2c\xe6\x56\x5c\xbd\xf1\x3d\xca\x40\x38"
+ "\x32\xcf\xcb\x0e\x8b\x72\x11\xe8\x3a\xf3"
+ "\x2a\x11\xac\x17\x92\x9f\xf1\xc0\x73\xa5"
+ "\x1c\xc0\x27\xaa\xed\xef\xf8\x5a\xad\x7c"
+ "\x2b\x7c\x5a\x80\x3e\x24\x04\xd9\x6d\x2a"
+ "\x77\x35\x7b\xda\x1a\x6d\xae\xed\x17\x15"
+ "\x1c\xb9\xbc\x51\x25\xa4\x22\xe9\x41\xde"
+ "\x0c\xa0\xfc\x50\x11\xc2\x3e\xcf\xfe\xfd"
+ "\xd0\x96\x76\x71\x1c\xf3\xdb\x0a\x34\x40"
+ "\x72\x0e\x16\x15\xc1\xf2\x2f\xbc\x3c\x72"
+ "\x1d\xe5\x21\xe1\xb9\x9b\xa1\xbd\x55\x77"
+ "\x40\x86\x42\x14\x7e\xd0\x96"),
+ "0x4F440DB1E6EDD2899FA335F09515AA025EE177A79F4B4A"
+ "AF38E42B5C4DE660F5DE8FB2A5B2FBD2A3CBFFD2"
+ "0CFF1288C0",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ isc_sha384_init(&sha384);
+ for(i = 0; i < testcase->repeats; i++) {
+ isc_sha384_update(&sha384,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ }
+ isc_sha384_final(digest, &sha384);
+ /*
+ *API inconsistency BUG HERE
+ * in order to be consistant with the other isc_hash_final
+ * functions the call should be
+ * isc_sha224_final(&sha224, digest);
+ */
+ tohexstr(digest, ISC_SHA384_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_sha512);
+ATF_TC_HEAD(isc_sha512, tc) {
+ atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634");
+}
+ATF_TC_BODY(isc_sha512, tc) {
+ isc_sha512_t sha512;
+ int i;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("abc"),
+ "0xDDAF35A193617ABACC417349AE20413112E6FA4E89A97E"
+ "A20A9EEEE64B55D39A2192992A274FC1A836BA3C"
+ "23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("abcdefghbcdefghicdefghijdefghijkefghijkl"
+ "fghijklmghijklmnhijklmnoijklmnopjklmnopq"
+ "klmnopqrlmnopqrsmnopqrstnopqrstu"),
+ "0x8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7F"
+ "A17299AEADB6889018501D289E4900F7E4331B99"
+ "DEC4B5433AC7D329EEB6DD26545E96E55B874BE909",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("a"),
+ "0xE718483D0CE769644E2E42C7BC15B4638E1F98B13B2044"
+ "285632A803AFA973EBDE0FF244877EA60A4CB043"
+ "2CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B",
+ 1000000
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("01234567012345670123456701234567"),
+ "0x89D05BA632C699C31231DED4FFC127D5A894DAD412C0E0"
+ "24DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF"
+ "33C765CB510813A39CD5A84C4ACAA64D3F3FB7BAE9",
+ 20
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("\xD0"),
+ "0x9992202938E882E73E20F6B69E68A0A7149090423D93C8"
+ "1BAB3F21678D4ACEEEE50E4E8CAFADA4C85A54EA"
+ "8306826C4AD6E74CECE9631BFA8A549B4AB3FBBA15",
+ 1
+ },
+#if 0
+ /* Test 7 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 8 */
+ {
+ TEST_INPUT("\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81"
+ "\x6e\x9d\x98\xbf\xf0\xa0"),
+ "0xCB0B67A4B8712CD73C9AABC0B199E9269B20844AFB75AC"
+ "BDD1C153C9828924C3DDEDAAFE669C5FDD0BC66F"
+ "630F6773988213EB1B16F517AD0DE4B2F0C95C90F8",
+ 1
+ },
+#if 0
+ /* Test 9 -- unimplemented optional functionality */
+ {
+ TEST_INPUT(""),
+ "0xXXX",
+ 1
+ },
+#endif
+ /* Test 10 */
+ {
+ TEST_INPUT("\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a"
+ "\x50\x2d\x65\x82\x4e\x31\xa2\x30\x54\x32"
+ "\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d"
+ "\xe1\xde\x69\x74\xbf\x49\x54\x69\xfc\x7f"
+ "\x33\x8f\x80\x54\xd5\x8c\x26\xc4\x93\x60"
+ "\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d"
+ "\x03\xe5\x6f\xf2\xf8\x68\x00\x2b\xc3\xe4"
+ "\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3"
+ "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69"
+ "\x4f\xcb\xba\xf8\x8d\x95\x19\xe4\xeb\x50"
+ "\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc"
+ "\x44\x65\xc8\x82\x1a\xac\xd2\xfe\x15\xab"
+ "\x49\x81\x16\x4b\xbb\x6d\xc3\x2f\x96\x90"
+ "\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b"
+ "\x76\x32\x99\x41\x9c\xc4\x12\x8b\xe9\xa0"
+ "\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28"
+ "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13"
+ "\x2e\x9a\x0d\xc6\xd3\xb1\xf8\xb2\x46\xf1"
+ "\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20"
+ "\x98\xe8\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f"
+ "\x47\x07\xfe\x1e\xa1\xa1\x79\x1b\xa2\xf3"
+ "\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9"
+ "\x49\xad\x47\xd7\xfb\x40\xd2"),
+ "0xC665BEFB36DA189D78822D10528CBF3B12B3EEF7260399"
+ "09C1A16A270D48719377966B957A878E72058477"
+ "9A62825C18DA26415E49A7176A894E7510FD1451F5",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ isc_sha512_init(&sha512);
+ for(i = 0; i < testcase->repeats; i++) {
+ isc_sha512_update(&sha512,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ }
+ isc_sha512_final(digest, &sha512);
+ /*
+ *API inconsistency BUG HERE
+ * in order to be consistant with the other isc_hash_final
+ * functions the call should be
+ * isc_sha224_final(&sha224, digest);
+ */
+ tohexstr(digest, ISC_SHA512_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+#ifndef PK11_MD5_DISABLE
+ATF_TC(isc_md5);
+ATF_TC_HEAD(isc_md5, tc) {
+ atf_tc_set_md_var(tc, "descr", "md5 example from RFC1321");
+}
+ATF_TC_BODY(isc_md5, tc) {
+ isc_md5_t md5;
+ int i;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ {
+ TEST_INPUT(""),
+ "0xD41D8CD98F00B204E9800998ECF8427E",
+ 1
+ },
+ {
+ TEST_INPUT("a"),
+ "0x0CC175B9C0F1B6A831C399E269772661",
+ 1
+ },
+ {
+ TEST_INPUT("abc"),
+ "0x900150983CD24FB0D6963F7D28E17F72",
+ 1
+ },
+ {
+ TEST_INPUT("message digest"),
+ "0xF96B697D7CB7938D525A2F31AAF161D0",
+ 1
+ },
+ {
+ TEST_INPUT("abcdefghijklmnopqrstuvwxyz"),
+ "0xC3FCD3D76192E4007DFB496CCA67E13B",
+ 1
+ },
+ {
+ TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"
+ "nopqrstuvwxyz0123456789"),
+ "0xD174AB98D277D9F5A5611C2C9F419D9F",
+ 1
+ },
+ {
+ TEST_INPUT("123456789012345678901234567890123456789"
+ "01234567890123456789012345678901234567890"),
+ "0x57EDF4A22BE3C955AC49DA2E2107B67A",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ isc_md5_init(&md5);
+ for(i = 0; i < testcase->repeats; i++) {
+ isc_md5_update(&md5,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ }
+ isc_md5_final(&md5, digest);
+ tohexstr(digest, ISC_MD5_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+#endif
+
+/* HMAC-SHA1 test */
+ATF_TC(isc_hmacsha1);
+ATF_TC_HEAD(isc_hmacsha1, tc) {
+ atf_tc_set_md_var(tc, "descr", "HMAC-SHA1 examples from RFC2104");
+}
+ATF_TC_BODY(isc_hmacsha1, tc) {
+ isc_hmacsha1_t hmacsha1;
+
+ UNUSED(tc);
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+ "0xB617318655057264E28BC0B6FB378C8EF146BE00",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+ "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+ "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+ "0xEFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+ "0x125D7342B9AC11CD91A39AF48AA17B4F63F175D3",
+ 1
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+ "0x4C9007F4026250C6BC8414F9BF50C86C2D7235DA",
+ 1
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test With Truncation"),
+ "0x4C1A03424B55E07FE7F27BE1",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key - "
+ "Hash Key First"),
+ "0xAA4AE5E15272D00E95705637CE8A3B55ED402112", 1 },
+ /* Test 7 */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key and "
+ "Larger Than One Block-Size Data"),
+ "0xE8E99D0F45237D786D6BBAA7965C7808BBFF1A91",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ hash_test_key_t test_keys[] = {
+ /* Key 1 */
+ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
+ /* Key 2 */
+ { "Jefe", 4 },
+ /* Key 3 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
+ /* Key 4 */
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19", 25 },
+#if 0
+ /* Key 5 */
+ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
+#endif
+ /* Key 6 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80 },
+ /* Key 7 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80 },
+ { "", 0 }
+ };
+
+ hash_test_key_t *test_key = test_keys;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ memmove(buffer, test_key->key, test_key->len);
+ isc_hmacsha1_init(&hmacsha1, buffer, test_key->len);
+ isc_hmacsha1_update(&hmacsha1,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH);
+ tohexstr(digest, ISC_SHA1_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ test_key++;
+ }
+}
+
+/* HMAC-SHA224 test */
+ATF_TC(isc_hmacsha224);
+ATF_TC_HEAD(isc_hmacsha224, tc) {
+ atf_tc_set_md_var(tc, "descr", "HMAC-SHA224 examples from RFC4634");
+}
+ATF_TC_BODY(isc_hmacsha224, tc) {
+ isc_hmacsha224_t hmacsha224;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+ "0x896FB1128ABBDF196832107CD49DF33F47B4B1169912BA"
+ "4F53684B22",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+ "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+ "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+ "0xA30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E61480"
+ "08FD05E44",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+ "0x7FB3CB3588C6C1F6FFA9694D7D6AD2649365B0C1F65D69"
+ "D1EC8333EA",
+ 1
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+ "0x6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC01"
+ "2DE7AFEC5A",
+ 1
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test With Truncation"),
+ "0x4C1A03424B55E07FE7F27BE1",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key - "
+ "Hash Key First"),
+ "0x95E9A0DB962095ADAEBE9B2D6F0DBCE2D499F112F2D2B7"
+ "273FA6870E",
+ 1
+ },
+ /* Test 7 */
+ {
+ TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+ "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+ "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+ "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+ "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+ "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+ "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+ "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+ "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+ "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+ "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+ "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+ "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+ "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+ "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+ "\x6d\x2e"),
+ "0x3A854166AC5D9F023F54D517D0B39DBD946770DB9C2B95"
+ "C9F6F565D1",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ hash_test_key_t test_keys[] = {
+ /* Key 1 */
+ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
+ /* Key 2 */
+ { "Jefe", 4 },
+ /* Key 3 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
+ /* Key 4 */
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19", 25 },
+#if 0
+ /* Key 5 */
+ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
+#endif
+ /* Key 6 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ /* Key 7 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ { "", 0 }
+ };
+
+ hash_test_key_t *test_key = test_keys;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ memmove(buffer, test_key->key, test_key->len);
+ isc_hmacsha224_init(&hmacsha224, buffer, test_key->len);
+ isc_hmacsha224_update(&hmacsha224,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH);
+ tohexstr(digest, ISC_SHA224_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ test_key++;
+ }
+}
+
+/* HMAC-SHA256 test */
+ATF_TC(isc_hmacsha256);
+ATF_TC_HEAD(isc_hmacsha256, tc) {
+ atf_tc_set_md_var(tc, "descr", "HMAC-SHA256 examples from RFC4634");
+}
+ATF_TC_BODY(isc_hmacsha256, tc) {
+ isc_hmacsha256_t hmacsha256;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+ "0xB0344C61D8DB38535CA8AFCEAF0BF12B881DC200C9833D"
+ "A726E9376C2E32CFF7",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+ "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+ "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+ "0x5BDCC146BF60754E6A042426089575C75A003F089D2739"
+ "839DEC58B964EC3843",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+ "0x773EA91E36800E46854DB8EBD09181A72959098B3EF8C1"
+ "22D9635514CED565FE",
+ 1
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+ "0x82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8"
+ "077A2E3FF46729665B",
+ 1
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test With Truncation"),
+ "0x4C1A03424B55E07FE7F27BE1",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key - "
+ "Hash Key First"),
+ "0x60E431591EE0B67F0D8A26AACBF5B77F8E0BC6213728C5"
+ "140546040F0EE37F54",
+ 1
+ },
+ /* Test 7 */
+ {
+ TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+ "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+ "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+ "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+ "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+ "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+ "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+ "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+ "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+ "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+ "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+ "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+ "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+ "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+ "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+ "\x6d\x2e"),
+ "0x9B09FFA71B942FCB27635FBCD5B0E944BFDC63644F0713"
+ "938A7F51535C3A35E2",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ hash_test_key_t test_keys[] = {
+ /* Key 1 */
+ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
+ /* Key 2 */
+ { "Jefe", 4 },
+ /* Key 3 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
+ /* Key 4 */
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19", 25 },
+#if 0
+ /* Key 5 */
+ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
+#endif
+ /* Key 6 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ /* Key 7 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ { "", 0 }
+ };
+
+ hash_test_key_t *test_key = test_keys;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ memmove(buffer, test_key->key, test_key->len);
+ isc_hmacsha256_init(&hmacsha256, buffer, test_key->len);
+ isc_hmacsha256_update(&hmacsha256,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH);
+ tohexstr(digest, ISC_SHA256_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ test_key++;
+ }
+}
+
+/* HMAC-SHA384 test */
+ATF_TC(isc_hmacsha384);
+ATF_TC_HEAD(isc_hmacsha384, tc) {
+ atf_tc_set_md_var(tc, "descr", "HMAC-SHA384 examples from RFC4634");
+}
+ATF_TC_BODY(isc_hmacsha384, tc) {
+ isc_hmacsha384_t hmacsha384;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+ "0xAFD03944D84895626B0825F4AB46907F15F9DADBE4101E"
+ "C682AA034C7CEBC59CFAEA9EA9076EDE7F4AF152"
+ "E8B2FA9CB6",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+ "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+ "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+ "0xAF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B"
+ "47E42EC3736322445E8E2240CA5E69E2C78B3239"
+ "ECFAB21649",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+ "0x88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9F"
+ "EBE83EF4E55966144B2A5AB39DC13814B94E3AB6"
+ "E101A34F27",
+ 1
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+ "0x3E8A69B7783C25851933AB6290AF6CA77A998148085000"
+ "9CC5577C6E1F573B4E6801DD23C4A7D679CCF8A3"
+ "86C674CFFB",
+ 1
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test With Truncation"),
+ "0x4C1A03424B55E07FE7F27BE1",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key - "
+ "Hash Key First"),
+ "0x4ECE084485813E9088D2C63A041BC5B44F9EF1012A2B58"
+ "8F3CD11F05033AC4C60C2EF6AB4030FE8296248D"
+ "F163F44952",
+ 1
+ },
+ /* Test 7 */
+ {
+ TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+ "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+ "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+ "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+ "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+ "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+ "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+ "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+ "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+ "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+ "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+ "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+ "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+ "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+ "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+ "\x6d\x2e"),
+ "0x6617178E941F020D351E2F254E8FD32C602420FEB0B8FB"
+ "9ADCCEBB82461E99C5A678CC31E799176D3860E6"
+ "110C46523E",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ hash_test_key_t test_keys[] = {
+ /* Key 1 */
+ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
+ /* Key 2 */
+ { "Jefe", 4 },
+ /* Key 3 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
+ /* Key 4 */
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19", 25 },
+#if 0
+ /* Key 5 */
+ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
+#endif
+ /* Key 6 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ /* Key 7 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ { "", 0 }
+ };
+
+ hash_test_key_t *test_key = test_keys;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ memmove(buffer, test_key->key, test_key->len);
+ isc_hmacsha384_init(&hmacsha384, buffer, test_key->len);
+ isc_hmacsha384_update(&hmacsha384,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH);
+ tohexstr(digest, ISC_SHA384_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ test_key++;
+ }
+}
+
+/* HMAC-SHA512 test */
+ATF_TC(isc_hmacsha512);
+ATF_TC_HEAD(isc_hmacsha512, tc) {
+ atf_tc_set_md_var(tc, "descr", "HMAC-SHA512 examples from RFC4634");
+}
+ATF_TC_BODY(isc_hmacsha512, tc) {
+ isc_hmacsha512_t hmacsha512;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+ "0x87AA7CDEA5EF619D4FF0B4241A1D6CB02379F4E2CE4EC2"
+ "787AD0B30545E17CDEDAA833B7D6B8A702038B27"
+ "4EAEA3F4E4BE9D914EEB61F1702E696C203A126854",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+ "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+ "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+ "0x164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831F"
+ "D610270CD7EA2505549758BF75C05A994A6D034F"
+ "65F8F0E6FDCAEAB1A34D4A6B4B636E070A38BCE737",
+ 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+ "0xFA73B0089D56A284EFB0F0756C890BE9B1B5DBDD8EE81A"
+ "3655F83E33B2279D39BF3E848279A722C806B485"
+ "A47E67C807B946A337BEE8942674278859E13292FB",
+ 1
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+ "0xB0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B87"
+ "2DE76F8050361EE3DBA91CA5C11AA25EB4D67927"
+ "5CC5788063A5F19741120C4F2DE2ADEBEB10A298DD",
+ 1
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test With Truncation"),
+ "0x4C1A03424B55E07FE7F27BE1",
+ 1
+ },
+#endif
+ /* Test 6 */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key - "
+ "Hash Key First"),
+ "0x80B24263C7C1A3EBB71493C1DD7BE8B49B46D1F41B4AEE"
+ "C1121B013783F8F3526B56D037E05F2598BD0FD2"
+ "215D6A1E5295E64F73F63F0AEC8B915A985D786598",
+ 1
+ },
+ /* Test 7 */
+ {
+ TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+ "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+ "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+ "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+ "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+ "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+ "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+ "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+ "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+ "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+ "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+ "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+ "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+ "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+ "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+ "\x6d\x2e"),
+ "0xE37B6A775DC87DBAA4DFA9F96E5E3FFDDEBD71F8867289"
+ "865DF5A32D20CDC944B6022CAC3C4982B10D5EEB"
+ "55C3E4DE15134676FB6DE0446065C97440FA8C6A58",
+ 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ hash_test_key_t test_keys[] = {
+ /* Key 1 */
+ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
+ /* Key 2 */
+ { "Jefe", 4 },
+ /* Key 3 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
+ /* Key 4 */
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19", 25 },
+#if 0
+ /* Key 5 */
+ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
+#endif
+ /* Key 6 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ /* Key 7 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ { "", 0 }
+ };
+
+ hash_test_key_t *test_key = test_keys;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ memmove(buffer, test_key->key, test_key->len);
+ isc_hmacsha512_init(&hmacsha512, buffer, test_key->len);
+ isc_hmacsha512_update(&hmacsha512,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH);
+ tohexstr(digest, ISC_SHA512_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ test_key++;
+ }
+}
+
+
+#ifndef PK11_MD5_DISABLE
+/* HMAC-MD5 Test */
+ATF_TC(isc_hmacmd5);
+ATF_TC_HEAD(isc_hmacmd5, tc) {
+ atf_tc_set_md_var(tc, "descr", "HMAC-MD5 examples from RFC2104");
+}
+ATF_TC_BODY(isc_hmacmd5, tc) {
+ isc_hmacmd5_t hmacmd5;
+
+ UNUSED(tc);
+
+ /*
+ * These are the various test vectors. All of these are passed
+ * through the hash function and the results are compared to the
+ * result specified here.
+ */
+ hash_testcase_t testcases[] = {
+ /* Test 1 */
+ {
+ TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+ "0x9294727A3638BB1C13F48EF8158BFC9D",
+ 1
+ },
+ /* Test 2 */
+ {
+ TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79"
+ "\x61\x20\x77\x61\x6e\x74\x20\x66\x6f"
+ "\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+ "0x750C783E6AB0B503EAA86E310A5DB738", 1
+ },
+ /* Test 3 */
+ {
+ TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+ "0x56BE34521D144C88DBB8C733F0E8B3F6",
+ 1
+ },
+ /* Test 4 */
+ {
+ TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+ "0x697EAF0ACA3A3AEA3A75164746FFAA79",
+ 1
+ },
+#if 0
+ /* Test 5 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test With Truncation"),
+ "0x4C1A03424B55E07FE7F27BE1",
+ 1
+ },
+ /* Test 6 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key - "
+ "Hash Key First"),
+ "0xAA4AE5E15272D00E95705637CE8A3B55ED402112",
+ 1
+ },
+ /* Test 7 -- unimplemented optional functionality */
+ {
+ TEST_INPUT("Test Using Larger Than Block-Size Key and "
+ "Larger Than One Block-Size Data"),
+ "0xE8E99D0F45237D786D6BBAA7965C7808BBFF1A91",
+ 1
+ },
+#endif
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ hash_test_key_t test_keys[] = {
+ /* Key 1 */
+ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b", 16 },
+ /* Key 2 */
+ { "Jefe", 4 },
+ /* Key 3 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa", 16 },
+ /* Key 4 */
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19", 25 },
+#if 0
+ /* Key 5 */
+ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
+ /* Key 6 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+ /* Key 7 */
+ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
+#endif
+ { "", 0 }
+ };
+
+ hash_test_key_t *test_key = test_keys;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ memmove(buffer, test_key->key, test_key->len);
+ isc_hmacmd5_init(&hmacmd5, buffer, test_key->len);
+ isc_hmacmd5_update(&hmacmd5,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ isc_hmacmd5_sign(&hmacmd5, digest);
+ tohexstr(digest, ISC_MD5_DIGESTLENGTH, str, sizeof(str));
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ test_key++;
+ }
+}
+#endif
+
+/* CRC64 Test */
+ATF_TC(isc_crc64);
+ATF_TC_HEAD(isc_crc64, tc) {
+ atf_tc_set_md_var(tc, "descr", "64-bit cyclic redundancy check");
+}
+ATF_TC_BODY(isc_crc64, tc) {
+ uint64_t crc;
+ int i;
+
+ UNUSED(tc);
+
+ hash_testcase_t testcases[] = {
+ {
+ TEST_INPUT(""),
+ "0x0000000000000000", 1
+ },
+ {
+ TEST_INPUT("a"),
+ "0xCE73F427ACC0A99A", 1
+ },
+ {
+ TEST_INPUT("abc"),
+ "0x048B813AF9F49702", 1
+ },
+ {
+ TEST_INPUT("message digest"),
+ "0x5273F9EA7A357BF4", 1
+ },
+ {
+ TEST_INPUT("abcdefghijklmnopqrstuvwxyz"),
+ "0x59F079F9218BAAA1", 1
+ },
+ {
+ TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"
+ "nopqrstuvwxyz0123456789"),
+ "0xA36DA8F71E78B6FB", 1
+ },
+ {
+ TEST_INPUT("123456789012345678901234567890123456789"
+ "01234567890123456789012345678901234567890"),
+ "0x81E5EB73C8E7874A", 1
+ },
+ { NULL, 0, NULL, 1 }
+ };
+
+ hash_testcase_t *testcase = testcases;
+
+ while (testcase->input != NULL && testcase->result != NULL) {
+ isc_crc64_init(&crc);
+ for(i = 0; i < testcase->repeats; i++) {
+ isc_crc64_update(&crc,
+ (const uint8_t *) testcase->input,
+ testcase->input_len);
+ }
+ isc_crc64_final(&crc);
+ snprintf(str, sizeof(str),
+ "0x%016" PRIX64, crc);
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_hash_function);
+ATF_TC_HEAD(isc_hash_function, tc) {
+ atf_tc_set_md_var(tc, "descr", "Hash function test");
+}
+ATF_TC_BODY(isc_hash_function, tc) {
+ unsigned int h1;
+ unsigned int h2;
+
+ UNUSED(tc);
+
+ /* Incremental hashing */
+
+ h1 = isc_hash_function(NULL, 0, true, NULL);
+ h1 = isc_hash_function("This ", 5, true, &h1);
+ h1 = isc_hash_function("is ", 3, true, &h1);
+ h1 = isc_hash_function("a long test", 12, true, &h1);
+
+ h2 = isc_hash_function("This is a long test", 20,
+ true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Immutability of hash function */
+ h1 = isc_hash_function(NULL, 0, true, NULL);
+ h2 = isc_hash_function(NULL, 0, true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Hash function characteristics */
+ h1 = isc_hash_function("Hello world", 12, true, NULL);
+ h2 = isc_hash_function("Hello world", 12, true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Case */
+ h1 = isc_hash_function("Hello world", 12, false, NULL);
+ h2 = isc_hash_function("heLLo WorLd", 12, false, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Unequal */
+ h1 = isc_hash_function("Hello world", 12, true, NULL);
+ h2 = isc_hash_function("heLLo WorLd", 12, true, NULL);
+
+ ATF_CHECK(h1 != h2);
+}
+
+ATF_TC(isc_hash_function_reverse);
+ATF_TC_HEAD(isc_hash_function_reverse, tc) {
+ atf_tc_set_md_var(tc, "descr", "Reverse hash function test");
+}
+ATF_TC_BODY(isc_hash_function_reverse, tc) {
+ unsigned int h1;
+ unsigned int h2;
+
+ UNUSED(tc);
+
+ /* Incremental hashing */
+
+ h1 = isc_hash_function_reverse(NULL, 0, true, NULL);
+ h1 = isc_hash_function_reverse("\000", 1, true, &h1);
+ h1 = isc_hash_function_reverse("\003org", 4, true, &h1);
+ h1 = isc_hash_function_reverse("\007example", 8, true, &h1);
+
+ h2 = isc_hash_function_reverse("\007example\003org\000", 13,
+ true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Immutability of hash function */
+ h1 = isc_hash_function_reverse(NULL, 0, true, NULL);
+ h2 = isc_hash_function_reverse(NULL, 0, true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Hash function characteristics */
+ h1 = isc_hash_function_reverse("Hello world", 12, true, NULL);
+ h2 = isc_hash_function_reverse("Hello world", 12, true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Case */
+ h1 = isc_hash_function_reverse("Hello world", 12, false, NULL);
+ h2 = isc_hash_function_reverse("heLLo WorLd", 12, false, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ /* Unequal */
+ h1 = isc_hash_function_reverse("Hello world", 12, true, NULL);
+ h2 = isc_hash_function_reverse("heLLo WorLd", 12, true, NULL);
+
+ ATF_CHECK(h1 != h2);
+}
+
+ATF_TC(isc_hash_initializer);
+ATF_TC_HEAD(isc_hash_initializer, tc) {
+ atf_tc_set_md_var(tc, "descr", "Hash function initializer test");
+}
+ATF_TC_BODY(isc_hash_initializer, tc) {
+ unsigned int h1;
+ unsigned int h2;
+
+ UNUSED(tc);
+
+ h1 = isc_hash_function("Hello world", 12, true, NULL);
+ h2 = isc_hash_function("Hello world", 12, true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+
+ isc_hash_set_initializer(isc_hash_get_initializer());
+
+ /* Hash value must not change */
+ h2 = isc_hash_function("Hello world", 12, true, NULL);
+
+ ATF_CHECK_EQ(h1, h2);
+}
+
+#ifndef PK11_MD5_DISABLE
+ATF_TC(md5_check);
+ATF_TC_HEAD(md5_check, tc) {
+ atf_tc_set_md_var(tc, "descr", "Startup MD5 check test");
+}
+ATF_TC_BODY(md5_check, tc) {
+ UNUSED(tc);
+
+ ATF_REQUIRE(isc_md5_check(false));
+ ATF_CHECK(!isc_md5_check(true));
+
+ ATF_REQUIRE(isc_hmacmd5_check(0));
+ ATF_CHECK(!isc_hmacmd5_check(1));
+ ATF_CHECK(!isc_hmacmd5_check(2));
+ ATF_CHECK(!isc_hmacmd5_check(3));
+ ATF_CHECK(!isc_hmacmd5_check(4));
+}
+#endif
+
+ATF_TC(sha1_check);
+ATF_TC_HEAD(sha1_check, tc) {
+ atf_tc_set_md_var(tc, "descr", "Startup SHA-1 check test");
+}
+ATF_TC_BODY(sha1_check, tc) {
+ UNUSED(tc);
+
+ ATF_REQUIRE(isc_sha1_check(false));
+ ATF_CHECK(!isc_sha1_check(true));
+
+ ATF_REQUIRE(isc_hmacsha1_check(0));
+ ATF_CHECK(!isc_hmacsha1_check(1));
+ ATF_CHECK(!isc_hmacsha1_check(2));
+ ATF_CHECK(!isc_hmacsha1_check(3));
+ ATF_CHECK(!isc_hmacsha1_check(4));
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ /*
+ * Tests of hash functions, including isc_hash and the
+ * various cryptographic hashes.
+ */
+#ifndef PK11_MD5_DISABLE
+ ATF_TP_ADD_TC(tp, md5_check);
+#endif
+ ATF_TP_ADD_TC(tp, sha1_check);
+
+ ATF_TP_ADD_TC(tp, isc_hash_function);
+ ATF_TP_ADD_TC(tp, isc_hash_function_reverse);
+ ATF_TP_ADD_TC(tp, isc_hash_initializer);
+#ifndef PK11_MD5_DISABLE
+ ATF_TP_ADD_TC(tp, isc_hmacmd5);
+#endif
+ ATF_TP_ADD_TC(tp, isc_hmacsha1);
+ ATF_TP_ADD_TC(tp, isc_hmacsha224);
+ ATF_TP_ADD_TC(tp, isc_hmacsha256);
+ ATF_TP_ADD_TC(tp, isc_hmacsha384);
+ ATF_TP_ADD_TC(tp, isc_hmacsha512);
+#ifndef PK11_MD5_DISABLE
+ ATF_TP_ADD_TC(tp, isc_md5);
+#endif
+ ATF_TP_ADD_TC(tp, isc_sha1);
+ ATF_TP_ADD_TC(tp, isc_sha224);
+ ATF_TP_ADD_TC(tp, isc_sha256);
+ ATF_TP_ADD_TC(tp, isc_sha384);
+ ATF_TP_ADD_TC(tp, isc_sha512);
+ ATF_TP_ADD_TC(tp, isc_crc64);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/heap_test.c b/lib/isc/tests/heap_test.c
new file mode 100644
index 0000000..c030573
--- /dev/null
+++ b/lib/isc/tests/heap_test.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/* ! \file */
+
+#include <config.h>
+
+#include <stdbool.h>
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/heap.h>
+#include <isc/mem.h>
+
+#include <isc/util.h>
+
+struct e {
+ unsigned int value;
+ unsigned int index;
+};
+
+static bool
+compare(void *p1, void *p2) {
+ struct e *e1 = p1;
+ struct e *e2 = p2;
+
+ return (e1->value < e2->value);
+}
+
+static void
+idx(void *p, unsigned int i) {
+ struct e *e = p;
+
+ e->index = i;
+}
+
+ATF_TC(isc_heap_delete);
+ATF_TC_HEAD(isc_heap_delete, tc) {
+ atf_tc_set_md_var(tc, "descr", "test isc_heap_delete");
+}
+ATF_TC_BODY(isc_heap_delete, tc) {
+ isc_mem_t *mctx = NULL;
+ isc_heap_t *heap = NULL;
+ isc_result_t result;
+ struct e e1 = { 100, 0 };
+
+ UNUSED(tc);
+
+ result = isc_mem_create(0, 0, &mctx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_heap_create(mctx, compare, idx, 0, &heap);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(heap != NULL);
+
+ isc_heap_insert(heap, &e1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(e1.index, 1);
+
+ isc_heap_delete(heap, e1.index);
+ ATF_CHECK_EQ(e1.index, 0);
+
+ isc_heap_destroy(&heap);
+ ATF_REQUIRE_EQ(heap, NULL);
+
+ isc_mem_detach(&mctx);
+ ATF_REQUIRE_EQ(mctx, NULL);
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_heap_delete);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/ht_test.c b/lib/isc/tests/ht_test.c
new file mode 100644
index 0000000..5356142
--- /dev/null
+++ b/lib/isc/tests/ht_test.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/* ! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <isc/hash.h>
+#include <isc/ht.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+static void *
+default_memalloc(void *arg, size_t size) {
+ UNUSED(arg);
+ if (size == 0U)
+ size = 1;
+ return (malloc(size));
+}
+
+static void
+default_memfree(void *arg, void *ptr) {
+ UNUSED(arg);
+ free(ptr);
+}
+
+static void test_ht_full(int bits, uintptr_t count) {
+ isc_ht_t *ht = NULL;
+ isc_result_t result;
+ isc_mem_t *mctx = NULL;
+ uintptr_t i;
+
+ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_ht_init(&ht, mctx, bits);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(ht != NULL);
+
+ for (i = 1; i < count; i++) {
+ /*
+ * Note: snprintf() is followed with strlcat()
+ * to ensure we are always filling the 16 byte key.
+ */
+ unsigned char key[16];
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_add(ht, key, 16, (void *) i);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ }
+
+ for (i = 1; i < count; i++) {
+ unsigned char key[16];
+ void *f = NULL;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_find(ht, key, 16, &f);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(i, (uintptr_t) f);
+ }
+
+ for (i = 1; i < count; i++) {
+ unsigned char key[16];
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_add(ht, key, 16, (void *) i);
+ ATF_REQUIRE_EQ(result, ISC_R_EXISTS);
+ }
+
+ for (i = 1; i < count; i++) {
+ char key[64];
+ /*
+ * Note: the key size is now strlen(key) which is bigger
+ * then the keys added above.
+ */
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_add(ht, (const unsigned char *) key,
+ strlen(key), (void *) i);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ }
+
+ for (i = 1; i < count; i++) {
+ unsigned char key[16];
+ void *f = NULL;
+ /*
+ * Note: case of KEY is now in capitals,
+ */
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " KEY of a raw hashtable!!", sizeof(key));
+ result = isc_ht_find(ht, key, 16, &f);
+ ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
+ ATF_REQUIRE_EQ(f, NULL);
+ }
+
+ for (i = 1; i < count; i++) {
+ char key[64];
+ void *f = NULL;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_find(ht, (const unsigned char *) key,
+ strlen(key), &f);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(f, (void *) i);
+ }
+
+ for (i = 1; i < count; i++) {
+ unsigned char key[16];
+ void *f = NULL;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_delete(ht, key, 16);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_ht_find(ht, key, 16, &f);
+ ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
+ ATF_REQUIRE_EQ(f, NULL);
+ }
+
+ for (i = 1; i < count; i++) {
+ unsigned char key[16];
+ /*
+ * Note: upper case KEY.
+ */
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " KEY of a raw hashtable!!", sizeof(key));
+ result = isc_ht_add(ht, key, 16, (void *) i);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ }
+
+ for (i = 1; i < count; i++) {
+ char key[64];
+ void *f = NULL;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_delete(ht, (const unsigned char *) key,
+ strlen(key));
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_ht_find(ht, (const unsigned char *) key,
+ strlen(key), &f);
+ ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
+ ATF_REQUIRE_EQ(f, NULL);
+ }
+
+
+ for (i = 1; i < count; i++) {
+ unsigned char key[16];
+ void *f = NULL;
+ /*
+ * Note: case of KEY is now in capitals,
+ */
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " KEY of a raw hashtable!!", sizeof(key));
+ result = isc_ht_find(ht, key, 16, &f);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(i, (uintptr_t) f);
+ }
+
+ for (i = 1; i < count; i++) {
+ unsigned char key[16];
+ void *f = NULL;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, " key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_find(ht, key, 16, &f);
+ ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
+ ATF_REQUIRE_EQ(f, NULL);
+ }
+
+ isc_ht_destroy(&ht);
+ ATF_REQUIRE_EQ(ht, NULL);
+}
+
+static void test_ht_iterator() {
+ isc_ht_t *ht = NULL;
+ isc_result_t result;
+ isc_mem_t *mctx = NULL;
+ isc_ht_iter_t * iter = NULL;
+ uintptr_t i;
+ void *v;
+ uintptr_t count = 10000;
+ uint32_t walked;
+ unsigned char key[16];
+ unsigned char *tkey;
+ size_t tksize;
+
+ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_ht_init(&ht, mctx, 16);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(ht != NULL);
+ for (i = 1; i <= count; i++) {
+ /*
+ * Note that the string we're snprintfing is always > 16 bytes
+ * so we are always filling the key.
+ */
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, "key of a raw hashtable!!", sizeof(key));
+ result = isc_ht_add(ht, key, 16, (void *) i);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ }
+
+ walked = 0;
+ result = isc_ht_iter_create(ht, &iter);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ for (result = isc_ht_iter_first(iter);
+ result == ISC_R_SUCCESS;
+ result = isc_ht_iter_next(iter))
+ {
+ isc_ht_iter_current(iter, &v);
+ isc_ht_iter_currentkey(iter, &tkey, &tksize);
+ ATF_REQUIRE_EQ(tksize, 16);
+ i = (uintptr_t)v;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, "key of a raw hashtable!!", sizeof(key));
+ ATF_REQUIRE_EQ(memcmp(key, tkey, 16), 0);
+ walked++;
+ }
+ ATF_REQUIRE_EQ(walked, count);
+ ATF_REQUIRE_EQ(result, ISC_R_NOMORE);
+
+ /* erase odd */
+ walked = 0;
+ result = isc_ht_iter_first(iter);
+ while (result == ISC_R_SUCCESS) {
+ isc_ht_iter_current(iter, &v);
+ isc_ht_iter_currentkey(iter, &tkey, &tksize);
+ ATF_REQUIRE_EQ(tksize, 16);
+ i = (uintptr_t)v;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, "key of a raw hashtable!!", sizeof(key));
+ ATF_REQUIRE_EQ(memcmp(key, tkey, 16), 0);
+ if ((uintptr_t)v % 2 == 0) {
+ result = isc_ht_iter_delcurrent_next(iter);
+ } else {
+ result = isc_ht_iter_next(iter);
+ }
+ walked++;
+ }
+ ATF_REQUIRE_EQ(result, ISC_R_NOMORE);
+ ATF_REQUIRE_EQ(walked, count);
+
+ /* erase even */
+ walked = 0;
+ result = isc_ht_iter_first(iter);
+ while (result == ISC_R_SUCCESS) {
+ isc_ht_iter_current(iter, &v);
+ isc_ht_iter_currentkey(iter, &tkey, &tksize);
+ ATF_REQUIRE_EQ(tksize, 16);
+ i = (uintptr_t)v;
+ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i);
+ strlcat((char *)key, "key of a raw hashtable!!", sizeof(key));
+ ATF_REQUIRE_EQ(memcmp(key, tkey, 16), 0);
+ if ((uintptr_t)v % 2 == 1) {
+ result = isc_ht_iter_delcurrent_next(iter);
+ } else {
+ result = isc_ht_iter_next(iter);
+ }
+ walked++;
+ }
+ ATF_REQUIRE_EQ(result, ISC_R_NOMORE);
+ ATF_REQUIRE_EQ(walked, count/2);
+
+ walked = 0;
+ for (result = isc_ht_iter_first(iter);
+ result == ISC_R_SUCCESS;
+ result = isc_ht_iter_next(iter))
+ {
+ walked++;
+ }
+
+ ATF_REQUIRE_EQ(result, ISC_R_NOMORE);
+ ATF_REQUIRE_EQ(walked, 0);
+
+ isc_ht_destroy(&ht);
+ ATF_REQUIRE_EQ(ht, NULL);
+}
+
+ATF_TC(isc_ht_20);
+ATF_TC_HEAD(isc_ht_20, tc) {
+ atf_tc_set_md_var(tc, "descr", "20 bit, 200K elements test");
+}
+
+ATF_TC_BODY(isc_ht_20, tc) {
+ UNUSED(tc);
+ test_ht_full(20, 200000);
+}
+
+
+ATF_TC(isc_ht_8);
+ATF_TC_HEAD(isc_ht_8, tc) {
+ atf_tc_set_md_var(tc, "descr", "8 bit, 20000 elements crowded test");
+}
+
+ATF_TC_BODY(isc_ht_8, tc) {
+ UNUSED(tc);
+ test_ht_full(8, 20000);
+}
+
+ATF_TC(isc_ht_1);
+ATF_TC_HEAD(isc_ht_1, tc) {
+ atf_tc_set_md_var(tc, "descr", "1 bit, 100 elements corner case test");
+}
+
+ATF_TC_BODY(isc_ht_1, tc) {
+ UNUSED(tc);
+ test_ht_full(1, 100);
+}
+
+/* xxxwpk we should limit the size of hashtable, 32bit doesn't make sense */
+#if 0
+ATF_TC(isc_ht_32);
+ATF_TC_HEAD(isc_ht_32, tc) {
+ atf_tc_set_md_var(tc, "descr", "32 bit, 10000 elements corner case test");
+}
+
+ATF_TC_BODY(isc_ht_32, tc) {
+ UNUSED(tc);
+ test_ht_full(32, 10000);
+}
+#endif
+
+ATF_TC(isc_ht_iterator);
+ATF_TC_HEAD(isc_ht_iterator, tc) {
+ atf_tc_set_md_var(tc, "descr", "hashtable iterator");
+}
+
+ATF_TC_BODY(isc_ht_iterator, tc) {
+ UNUSED(tc);
+ test_ht_iterator();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_ht_20);
+ ATF_TP_ADD_TC(tp, isc_ht_8);
+ ATF_TP_ADD_TC(tp, isc_ht_1);
+/* ATF_TP_ADD_TC(tp, isc_ht_32); */
+ ATF_TP_ADD_TC(tp, isc_ht_iterator);
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/inet_ntop_test.c b/lib/isc/tests/inet_ntop_test.c
new file mode 100644
index 0000000..2bfe9de
--- /dev/null
+++ b/lib/isc/tests/inet_ntop_test.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+/*
+ * Force the prototype for isc_net_ntop to be declared.
+ */
+#include <isc/platform.h>
+#undef ISC_PLATFORM_NEEDNTOP
+#define ISC_PLATFORM_NEEDNTOP
+#include "../inet_ntop.c"
+
+ATF_TC(isc_net_ntop);
+ATF_TC_HEAD(isc_net_ntop, tc) {
+ atf_tc_set_md_var(tc, "descr", "isc_net_ntop implementation");
+}
+ATF_TC_BODY(isc_net_ntop, tc) {
+ char buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+ int r;
+ size_t i;
+ unsigned char abuf[16];
+ struct {
+ int family;
+ const char * address;
+ } testdata[] = {
+ { AF_INET, "0.0.0.0" },
+ { AF_INET, "0.1.0.0" },
+ { AF_INET, "0.0.2.0" },
+ { AF_INET, "0.0.0.3" },
+ { AF_INET, "255.255.255.255" },
+ { AF_INET6, "::" },
+ { AF_INET6, "::1.2.3.4" },
+ { AF_INET6, "::ffff:1.2.3.4" },
+ { AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" }
+ };
+
+ for (i = 0; i < sizeof(testdata)/sizeof(testdata[0]); i++) {
+ r = inet_pton(testdata[i].family, testdata[i].address, abuf);
+ ATF_REQUIRE_EQ_MSG(r, 1, "%s", testdata[i].address);
+ isc_net_ntop(testdata[i].family, abuf, buf, sizeof(buf));
+ ATF_CHECK_STREQ(buf, testdata[i].address);
+ }
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_net_ntop);
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/isctest.c b/lib/isc/tests/isctest.c
new file mode 100644
index 0000000..cf4ae97
--- /dev/null
+++ b/lib/isc/tests/isctest.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <isc/app.h>
+#include <isc/buffer.h>
+#include <isc/entropy.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
+#include <isc/os.h>
+#include <isc/socket.h>
+#include <isc/string.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include "isctest.h"
+
+isc_mem_t *mctx = NULL;
+isc_entropy_t *ectx = NULL;
+isc_log_t *lctx = NULL;
+isc_taskmgr_t *taskmgr = NULL;
+isc_timermgr_t *timermgr = NULL;
+isc_socketmgr_t *socketmgr = NULL;
+isc_task_t *maintask = NULL;
+int ncpus;
+
+static bool hash_active = false;
+
+/*
+ * Logging categories: this needs to match the list in bin/named/log.c.
+ */
+static isc_logcategory_t categories[] = {
+ { "", 0 },
+ { "client", 0 },
+ { "network", 0 },
+ { "update", 0 },
+ { "queries", 0 },
+ { "unmatched", 0 },
+ { "update-security", 0 },
+ { "query-errors", 0 },
+ { NULL, 0 }
+};
+
+static void
+cleanup_managers(void) {
+ if (maintask != NULL)
+ isc_task_destroy(&maintask);
+ if (socketmgr != NULL)
+ isc_socketmgr_destroy(&socketmgr);
+ if (taskmgr != NULL)
+ isc_taskmgr_destroy(&taskmgr);
+ if (timermgr != NULL)
+ isc_timermgr_destroy(&timermgr);
+}
+
+static isc_result_t
+create_managers(unsigned int workers) {
+ isc_result_t result;
+ char *p;
+
+ if (workers == 0) {
+#ifdef ISC_PLATFORM_USETHREADS
+ workers = isc_os_ncpus();
+#else
+ workers = 1;
+#endif
+ }
+
+ p = getenv("ISC_TASK_WORKERS");
+ if (p != NULL) {
+ workers = atoi(p);
+ }
+
+ CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr));
+ CHECK(isc_task_create(taskmgr, 0, &maintask));
+ isc_taskmgr_setexcltask(taskmgr, maintask);
+
+ CHECK(isc_timermgr_create(mctx, &timermgr));
+ CHECK(isc_socketmgr_create(mctx, &socketmgr));
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ cleanup_managers();
+ return (result);
+}
+
+isc_result_t
+isc_test_begin(FILE *logfile, bool start_managers,
+ unsigned int workers)
+{
+ isc_result_t result;
+
+ isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
+ CHECK(isc_mem_create(0, 0, &mctx));
+ CHECK(isc_entropy_create(mctx, &ectx));
+
+ CHECK(isc_hash_create(mctx, ectx, 255));
+ hash_active = true;
+
+ if (logfile != NULL) {
+ isc_logdestination_t destination;
+ isc_logconfig_t *logconfig = NULL;
+
+ CHECK(isc_log_create(mctx, &lctx, &logconfig));
+ isc_log_registercategories(lctx, categories);
+ isc_log_setcontext(lctx);
+
+ destination.file.stream = logfile;
+ destination.file.name = NULL;
+ destination.file.versions = ISC_LOG_ROLLNEVER;
+ destination.file.maximum_size = 0;
+ CHECK(isc_log_createchannel(logconfig, "stderr",
+ ISC_LOG_TOFILEDESC,
+ ISC_LOG_DYNAMIC,
+ &destination, 0));
+ CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
+ }
+
+#ifdef ISC_PLATFORM_USETHREADS
+ ncpus = isc_os_ncpus();
+#else
+ ncpus = 1;
+#endif
+
+ if (start_managers) {
+ CHECK(create_managers(workers));
+ }
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ isc_test_end();
+ return (result);
+}
+
+void
+isc_test_end(void) {
+ if (maintask != NULL)
+ isc_task_detach(&maintask);
+ if (taskmgr != NULL)
+ isc_taskmgr_destroy(&taskmgr);
+ if (hash_active) {
+ isc_hash_destroy();
+ hash_active = false;
+ }
+ if (ectx != NULL)
+ isc_entropy_detach(&ectx);
+
+ cleanup_managers();
+
+ if (lctx != NULL)
+ isc_log_destroy(&lctx);
+ if (mctx != NULL)
+ isc_mem_destroy(&mctx);
+}
+
+/*
+ * Sleep for 'usec' microseconds.
+ */
+void
+isc_test_nap(uint32_t usec) {
+#ifdef HAVE_NANOSLEEP
+ struct timespec ts;
+
+ ts.tv_sec = usec / 1000000;
+ ts.tv_nsec = (usec % 1000000) * 1000;
+ nanosleep(&ts, NULL);
+#elif HAVE_USLEEP
+ usleep(usec);
+#else
+ /*
+ * No fractional-second sleep function is available, so we
+ * round up to the nearest second and sleep instead
+ */
+ sleep((usec / 1000000) + 1);
+#endif
+}
diff --git a/lib/isc/tests/isctest.h b/lib/isc/tests/isctest.h
new file mode 100644
index 0000000..e553b8a
--- /dev/null
+++ b/lib/isc/tests/isctest.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <isc/buffer.h>
+#include <isc/entropy.h>
+#include <isc/hash.h>
+#include <isc/log.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/result.h>
+#include <isc/string.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#define CHECK(r) \
+ do { \
+ result = (r); \
+ if (result != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
+extern isc_mem_t *mctx;
+extern isc_entropy_t *ectx;
+extern isc_log_t *lctx;
+extern isc_taskmgr_t *taskmgr;
+extern isc_timermgr_t *timermgr;
+extern isc_socketmgr_t *socketmgr;
+extern int ncpus;
+
+isc_result_t
+isc_test_begin(FILE *logfile, bool start_managers,
+ unsigned int workers);
+/*%<
+ * Begin test, logging to 'logfile' or default if not specified.
+ *
+ * If 'start_managers' is set, start a task manager, timer manager,
+ * and socket manager.
+ *
+ * If 'workers' is zero, use the number of CPUs on the system as a default;
+ * otherwise, set up the task manager with the specified number of worker
+ * threads. The environment variable ISC_TASK_WORKERS overrides this value.
+ */
+
+void
+isc_test_end(void);
+
+void
+isc_test_nap(uint32_t usec);
diff --git a/lib/isc/tests/lex_test.c b/lib/isc/tests/lex_test.c
new file mode 100644
index 0000000..1315022
--- /dev/null
+++ b/lib/isc/tests/lex_test.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <isc/buffer.h>
+#include <isc/lex.h>
+#include <isc/mem.h>
+#include <isc/util.h>
+
+ATF_TC(lex_0xff);
+ATF_TC_HEAD(lex_0xff, tc) {
+ atf_tc_set_md_var(tc, "descr", "check handling of 0xff");
+}
+ATF_TC_BODY(lex_0xff, tc) {
+ isc_mem_t *mctx = NULL;
+ isc_result_t result;
+ isc_lex_t *lex = NULL;
+ isc_buffer_t death_buf;
+ isc_token_t token;
+
+ unsigned char death[] = { EOF, 'A' };
+
+ UNUSED(tc);
+
+ result = isc_mem_create(0, 0, &mctx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_lex_create(mctx, 1024, &lex);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_buffer_init(&death_buf, &death[0], sizeof(death));
+ isc_buffer_add(&death_buf, sizeof(death));
+
+ result = isc_lex_openbuffer(lex, &death_buf);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_lex_gettoken(lex, 0, &token);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+}
+
+ATF_TC(lex_setline);
+ATF_TC_HEAD(lex_setline, tc) {
+ atf_tc_set_md_var(tc, "descr", "check setting of source line");
+}
+ATF_TC_BODY(lex_setline, tc) {
+ isc_mem_t *mctx = NULL;
+ isc_result_t result;
+ isc_lex_t *lex = NULL;
+ unsigned char text[] = "text\nto\nbe\nprocessed\nby\nlexer";
+ isc_buffer_t buf;
+ isc_token_t token;
+ unsigned long line;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_mem_create(0, 0, &mctx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_lex_create(mctx, 1024, &lex);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_buffer_init(&buf, &text[0], sizeof(text));
+ isc_buffer_add(&buf, sizeof(text));
+
+ result = isc_lex_openbuffer(lex, &buf);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_lex_setsourceline(lex, 100);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ for (i = 0; i < 6; i++) {
+ result = isc_lex_gettoken(lex, 0, &token);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ line = isc_lex_getsourceline(lex);
+ ATF_REQUIRE_EQ(line, 100U + i);
+ }
+
+ result = isc_lex_gettoken(lex, 0, &token);
+ ATF_REQUIRE_EQ(result, ISC_R_EOF);
+
+ line = isc_lex_getsourceline(lex);
+ ATF_REQUIRE_EQ(line, 105U);
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, lex_0xff);
+ ATF_TP_ADD_TC(tp, lex_setline);
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/mem_test.c b/lib/isc/tests/mem_test.c
new file mode 100644
index 0000000..22de74f
--- /dev/null
+++ b/lib/isc/tests/mem_test.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <atf-c.h>
+
+#include "isctest.h"
+
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/result.h>
+
+static void *
+default_memalloc(void *arg, size_t size) {
+ UNUSED(arg);
+ if (size == 0U)
+ size = 1;
+ return (malloc(size));
+}
+
+static void
+default_memfree(void *arg, void *ptr) {
+ UNUSED(arg);
+ free(ptr);
+}
+
+ATF_TC(isc_mem);
+ATF_TC_HEAD(isc_mem, tc) {
+ atf_tc_set_md_var(tc, "descr", "general memory system tests");
+}
+
+#define MP1_FREEMAX 10
+#define MP1_FILLCNT 10
+#define MP1_MAXALLOC 30
+
+#define MP2_FREEMAX 25
+#define MP2_FILLCNT 25
+
+ATF_TC_BODY(isc_mem, tc) {
+ isc_result_t result;
+ void *items1[50];
+ void *items2[50];
+ void *tmp;
+ isc_mem_t *localmctx = NULL;
+ isc_mempool_t *mp1 = NULL, *mp2 = NULL;
+ unsigned int i, j;
+ int rval;
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mem_create(0, 0, &localmctx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mempool_create(localmctx, 24, &mp1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mempool_create(localmctx, 31, &mp2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_mempool_setfreemax(mp1, MP1_FREEMAX);
+ isc_mempool_setfillcount(mp1, MP1_FILLCNT);
+ isc_mempool_setmaxalloc(mp1, MP1_MAXALLOC);
+
+ /*
+ * Allocate MP1_MAXALLOC items from the pool. This is our max.
+ */
+ for (i = 0; i < MP1_MAXALLOC; i++) {
+ items1[i] = isc_mempool_get(mp1);
+ ATF_CHECK(items1[i] != NULL);
+ }
+
+ /*
+ * Try to allocate one more. This should fail.
+ */
+ tmp = isc_mempool_get(mp1);
+ ATF_CHECK_EQ(tmp, NULL);
+
+ /*
+ * Free the first 11 items. Verify that there are 10 free items on
+ * the free list (which is our max).
+ */
+ for (i = 0; i < 11; i++) {
+ isc_mempool_put(mp1, items1[i]);
+ items1[i] = NULL;
+ }
+
+ rval = isc_mempool_getfreecount(mp1);
+ ATF_CHECK_EQ(rval, 10);
+
+ rval = isc_mempool_getallocated(mp1);
+ ATF_CHECK_EQ(rval, 19);
+
+ /*
+ * Now, beat up on mp2 for a while. Allocate 50 items, then free
+ * them, then allocate 50 more, etc.
+ */
+
+ isc_mempool_setfreemax(mp2, 25);
+ isc_mempool_setfillcount(mp2, 25);
+
+ for (j = 0; j < 500000; j++) {
+ for (i = 0; i < 50; i++) {
+ items2[i] = isc_mempool_get(mp2);
+ ATF_CHECK(items2[i] != NULL);
+ }
+ for (i = 0; i < 50; i++) {
+ isc_mempool_put(mp2, items2[i]);
+ items2[i] = NULL;
+ }
+ }
+
+ /*
+ * Free all the other items and blow away this pool.
+ */
+ for (i = 11; i < MP1_MAXALLOC; i++) {
+ isc_mempool_put(mp1, items1[i]);
+ items1[i] = NULL;
+ }
+
+ isc_mempool_destroy(&mp1);
+ isc_mempool_destroy(&mp2);
+
+ isc_mem_destroy(&localmctx);
+
+ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
+ NULL, &localmctx, ISC_MEMFLAG_INTERNAL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mempool_create(localmctx, 2, &mp1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ tmp = isc_mempool_get(mp1);
+ ATF_CHECK(tmp != NULL);
+
+ isc_mempool_put(mp1, tmp);
+
+ isc_mempool_destroy(&mp1);
+
+ isc_test_end();
+}
+
+ATF_TC(isc_mem_total);
+ATF_TC_HEAD(isc_mem_total, tc) {
+ atf_tc_set_md_var(tc, "descr", "test TotalUse calculation");
+}
+
+ATF_TC_BODY(isc_mem_total, tc) {
+ isc_result_t result;
+ isc_mem_t *mctx2 = NULL;
+ size_t before, after;
+ ssize_t diff;
+ int i;
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /* Local alloc, free */
+ mctx2 = NULL;
+ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx2, 0);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+
+ before = isc_mem_total(mctx2);
+
+ for (i = 0; i < 100000; i++) {
+ void *ptr;
+
+ ptr = isc_mem_allocate(mctx2, 2048);
+ isc_mem_free(mctx2, ptr);
+ }
+
+ after = isc_mem_total(mctx2);
+ diff = after - before;
+
+ printf("total_before=%lu, total_after=%lu, total_diff=%lu\n",
+ (unsigned long)before, (unsigned long)after,
+ (unsigned long)diff);
+ /* 2048 +8 bytes extra for size_info */
+ ATF_CHECK_EQ(diff, (2048 + 8) * 100000);
+
+ /* ISC_MEMFLAG_INTERNAL */
+
+ before = isc_mem_total(mctx);
+
+ for (i = 0; i < 100000; i++) {
+ void *ptr;
+
+ ptr = isc_mem_allocate(mctx, 2048);
+ isc_mem_free(mctx, ptr);
+ }
+
+ after = isc_mem_total(mctx);
+ diff = after - before;
+
+ printf("total_before=%lu, total_after=%lu, total_diff=%lu\n",
+ (unsigned long)before, (unsigned long)after,
+ (unsigned long)diff);
+ /* 2048 +8 bytes extra for size_info */
+ ATF_CHECK_EQ(diff, (2048 + 8) * 100000);
+
+ out:
+ if (mctx2 != NULL)
+ isc_mem_destroy(&mctx2);
+
+ isc_test_end();
+}
+
+ATF_TC(isc_mem_inuse);
+ATF_TC_HEAD(isc_mem_inuse, tc) {
+ atf_tc_set_md_var(tc, "descr", "test InUse calculation");
+}
+
+ATF_TC_BODY(isc_mem_inuse, tc) {
+ isc_result_t result;
+ isc_mem_t *mctx2 = NULL;
+ size_t before, during, after;
+ ssize_t diff;
+ void *ptr;
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ mctx2 = NULL;
+ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx2, 0);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+
+ before = isc_mem_inuse(mctx2);
+ ptr = isc_mem_allocate(mctx2, 1024000);
+ during = isc_mem_inuse(mctx2);
+ isc_mem_free(mctx2, ptr);
+ after = isc_mem_inuse(mctx2);
+
+ diff = after - before;
+
+ printf("inuse_before=%lu, inuse_during=%lu, inuse_after=%lu\n",
+ (unsigned long)before, (unsigned long)during,
+ (unsigned long)after);
+ ATF_REQUIRE_EQ(diff, 0);
+
+ out:
+ if (mctx2 != NULL)
+ isc_mem_destroy(&mctx2);
+
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_mem);
+ ATF_TP_ADD_TC(tp, isc_mem_total);
+ ATF_TP_ADD_TC(tp, isc_mem_inuse);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/netaddr_test.c b/lib/isc/tests/netaddr_test.c
new file mode 100644
index 0000000..aa41b96
--- /dev/null
+++ b/lib/isc/tests/netaddr_test.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/* ! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/netaddr.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+ATF_TC(netaddr_isnetzero);
+ATF_TC_HEAD(netaddr_isnetzero, tc) {
+ atf_tc_set_md_var(tc, "descr", "test netaddr_isnetzero");
+}
+ATF_TC_BODY(netaddr_isnetzero, tc) {
+ unsigned int i;
+ struct in_addr ina;
+ struct {
+ const char *address;
+ bool expect;
+ } tests[] = {
+ { "0.0.0.0", true },
+ { "0.0.0.1", true },
+ { "0.0.1.2", true },
+ { "0.1.2.3", true },
+ { "10.0.0.0", false },
+ { "10.9.0.0", false },
+ { "10.9.8.0", false },
+ { "10.9.8.7", false },
+ { "127.0.0.0", false },
+ { "127.0.0.1", false }
+ };
+ bool result;
+ isc_netaddr_t netaddr;
+
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
+ ina.s_addr = inet_addr(tests[i].address);
+ isc_netaddr_fromin(&netaddr, &ina);
+ result = isc_netaddr_isnetzero(&netaddr);
+ ATF_CHECK_EQ_MSG(result, tests[i].expect,
+ "%s", tests[i].address);
+ }
+}
+
+ATF_TC(netaddr_masktoprefixlen);
+ATF_TC_HEAD(netaddr_masktoprefixlen, tc) {
+ atf_tc_set_md_var(tc, "descr",
+ "isc_netaddr_masktoprefixlen() "
+ "calculates correct prefix lengths ");
+}
+ATF_TC_BODY(netaddr_masktoprefixlen, tc) {
+ struct in_addr na_a;
+ struct in_addr na_b;
+ struct in_addr na_c;
+ struct in_addr na_d;
+ isc_netaddr_t ina_a;
+ isc_netaddr_t ina_b;
+ isc_netaddr_t ina_c;
+ isc_netaddr_t ina_d;
+ unsigned int plen;
+
+ UNUSED(tc);
+
+ ATF_CHECK(inet_pton(AF_INET, "0.0.0.0", &na_a) >= 0);
+ ATF_CHECK(inet_pton(AF_INET, "255.255.255.254", &na_b) >= 0);
+ ATF_CHECK(inet_pton(AF_INET, "255.255.255.255", &na_c) >= 0);
+ ATF_CHECK(inet_pton(AF_INET, "255.255.255.0", &na_d) >= 0);
+
+ isc_netaddr_fromin(&ina_a, &na_a);
+ isc_netaddr_fromin(&ina_b, &na_b);
+ isc_netaddr_fromin(&ina_c, &na_c);
+ isc_netaddr_fromin(&ina_d, &na_d);
+
+ ATF_CHECK_EQ(isc_netaddr_masktoprefixlen(&ina_a, &plen),
+ ISC_R_SUCCESS);
+ ATF_CHECK_EQ(plen, 0);
+
+ ATF_CHECK_EQ(isc_netaddr_masktoprefixlen(&ina_b, &plen),
+ ISC_R_SUCCESS);
+ ATF_CHECK_EQ(plen, 31);
+
+ ATF_CHECK_EQ(isc_netaddr_masktoprefixlen(&ina_c, &plen),
+ ISC_R_SUCCESS);
+ ATF_CHECK_EQ(plen, 32);
+
+ ATF_CHECK_EQ(isc_netaddr_masktoprefixlen(&ina_d, &plen),
+ ISC_R_SUCCESS);
+ ATF_CHECK_EQ(plen, 24);
+}
+
+ATF_TC(netaddr_multicast);
+ATF_TC_HEAD(netaddr_multicast, tc) {
+ atf_tc_set_md_var(tc, "descr",
+ "check multicast addresses are detected properly");
+}
+ATF_TC_BODY(netaddr_multicast, tc) {
+ unsigned int i;
+ struct {
+ int family;
+ const char *addr;
+ bool is_multicast;
+ } tests[] = {
+ { AF_INET, "1.2.3.4", false },
+ { AF_INET, "4.3.2.1", false },
+ { AF_INET, "224.1.1.1", true },
+ { AF_INET, "1.1.1.244", false },
+ { AF_INET6, "::1", false },
+ { AF_INET6, "ff02::1", true }
+ };
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ isc_netaddr_t na;
+ struct in_addr in;
+ struct in6_addr in6;
+ int r;
+
+ if (tests[i].family == AF_INET) {
+ r = inet_pton(AF_INET, tests[i].addr,
+ (unsigned char *)&in);
+ ATF_REQUIRE_EQ(r, 1);
+ isc_netaddr_fromin(&na, &in);
+ } else {
+ r = inet_pton(AF_INET6, tests[i].addr,
+ (unsigned char *)&in6);
+ ATF_REQUIRE_EQ(r, 1);
+ isc_netaddr_fromin6(&na, &in6);
+ }
+
+ ATF_CHECK_EQ(isc_netaddr_ismulticast(&na),
+ tests[i].is_multicast);
+ }
+}
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, netaddr_isnetzero);
+ ATF_TP_ADD_TC(tp, netaddr_masktoprefixlen);
+ ATF_TP_ADD_TC(tp, netaddr_multicast);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/parse_test.c b/lib/isc/tests/parse_test.c
new file mode 100644
index 0000000..edc8139
--- /dev/null
+++ b/lib/isc/tests/parse_test.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <inttypes.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <isc/parseint.h>
+
+#include "isctest.h"
+
+/*
+ * Individual unit tests
+ */
+
+/* Test for 32 bit overflow on 64 bit machines in isc_parse_uint32 */
+ATF_TC(parse_overflow);
+ATF_TC_HEAD(parse_overflow, tc) {
+ atf_tc_set_md_var(tc, "descr", "Check for 32 bit overflow");
+}
+ATF_TC_BODY(parse_overflow, tc) {
+ isc_result_t result;
+ uint32_t output;
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_parse_uint32(&output, "1234567890", 10);
+ ATF_CHECK_EQ(ISC_R_SUCCESS, result);
+ ATF_CHECK_EQ(1234567890, output);
+
+ result = isc_parse_uint32(&output, "123456789012345", 10);
+ ATF_CHECK_EQ(ISC_R_RANGE, result);
+
+ result = isc_parse_uint32(&output, "12345678901234567890", 10);
+ ATF_CHECK_EQ(ISC_R_RANGE, result);
+
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, parse_overflow);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/pool_test.c b/lib/isc/tests/pool_test.c
new file mode 100644
index 0000000..fb9197e
--- /dev/null
+++ b/lib/isc/tests/pool_test.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+
+#include <isc/mem.h>
+#include <isc/pool.h>
+
+#include "isctest.h"
+
+static isc_result_t
+poolinit(void **target, void *arg) {
+ isc_result_t result;
+
+ isc_taskmgr_t *mgr = (isc_taskmgr_t *) arg;
+ isc_task_t *task = NULL;
+ result = isc_task_create(mgr, 0, &task);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ *target = (void *) task;
+ return (ISC_R_SUCCESS);
+}
+
+static void
+poolfree(void **target) {
+ isc_task_t *task = *(isc_task_t **) target;
+ isc_task_destroy(&task);
+ *target = NULL;
+}
+
+/*
+ * Individual unit tests
+ */
+
+/* Create a pool */
+ATF_TC(create_pool);
+ATF_TC_HEAD(create_pool, tc) {
+ atf_tc_set_md_var(tc, "descr", "create a pool");
+}
+ATF_TC_BODY(create_pool, tc) {
+ isc_result_t result;
+ isc_pool_t *pool = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_pool_create(mctx, 8, poolfree, poolinit, taskmgr, &pool);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_pool_count(pool), 8);
+
+ isc_pool_destroy(&pool);
+ ATF_REQUIRE_EQ(pool, NULL);
+
+ isc_test_end();
+}
+
+/* Resize a pool */
+ATF_TC(expand_pool);
+ATF_TC_HEAD(expand_pool, tc) {
+ atf_tc_set_md_var(tc, "descr", "expand a pool");
+}
+ATF_TC_BODY(expand_pool, tc) {
+ isc_result_t result;
+ isc_pool_t *pool1 = NULL, *pool2 = NULL, *hold = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_pool_create(mctx, 10, poolfree, poolinit, taskmgr, &pool1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_pool_count(pool1), 10);
+
+ /* resizing to a smaller size should have no effect */
+ hold = pool1;
+ result = isc_pool_expand(&pool1, 5, &pool2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_pool_count(pool2), 10);
+ ATF_REQUIRE_EQ(pool2, hold);
+ ATF_REQUIRE_EQ(pool1, NULL);
+ pool1 = pool2;
+ pool2 = NULL;
+
+ /* resizing to the same size should have no effect */
+ hold = pool1;
+ result = isc_pool_expand(&pool1, 10, &pool2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_pool_count(pool2), 10);
+ ATF_REQUIRE_EQ(pool2, hold);
+ ATF_REQUIRE_EQ(pool1, NULL);
+ pool1 = pool2;
+ pool2 = NULL;
+
+ /* resizing to larger size should make a new pool */
+ hold = pool1;
+ result = isc_pool_expand(&pool1, 20, &pool2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_pool_count(pool2), 20);
+ ATF_REQUIRE(pool2 != hold);
+ ATF_REQUIRE_EQ(pool1, NULL);
+
+ isc_pool_destroy(&pool2);
+ ATF_REQUIRE_EQ(pool2, NULL);
+
+ isc_test_end();
+}
+
+/* Get objects */
+ATF_TC(get_objects);
+ATF_TC_HEAD(get_objects, tc) {
+ atf_tc_set_md_var(tc, "descr", "get objects");
+}
+ATF_TC_BODY(get_objects, tc) {
+ isc_result_t result;
+ isc_pool_t *pool = NULL;
+ void *item;
+ isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_pool_create(mctx, 2, poolfree, poolinit, taskmgr, &pool);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_pool_count(pool), 2);
+
+ item = isc_pool_get(pool);
+ ATF_REQUIRE(item != NULL);
+ isc_task_attach((isc_task_t *) item, &task1);
+
+ item = isc_pool_get(pool);
+ ATF_REQUIRE(item != NULL);
+ isc_task_attach((isc_task_t *) item, &task2);
+
+ item = isc_pool_get(pool);
+ ATF_REQUIRE(item != NULL);
+ isc_task_attach((isc_task_t *) item, &task3);
+
+ isc_task_detach(&task1);
+ isc_task_detach(&task2);
+ isc_task_detach(&task3);
+
+ isc_pool_destroy(&pool);
+ ATF_REQUIRE_EQ(pool, NULL);
+
+ isc_test_end();
+}
+
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, create_pool);
+ ATF_TP_ADD_TC(tp, expand_pool);
+ ATF_TP_ADD_TC(tp, get_objects);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/print_test.c b/lib/isc/tests/print_test.c
new file mode 100644
index 0000000..259e301
--- /dev/null
+++ b/lib/isc/tests/print_test.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * Workout if we need to force the inclusion of print.c so we can test
+ * it on all platforms even if we don't include it in libisc.
+ */
+#include <isc/platform.h>
+#if !defined(ISC_PLATFORM_NEEDPRINTF) && \
+ !defined(ISC_PLATFORM_NEEDFPRINTF) && \
+ !defined(ISC_PLATFORM_NEEDSPRINTF) && \
+ !defined(ISC_PLATFORM_NEEDVSNPRINTF)
+#define ISC__PRINT_SOURCE
+#include "../print.c"
+#else
+#if !defined(ISC_PLATFORM_NEEDPRINTF) || \
+ !defined(ISC_PLATFORM_NEEDFPRINTF) || \
+ !defined(ISC_PLATFORM_NEEDSPRINTF) || \
+ !defined(ISC_PLATFORM_NEEDVSNPRINTF)
+#define ISC__PRINT_SOURCE
+#endif
+#include <isc/print.h>
+#include <isc/types.h>
+#include <isc/util.h>
+#endif
+
+ATF_TC(snprintf);
+ATF_TC_HEAD(snprintf, tc) {
+ atf_tc_set_md_var(tc, "descr", "snprintf implementation");
+}
+ATF_TC_BODY(snprintf, tc) {
+ char buf[10000];
+ uint64_t ll = 8589934592ULL;
+ uint64_t nn = 20000000000000ULL;
+ uint64_t zz = 10000000000000000000ULL;
+ float pi = 3.141;
+ int n;
+ size_t size;
+
+ UNUSED(tc);
+
+ /*
+ * 4294967296 <= 8589934592 < 1000000000^2 to verify fix for
+ * RT#36505.
+ */
+
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%" PRIu64, ll);
+ ATF_CHECK_EQ(n, 10);
+ ATF_CHECK_STREQ(buf, "8589934592");
+
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%" PRIu64, ll);
+ ATF_CHECK_EQ(n, 10);
+ ATF_CHECK_STREQ(buf, "8589934592");
+
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%" PRIu64, nn);
+ ATF_CHECK_EQ(n, 14);
+ ATF_CHECK_STREQ(buf, "20000000000000");
+
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%" PRIu64, nn);
+ ATF_CHECK_EQ(n, 14);
+ ATF_CHECK_STREQ(buf, "20000000000000");
+
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%" PRIu64, zz);
+ ATF_CHECK_EQ(n, 20);
+ ATF_CHECK_STREQ(buf, "10000000000000000000");
+
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%" PRIu64, zz);
+ ATF_CHECK_EQ(n, 20);
+ ATF_CHECK_STREQ(buf, "10000000000000000000");
+
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%" PRId64, nn);
+ ATF_CHECK_EQ(n, 14);
+ ATF_CHECK_STREQ(buf, "20000000000000");
+
+ size = 1000;
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%zu", size);
+ ATF_CHECK_EQ(n, 4);
+ ATF_CHECK_STREQ(buf, "1000");
+
+ size = 1000;
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%zx", size);
+ ATF_CHECK_EQ(n, 3);
+ ATF_CHECK_STREQ(buf, "3e8");
+
+ size = 1000;
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%zo", size);
+ ATF_CHECK_EQ(n, 4);
+ ATF_CHECK_STREQ(buf, "1750");
+
+ zz = 0xf5f5f5f5f5f5f5f5ULL;
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "0x%" PRIx64, zz);
+ ATF_CHECK_EQ(n, 18);
+ ATF_CHECK_STREQ(buf, "0xf5f5f5f5f5f5f5f5");
+
+ n = isc_print_snprintf(buf, sizeof(buf), "%.2f", pi);
+ ATF_CHECK_EQ(n, 4);
+ ATF_CHECK_STREQ(buf, "3.14");
+
+ /* Similar to the above, but additional characters follows */
+ n = isc_print_snprintf(buf, sizeof(buf), "%.2f1592", pi);
+ ATF_CHECK_EQ(n, 8);
+ ATF_CHECK_STREQ(buf, "3.141592");
+
+ /* Similar to the above, but with leading spaces */
+ n = isc_print_snprintf(buf, sizeof(buf), "% 8.2f1592", pi);
+ ATF_CHECK_EQ(n, 12);
+ ATF_CHECK_STREQ(buf, " 3.141592");
+
+ /* Similar to the above, but with trail spaces after the 4 */
+ n = isc_print_snprintf(buf, sizeof(buf), "%-8.2f1592", pi);
+ ATF_CHECK_EQ(n, 12);
+ ATF_CHECK_STREQ(buf, "3.14 1592");
+}
+
+ATF_TC(fprintf);
+ATF_TC_HEAD(fprintf, tc) {
+ atf_tc_set_md_var(tc, "descr", "fprintf implementation");
+}
+ATF_TC_BODY(fprintf, tc) {
+ FILE *f;
+ int n;
+ size_t size;
+ char buf[10000];
+
+ UNUSED(tc);
+
+ f = fopen("fprintf.test", "w+");
+ ATF_REQUIRE(f != NULL);
+
+ size = 1000;
+ n = isc_print_fprintf(f, "%zu", size);
+ ATF_CHECK_EQ(n, 4);
+
+ rewind(f);
+
+ memset(buf, 0, sizeof(buf));
+ n = fread(buf, 1, sizeof(buf), f);
+ ATF_CHECK_EQ(n, 4);
+
+ fclose(f);
+
+ ATF_CHECK_STREQ(buf, "1000");
+
+ if ((n > 0) && (!strcmp(buf, "1000")))
+ unlink("fprintf.test");
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, snprintf);
+ ATF_TP_ADD_TC(tp, fprintf);
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/queue_test.c b/lib/isc/tests/queue_test.c
new file mode 100644
index 0000000..843e641
--- /dev/null
+++ b/lib/isc/tests/queue_test.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+#include <time.h>
+
+#include <isc/queue.h>
+
+#include "isctest.h"
+
+typedef struct item item_t;
+struct item {
+ int value;
+ ISC_QLINK(item_t) qlink;
+};
+
+typedef ISC_QUEUE(item_t) item_queue_t;
+
+static void
+item_init(item_t *item, int value) {
+ item->value = value;
+ ISC_QLINK_INIT(item, qlink);
+}
+
+/*
+ * Individual unit tests
+ */
+
+/* Test UDP sendto/recv (IPv4) */
+ATF_TC(queue_valid);
+ATF_TC_HEAD(queue_valid, tc) {
+ atf_tc_set_md_var(tc, "descr", "Check queue validity");
+}
+ATF_TC_BODY(queue_valid, tc) {
+ isc_result_t result;
+ item_queue_t queue;
+ item_t one, two, three, four, five;
+ item_t *p;
+
+ UNUSED(tc);
+
+ ISC_QUEUE_INIT(queue, qlink);
+
+ item_init(&one, 1);
+ item_init(&two, 2);
+ item_init(&three, 3);
+ item_init(&four, 4);
+ item_init(&five, 5);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_CHECK(ISC_QUEUE_EMPTY(queue));
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_CHECK(p == NULL);
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&one, qlink));
+ ISC_QUEUE_PUSH(queue, &one, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&one, qlink));
+
+ ATF_CHECK(! ISC_QUEUE_EMPTY(queue));
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 1);
+ ATF_CHECK(ISC_QUEUE_EMPTY(queue));
+ ATF_CHECK(! ISC_QLINK_LINKED(p, qlink));
+
+ ISC_QUEUE_PUSH(queue, p, qlink);
+ ATF_CHECK(! ISC_QUEUE_EMPTY(queue));
+ ATF_CHECK(ISC_QLINK_LINKED(p, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&two, qlink));
+ ISC_QUEUE_PUSH(queue, &two, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&two, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&three, qlink));
+ ISC_QUEUE_PUSH(queue, &three, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&three, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&four, qlink));
+ ISC_QUEUE_PUSH(queue, &four, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&four, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&five, qlink));
+ ISC_QUEUE_PUSH(queue, &five, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&five, qlink));
+
+ /* Test unlink by removing one item from the middle */
+ ISC_QUEUE_UNLINK(queue, &three, qlink);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 1);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 2);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 4);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 5);
+
+ ATF_CHECK(ISC_QUEUE_EMPTY(queue));
+
+ ISC_QUEUE_DESTROY(queue);
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, queue_valid);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/radix_test.c b/lib/isc/tests/radix_test.c
new file mode 100644
index 0000000..0a0b534
--- /dev/null
+++ b/lib/isc/tests/radix_test.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <isc/mem.h>
+#include <isc/netaddr.h>
+#include <isc/radix.h>
+#include <isc/result.h>
+#include <isc/util.h>
+
+#include <atf-c.h>
+
+#include <stdlib.h>
+
+#include "isctest.h"
+
+ATF_TC(isc_radix_search);
+ATF_TC_HEAD(isc_radix_search, tc) {
+ atf_tc_set_md_var(tc, "descr", "test radix seaching");
+}
+ATF_TC_BODY(isc_radix_search, tc) {
+ isc_radix_tree_t *radix = NULL;
+ isc_radix_node_t *node;
+ isc_prefix_t prefix;
+ isc_result_t result;
+ struct in_addr in_addr;
+ isc_netaddr_t netaddr;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_radix_create(mctx, &radix, 32);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ in_addr.s_addr = inet_addr("3.3.3.0");
+ isc_netaddr_fromin(&netaddr, &in_addr);
+ NETADDR_TO_PREFIX_T(&netaddr, prefix, 24, false);
+
+ node = NULL;
+ result = isc_radix_insert(radix, &node, NULL, &prefix);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ node->data[0] = (void *)1;
+ isc_refcount_destroy(&prefix.refcount);
+
+ in_addr.s_addr = inet_addr("3.3.0.0");
+ isc_netaddr_fromin(&netaddr, &in_addr);
+ NETADDR_TO_PREFIX_T(&netaddr, prefix, 16, false);
+
+ node = NULL;
+ result = isc_radix_insert(radix, &node, NULL, &prefix);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ node->data[0] = (void *)2;
+ isc_refcount_destroy(&prefix.refcount);
+
+ in_addr.s_addr = inet_addr("3.3.3.3");
+ isc_netaddr_fromin(&netaddr, &in_addr);
+ NETADDR_TO_PREFIX_T(&netaddr, prefix, 22, false);
+
+ node = NULL;
+ result = isc_radix_search(radix, &node, &prefix);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(node->data[0], (void *)2);
+
+ isc_refcount_destroy(&prefix.refcount);
+
+ isc_radix_destroy(radix, NULL);
+
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_radix_search);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/random_test.c b/lib/isc/tests/random_test.c
new file mode 100644
index 0000000..5637139
--- /dev/null
+++ b/lib/isc/tests/random_test.c
@@ -0,0 +1,670 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*
+ * IMPORTANT NOTE:
+ * These tests work by generating a large number of pseudo-random numbers
+ * and then statistically analyzing them to determine whether they seem
+ * random. The test is expected to fail on occasion by random happenstance.
+ */
+
+#include <config.h>
+
+#include <stdbool.h>
+
+#include <isc/random.h>
+#include <isc/result.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/util.h>
+
+#include <atf-c.h>
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#define REPS 25000
+
+typedef double (pvalue_func_t)(isc_mem_t *mctx,
+ uint16_t *values, size_t length);
+
+/* igamc(), igam(), etc. were adapted (and cleaned up) from the Cephes
+ * math library:
+ *
+ * Cephes Math Library Release 2.8: June, 2000
+ * Copyright 1985, 1987, 2000 by Stephen L. Moshier
+ *
+ * The Cephes math library was released into the public domain as part
+ * of netlib.
+*/
+
+static double MACHEP = 1.11022302462515654042E-16;
+static double MAXLOG = 7.09782712893383996843E2;
+static double big = 4.503599627370496e15;
+static double biginv = 2.22044604925031308085e-16;
+
+static double igamc(double a, double x);
+static double igam(double a, double x);
+
+static double
+igamc(double a, double x) {
+ double ans, ax, c, yc, r, t, y, z;
+ double pk, pkm1, pkm2, qk, qkm1, qkm2;
+
+ if ((x <= 0) || (a <= 0))
+ return (1.0);
+
+ if ((x < 1.0) || (x < a))
+ return (1.0 - igam(a, x));
+
+ ax = a * log(x) - x - lgamma(a);
+ if (ax < -MAXLOG) {
+ fprintf(stderr, "igamc: UNDERFLOW, ax=%f\n", ax);
+ return (0.0);
+ }
+ ax = exp(ax);
+
+ /* continued fraction */
+ y = 1.0 - a;
+ z = x + y + 1.0;
+ c = 0.0;
+ pkm2 = 1.0;
+ qkm2 = x;
+ pkm1 = x + 1.0;
+ qkm1 = z * x;
+ ans = pkm1 / qkm1;
+
+ do {
+ c += 1.0;
+ y += 1.0;
+ z += 2.0;
+ yc = y * c;
+ pk = pkm1 * z - pkm2 * yc;
+ qk = qkm1 * z - qkm2 * yc;
+ if (qk != 0) {
+ r = pk / qk;
+ t = fabs((ans - r) / r);
+ ans = r;
+ } else
+ t = 1.0;
+
+ pkm2 = pkm1;
+ pkm1 = pk;
+ qkm2 = qkm1;
+ qkm1 = qk;
+
+ if (fabs(pk) > big) {
+ pkm2 *= biginv;
+ pkm1 *= biginv;
+ qkm2 *= biginv;
+ qkm1 *= biginv;
+ }
+ } while (t > MACHEP);
+
+ return (ans * ax);
+}
+
+static double
+igam(double a, double x) {
+ double ans, ax, c, r;
+
+ if ((x <= 0) || (a <= 0))
+ return (0.0);
+
+ if ((x > 1.0) && (x > a))
+ return (1.0 - igamc(a, x));
+
+ /* Compute x**a * exp(-x) / md_gamma(a) */
+ ax = a * log(x) - x - lgamma(a);
+ if( ax < -MAXLOG ) {
+ fprintf(stderr, "igam: UNDERFLOW, ax=%f\n", ax);
+ return (0.0);
+ }
+ ax = exp(ax);
+
+ /* power series */
+ r = a;
+ c = 1.0;
+ ans = 1.0;
+
+ do {
+ r += 1.0;
+ c *= x / r;
+ ans += c;
+ } while (c / ans > MACHEP);
+
+ return (ans * ax / a);
+}
+
+static int8_t scounts_table[65536];
+static uint8_t bitcounts_table[65536];
+
+static int8_t
+scount_calculate(uint16_t n) {
+ int i;
+ int8_t sc;
+
+ sc = 0;
+ for (i = 0; i < 16; i++) {
+ uint16_t lsb;
+
+ lsb = n & 1;
+ if (lsb != 0)
+ sc += 1;
+ else
+ sc -= 1;
+
+ n >>= 1;
+ }
+
+ return (sc);
+}
+
+static uint8_t
+bitcount_calculate(uint16_t n) {
+ int i;
+ uint8_t bc;
+
+ bc = 0;
+ for (i = 0; i < 16; i++) {
+ uint16_t lsb;
+
+ lsb = n & 1;
+ if (lsb != 0)
+ bc += 1;
+
+ n >>= 1;
+ }
+
+ return (bc);
+}
+
+static void
+tables_init(void) {
+ uint32_t i;
+
+ for (i = 0; i < 65536; i++) {
+ scounts_table[i] = scount_calculate(i);
+ bitcounts_table[i] = bitcount_calculate(i);
+ }
+}
+
+/*
+ * The following code for computing Marsaglia's rank is based on the
+ * implementation in cdbinrnk.c from the diehard tests by George
+ * Marsaglia.
+ *
+ * This function destroys (modifies) the data passed in bits.
+ */
+static uint32_t
+matrix_binaryrank(uint32_t *bits, size_t rows, size_t cols) {
+ size_t i, j, k;
+ unsigned int rt = 0;
+ uint32_t rank = 0;
+ uint32_t tmp;
+
+ for (k = 0; k < rows; k++) {
+ i = k;
+
+ while (rt >= cols || ((bits[i] >> rt) & 1) == 0) {
+ i++;
+
+ if (i < rows)
+ continue;
+ else {
+ rt++;
+ if (rt < cols) {
+ i = k;
+ continue;
+ }
+ }
+
+ return (rank);
+ }
+
+ rank++;
+ if (i != k) {
+ tmp = bits[i];
+ bits[i] = bits[k];
+ bits[k] = tmp;
+ }
+
+ for (j = i + 1; j < rows; j++) {
+ if (((bits[j] >> rt) & 1) == 0)
+ continue;
+ else
+ bits[j] ^= bits[k];
+ }
+
+ rt++;
+ }
+
+ return (rank);
+}
+
+static void
+random_test(pvalue_func_t *func) {
+ isc_mem_t *mctx = NULL;
+ isc_result_t result;
+ isc_rng_t *rng;
+ uint32_t m;
+ uint32_t j;
+ uint32_t histogram[11] = { 0 };
+ uint32_t passed;
+ double proportion;
+ double p_hat;
+ double lower_confidence, higher_confidence;
+ double chi_square;
+ double p_value_t;
+ double alpha;
+
+ tables_init();
+
+ result = isc_mem_create(0, 0, &mctx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ rng = NULL;
+ result = isc_rng_create(mctx, NULL, &rng);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ m = 1000;
+ passed = 0;
+
+ for (j = 0; j < m; j++) {
+ uint32_t i;
+ uint16_t values[REPS];
+ double p_value;
+
+ for (i = 0; i < REPS; i++)
+ values[i] = isc_rng_random(rng);
+
+ p_value = (*func)(mctx, values, REPS);
+ if (p_value >= 0.01) {
+ passed++;
+ }
+
+ ATF_REQUIRE(p_value >= 0.0);
+ ATF_REQUIRE(p_value <= 1.0);
+
+ i = (int) floor(p_value * 10);
+ histogram[i]++;
+ }
+
+ isc_rng_detach(&rng);
+
+ /*
+ * Check proportion of sequences passing a test (see section
+ * 4.2.1 in NIST SP 800-22).
+ */
+ alpha = 0.01; /* the significance level */
+ proportion = (double) passed / (double) m;
+ p_hat = 1.0 - alpha;
+ lower_confidence = p_hat - (3.0 * sqrt((p_hat * (1.0 - p_hat)) / m));
+ higher_confidence = p_hat + (3.0 * sqrt((p_hat * (1.0 - p_hat)) / m));
+
+ /* Debug message, not displayed when running via atf-run */
+ printf("passed=%u/1000\n", passed);
+ printf("higher_confidence=%f, lower_confidence=%f, proportion=%f\n",
+ higher_confidence, lower_confidence, proportion);
+
+ ATF_REQUIRE(proportion >= lower_confidence);
+ ATF_REQUIRE(proportion <= higher_confidence);
+
+ /*
+ * Check uniform distribution of p-values (see section 4.2.2 in
+ * NIST SP 800-22).
+ */
+
+ /* Fold histogram[10] (p_value = 1.0) into histogram[9] for
+ * interval [0.9, 1.0]
+ */
+ histogram[9] += histogram[10];
+ histogram[10] = 0;
+
+ /* Pre-requisite that at least 55 sequences are processed. */
+ ATF_REQUIRE(m >= 55);
+
+ chi_square = 0.0;
+ for (j = 0; j < 10; j++) {
+ double numer;
+ double denom;
+
+ /* Debug message, not displayed when running via atf-run */
+ printf("hist%u=%u ", j, histogram[j]);
+
+ numer = (histogram[j] - (m / 10.0)) *
+ (histogram[j] - (m / 10.0));
+ denom = m / 10.0;
+ chi_square += numer / denom;
+ }
+
+ printf("\n");
+
+ p_value_t = igamc(9 / 2.0, chi_square / 2.0);
+
+ ATF_REQUIRE(p_value_t >= 0.0001);
+}
+
+/*
+ * This is a frequency (monobits) test taken from the NIST SP 800-22
+ * RNG test suite.
+ */
+static double
+monobit(isc_mem_t *mctx, uint16_t *values, size_t length) {
+ size_t i;
+ int32_t scount;
+ uint32_t numbits;
+ double s_obs;
+ double p_value;
+
+ UNUSED(mctx);
+
+ numbits = length * 16;
+ scount = 0;
+
+ for (i = 0; i < length; i++)
+ scount += scounts_table[values[i]];
+
+ /* Preconditions (section 2.1.7 in NIST SP 800-22) */
+ ATF_REQUIRE(numbits >= 100);
+
+ /* Debug message, not displayed when running via atf-run */
+ printf("numbits=%u, scount=%d\n", numbits, scount);
+
+ s_obs = abs(scount) / sqrt(numbits);
+ p_value = erfc(s_obs / sqrt(2.0));
+
+ return (p_value);
+}
+
+/*
+ * This is the runs test taken from the NIST SP 800-22 RNG test suite.
+ */
+static double
+runs(isc_mem_t *mctx, uint16_t *values, size_t length) {
+ size_t i;
+ uint32_t bcount;
+ uint32_t numbits;
+ double pi;
+ double tau;
+ uint32_t j;
+ uint32_t b;
+ uint8_t bit_this;
+ uint8_t bit_prev;
+ uint32_t v_obs;
+ double numer;
+ double denom;
+ double p_value;
+
+ UNUSED(mctx);
+
+ numbits = length * 16;
+ bcount = 0;
+
+ for (i = 0; i < REPS; i++)
+ bcount += bitcounts_table[values[i]];
+
+ /* Debug message, not displayed when running via atf-run */
+ printf("numbits=%u, bcount=%u\n", numbits, bcount);
+
+ pi = (double) bcount / (double) numbits;
+ tau = 2.0 / sqrt(numbits);
+
+ /* Preconditions (section 2.3.7 in NIST SP 800-22) */
+ ATF_REQUIRE(numbits >= 100);
+
+ /*
+ * Pre-condition implied from the monobit test. This can fail
+ * for some sequences, and the p-value is taken as 0 in these
+ * cases.
+ */
+ if (fabs(pi - 0.5) >= tau)
+ return (0.0);
+
+ /* Compute v_obs */
+ j = 0;
+ b = 14;
+ bit_prev = (values[j] & (1U << 15)) == 0 ? 0 : 1;
+
+ v_obs = 0;
+
+ for (i = 1; i < numbits; i++) {
+ bit_this = (values[j] & (1U << b)) == 0 ? 0 : 1;
+ if (b == 0) {
+ b = 15;
+ j++;
+ } else {
+ b--;
+ }
+
+ v_obs += bit_this ^ bit_prev;
+
+ bit_prev = bit_this;
+ }
+
+ v_obs += 1;
+
+ numer = fabs(v_obs - (2.0 * numbits * pi * (1.0 - pi)));
+ denom = 2.0 * sqrt(2.0 * numbits) * pi * (1.0 - pi);
+
+ p_value = erfc(numer / denom);
+
+ return (p_value);
+}
+
+/*
+ * This is the block frequency test taken from the NIST SP 800-22 RNG
+ * test suite.
+ */
+static double
+blockfrequency(isc_mem_t *mctx, uint16_t *values, size_t length) {
+ uint32_t i;
+ uint32_t numbits;
+ uint32_t mbits;
+ uint32_t mwords;
+ uint32_t numblocks;
+ double *pi;
+ double chi_square;
+ double p_value;
+
+ numbits = length * 16;
+ mbits = 32000;
+ mwords = mbits / 16;
+ numblocks = numbits / mbits;
+
+ /* Debug message, not displayed when running via atf-run */
+ printf("numblocks=%u\n", numblocks);
+
+ /* Preconditions (section 2.2.7 in NIST SP 800-22) */
+ ATF_REQUIRE(numbits >= 100);
+ ATF_REQUIRE(mbits >= 20);
+ ATF_REQUIRE((double) mbits > (0.01 * numbits));
+ ATF_REQUIRE(numblocks < 100);
+ ATF_REQUIRE(numbits >= (mbits * numblocks));
+
+ pi = isc_mem_get(mctx, numblocks * sizeof(double));
+ ATF_REQUIRE(pi != NULL);
+
+ for (i = 0; i < numblocks; i++) {
+ uint32_t j;
+ pi[i] = 0.0;
+ for (j = 0; j < mwords; j++) {
+ uint32_t idx;
+
+ idx = i * mwords + j;
+ pi[i] += bitcounts_table[values[idx]];
+ }
+ pi[i] /= mbits;
+ }
+
+ /* Compute chi_square */
+ chi_square = 0.0;
+ for (i = 0; i < numblocks; i++)
+ chi_square += (pi[i] - 0.5) * (pi[i] - 0.5);
+
+ chi_square *= 4 * mbits;
+
+ isc_mem_put(mctx, pi, numblocks * sizeof(double));
+
+ /* Debug message, not displayed when running via atf-run */
+ printf("chi_square=%f\n", chi_square);
+
+ p_value = igamc(numblocks * 0.5, chi_square * 0.5);
+
+ return (p_value);
+}
+
+/*
+ * This is the binary matrix rank test taken from the NIST SP 800-22 RNG
+ * test suite.
+ */
+static double
+binarymatrixrank(isc_mem_t *mctx, uint16_t *values, size_t length) {
+ uint32_t i;
+ size_t matrix_m;
+ size_t matrix_q;
+ uint32_t num_matrices;
+ size_t numbits;
+ uint32_t fm_0;
+ uint32_t fm_1;
+ uint32_t fm_rest;
+ double term1;
+ double term2;
+ double term3;
+ double chi_square;
+ double p_value;
+
+ UNUSED(mctx);
+
+ matrix_m = 32;
+ matrix_q = 32;
+ num_matrices = length / ((matrix_m * matrix_q) / 16);
+ numbits = num_matrices * matrix_m * matrix_q;
+
+ /* Preconditions (section 2.5.7 in NIST SP 800-22) */
+ ATF_REQUIRE(matrix_m == 32);
+ ATF_REQUIRE(matrix_q == 32);
+ ATF_REQUIRE(numbits >= (38 * matrix_m * matrix_q));
+
+ fm_0 = 0;
+ fm_1 = 0;
+ fm_rest = 0;
+ for (i = 0; i < num_matrices; i++) {
+ /*
+ * Each uint32_t supplies 32 bits, so a 32x32 bit matrix
+ * takes up uint32_t array of size 32.
+ */
+ uint32_t bits[32];
+ int j;
+ uint32_t rank;
+
+ for (j = 0; j < 32; j++) {
+ size_t idx;
+ uint32_t r1;
+ uint32_t r2;
+
+ idx = i * ((matrix_m * matrix_q) / 16);
+ idx += j * 2;
+
+ r1 = values[idx];
+ r2 = values[idx + 1];
+ bits[j] = (r1 << 16) | r2;
+ }
+
+ rank = matrix_binaryrank(bits, matrix_m, matrix_q);
+
+ if (rank == matrix_m)
+ fm_0++;
+ else if (rank == (matrix_m - 1))
+ fm_1++;
+ else
+ fm_rest++;
+ }
+
+ /* Compute chi_square */
+ term1 = ((fm_0 - (0.2888 * num_matrices)) *
+ (fm_0 - (0.2888 * num_matrices))) / (0.2888 * num_matrices);
+ term2 = ((fm_1 - (0.5776 * num_matrices)) *
+ (fm_1 - (0.5776 * num_matrices))) / (0.5776 * num_matrices);
+ term3 = ((fm_rest - (0.1336 * num_matrices)) *
+ (fm_rest - (0.1336 * num_matrices))) / (0.1336 * num_matrices);
+
+ chi_square = term1 + term2 + term3;
+
+ /* Debug message, not displayed when running via atf-run */
+ printf("fm_0=%u, fm_1=%u, fm_rest=%u, chi_square=%f\n",
+ fm_0, fm_1, fm_rest, chi_square);
+
+ p_value = exp(-chi_square * 0.5);
+
+ return (p_value);
+}
+
+ATF_TC(isc_rng_monobit);
+ATF_TC_HEAD(isc_rng_monobit, tc) {
+ atf_tc_set_md_var(tc, "descr", "Monobit test for the RNG");
+}
+
+ATF_TC_BODY(isc_rng_monobit, tc) {
+ UNUSED(tc);
+
+ random_test(monobit);
+}
+
+ATF_TC(isc_rng_runs);
+ATF_TC_HEAD(isc_rng_runs, tc) {
+ atf_tc_set_md_var(tc, "descr", "Runs test for the RNG");
+}
+
+ATF_TC_BODY(isc_rng_runs, tc) {
+ UNUSED(tc);
+
+ random_test(runs);
+}
+
+ATF_TC(isc_rng_blockfrequency);
+ATF_TC_HEAD(isc_rng_blockfrequency, tc) {
+ atf_tc_set_md_var(tc, "descr", "Block frequency test for the RNG");
+}
+
+ATF_TC_BODY(isc_rng_blockfrequency, tc) {
+ UNUSED(tc);
+
+ random_test(blockfrequency);
+}
+
+ATF_TC(isc_rng_binarymatrixrank);
+ATF_TC_HEAD(isc_rng_binarymatrixrank, tc) {
+ atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RNG");
+}
+
+/*
+ * This is the binary matrix rank test taken from the NIST SP 800-22 RNG
+ * test suite.
+ */
+ATF_TC_BODY(isc_rng_binarymatrixrank, tc) {
+ UNUSED(tc);
+
+ random_test(binarymatrixrank);
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_rng_monobit);
+ ATF_TP_ADD_TC(tp, isc_rng_runs);
+ ATF_TP_ADD_TC(tp, isc_rng_blockfrequency);
+ ATF_TP_ADD_TC(tp, isc_rng_binarymatrixrank);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/regex_test.c b/lib/isc/tests/regex_test.c
new file mode 100644
index 0000000..b5e88b3
--- /dev/null
+++ b/lib/isc/tests/regex_test.c
@@ -0,0 +1,1121 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
+#include <isc/regex.h>
+#include <isc/print.h>
+#include <isc/util.h>
+
+ATF_TC(regex_validate);
+ATF_TC_HEAD(regex_validate, tc) {
+ atf_tc_set_md_var(tc, "descr", "check isc_regex_validate()");
+}
+ATF_TC_BODY(regex_validate, tc) {
+ /*
+ * test regex were generated using http://code.google.com/p/regfuzz/
+ * modified to use only printable characters
+ */
+ struct {
+ const char * expression;
+ int expect;
+ int exception; /* regcomp accepts but is disallowed. */
+ } tests[] = {
+ { "", -1, 0 },
+ { "*", -1, 0 },
+ { ".*", 0, 0 },
+ { ".**", -1, 0 },
+ { ".*\?", -1, 0 },
+ { ".*+", -1, 0 },
+ { "+", -1, 0 },
+ { ".+", 0, 0 },
+ { ".++", -1, 0 },
+ { ".+\?", -1, 0 },
+ { ".+*", -1, 0 },
+ { "\?", -1, 0 },
+ { ".\?", 0, 0 },
+ { ".\?\?", -1, 0 },
+ { ".\?*", -1, 0 },
+ { ".\?+", -1, 0 },
+ { "(", -1, 0 },
+ { "()", 1, 0 },
+ { "(|)", -1, 0 },
+ { "(a|)", -1, 0 },
+ { "(|b)", -1, 0 },
+ { ".{", 0, 0 },
+ { ".{1", -1, 0 },
+ { ".\\{1", 0, 0 },
+ { ".{1}", 0, 0 },
+ { ".\\{1}", 0, 0 },
+ { ".{,", 0, 0 },
+ { ".{,}", 0, 0 },
+ { ".{1,}", 0, 0 },
+ { ".\\{1,}", 0, 0 },
+ { ".{1,\\}", -1, 0 },
+ { ".{1,", -1, 0 },
+ { ".\\{1,", 0, 0 },
+ { ".{1,2}", 0, 0 },
+ { ".{1,2}*", -1, 0 },
+ { ".{1,2}+", -1, 0 },
+ { ".{1,2}\?", -1, 0 },
+ { ".{1,2", -1, 0 },
+ { ".{2,1}", -1, 0 },
+ { "[", -1, 0 },
+ { "[]", -1, 0 },
+ { "[]]", 0, 0 },
+ { "[[]", 0, 0 },
+ { "[^]", -1, 0 },
+ { "[1-2-3]", -1, 0 },
+ { "[1-22-3]", 0, 0 },
+ { "[+--23]", 0, 0 },
+ { "[+--]", 0, 0 },
+ { "[-1]", 0, 0 },
+ { "[1-]", 0, 0 },
+ { "[[.^.]]", 0, 0 },
+ { "[^]]", 0, 0 },
+ { "[^^]", 0, 0 },
+ { "[]]\?", 0, 0 },
+ { "[[]\?", 0, 0 },
+ { "[[..]]", -1, 0 },
+ { "[[...]]", 0, 0 },
+ { "[[..5.]--]", -1, 0 },
+ { "[[.+.]--]", 0, 0 },
+ { "[[..+.]--]", -1, 0 },
+ { "[[.5.]--]", -1, 0 },
+ { "[1-[=x=]]", -1, 0 },
+ { "[[:alpha:]]", 0, 0 },
+ { "[[:alpha:]", -1, 0 },
+ { "[[:alnum:]]", 0, 0 },
+ { "[[:alnum:]", -1, 0 },
+ { "[[:digit:]]", 0, 0 },
+ { "[[:digit:]", -1, 0 },
+ { "[[:punct:]]", 0, 0 },
+ { "[[:punct:]", -1, 0 },
+ { "[[:graph:]]", 0, 0 },
+ { "[[:graph:]", -1, 0 },
+ { "[[:space:]]", 0, 0 },
+ { "[[:space:]", -1, 0 },
+ { "[[:blank:]]", 0, 0 },
+ { "[[:blank:]", -1, 0 },
+ { "[[:upper:]]", 0, 0 },
+ { "[[:upper:]", -1, 0 },
+ { "[[:cntrl:]]", 0, 0 },
+ { "[[:cntrl:]", -1, 0 },
+ { "[[:print:]]", 0, 0 },
+ { "[[:print:]", -1, 0 },
+ { "[[:xdigit:]]", 0, 0 },
+ { "[[:xdigit:]", -1, 0 },
+ { "[[:unknown:]]", -1, 0 },
+ { "\\[", 0, 0 },
+ { "(a)\\1", 1, 0 },
+ { "(a)\\2", -1, 1 },
+ { "\\0", 0, 0 },
+ { "[[][:g(\?(raph:][:alnu)(\?{m:][:space:]h]<Z3})AAA)S[:space:]{176,}", 0, 0 },
+ { "(()IIIIIIII(III[[[[[[[[[[[[[[[[[[^[[[[[[[[ [^ fX][:ascii:].)N[:a(\?<!lpha:])][:punct:]e*y+)a{-124,223}", 3, 0 },
+ { "(pP\\\\\\(\?<!\\\\\\\\\\\\\\\\\\\\\\lRRRRRRRRRRRRRRRRBBBBBBBBBBBBBBBB))kkkkkkkkkkkkkkkkkkkkk|^", 1, 0 },
+ { "[^[^[{111}(\?=(\?:(\?>/r(\?<(\?=!(\?(\?!<!Q(\?:=0_{Meqipm`(\?((\?{x|N)))))|))+]+]Z)O{,-215}])}))___________________{}", 0, 0 },
+ { "[C{,-218(\?=}E^< ]PP-Ga)t``````````````````````````{138}", 0, 0 },
+ { "[^h(\?<!(\?>Nn(\?#])))", 0, 0 },
+ { "[(\?!(\?<=[^{,37}AAAA(AAAAAAAAAAAAA])", 0, 0 },
+ { "[^((\?(\?:ms(\?<!xims:A{}(\?{*</H(\?=xL $(\?<!,[})))*)qqqqqqqqqqqqqqqqqq)]33333333333333333333333333333{[:graph:]p)-+( oqD]){-10,}-{247}_______________________X-e[:alpha:][:upperword:]_(______wwwwwwwww /c[:upperword:][:alnum:][:alnum:][:pun(\?{ct:])[:blankcntrl:]})*_*", 2, 0 },
+ { "[(\?<!:lowerprin(\?{t:]{}}){113,})[:punct:]IIIIIIIIIIIIIIIIIIIIIIII", 0, 0 },
+ { "PP)", 0, 0 },
+ { "(([^(\?<!((\?>\?=[])p.]}8X[:blankcntrl:],{-119,94})XmF1.{)-)[:upperword:])[:digit:]{zg-q", 2, 0 },
+ { "[^[({(\?#254}))Z[l][x50]=444444444444(4444444444u[:punct:]\?[:punct:(\?!])])", 1, 0 },
+ { "[^[^[^([^((*4[(^((\?<=])Ec)", 0, 0 },
+ { "(0)Y:8biiiiiiiiiiiiiiiiiii", 1, 0 },
+ { "[^w(\?!)P::::::::::::::(\?#::(\?<=:::::::::]\"\"{}[3333333333333333(\?<=33333(\?!)9Xja][:alph(\?<=a:])xB1)(PX8Cf\?4444)qq[:digit:])", 1, 0 },
+ { "([U[^[^].]^m]/306KS7JJJJJJJJ{})", 1, 0 },
+ { "[^[^([^[(\?!(\?>8j`Wg2(\?{,(\?>!#N++++(\?<![++++++)+44444444bA:K(\?<!O3([:digit:]3]}}}}}}}}}}}}}}}}}}}}}}}}LP})S", 0, 0 },
+ { "[({(\?{,(\?(=213}*))})]WWWWWWWWWWWWWWW[:alnum:])", 0, 0 },
+ { "[:(\?<=ascii:])", 0, 0 },
+ { "[U(\?#)(\?<=+HzE])[:punct:]{-207,170}\?s.!", 0, 0 },
+ { "{}z=jU75~n#soD\"&\?UL`X{xxxxxxxxxxxxxxxxxxxx(xxxxxx${-246,27}[:graph:]g\"{_bX)[:alnum:][:punct:]{-79,}-", 1, 0 },
+ { "[^{,-186}@@@@[^(\?{@@(\?>@+(\?>l.]}))*\\BCYX]^W{52,123}(lXislccccccccccccccccc)-*)", 1, 0 },
+ { "(x42+,)7=]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", 1, 0 },
+ { "[^(*[:graph:]q/TH\?B(\?{P)]})uZn[:digit:]+2", 0, 0 },
+ { "([XXXXXXXXXXXXXXXXXXXXX[(:alnum:][:space:]i%[:upperw(\?=o(\?#rd:])) ", 1, 0 },
+ { "(@@@@)", 1, 0 },
+ { "{-18,}[:as[(\?>^[cii:]]{}>+{-46,}{,95}[:punct:]{}99999999999999])-{-134}'sK$wCKjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj", 0, 0 },
+ { "(l[:alpha:(\?!]))", 1, 0 },
+ { "[[^(\?{]|JJ[:alph(a:]X{})B^][:lowerprint:]n-219{-32}{19,105}k4P}){,-144}", 0, 0 },
+ { "[[^]P[:punct:][:alpha:][:xdigit:]syh]|W#JS*(m<2,P-RK)cA@", 1, 0 },
+ { "([^((\?({\?<=)}){[^}^]{}])^P4[:punct:[]$)]", 1, 0 },
+ { "([(\?#:(\?{space:]}):{}{-242,}n)F[:alpha:]3$)d4H3up6qS[:blankcntrl:]B:C{}[:upperword:]r", 1, 0 },
+ { "([(\?:]))[:digit:]mLV.{}", 1, 0 },
+ { "[^PPP-[]{[,50}{128,}]111111111111111]p", 0, 0 },
+ { "[^([^([^([[^[([^[^[[2[[[[[[[[[[[[[^[[[[(\?(\?{:[[[[[[(\?([-[:ascii:]--*)", -1, 0 },
+ { ")!F^DA/ZZZZZZZZZZZZZZZZZZ", 0, 0 },
+ { "[[[[[[[((\?=\?(\?>([[[[[[[^[[[[(\?()[[[K(\?#))])))]7Y[:space:]{,-96}pP)[:ascii:]u{-88}:N{-251}uo", 0, 0 },
+ { "t[:x(\?<=digit:])eYYYYYYYYYYYYYYYYYY{,-220}A", 0, 0 },
+ { "[[({10,}[:graph:]Pdddddd(\?#X)])[:alnum:(]]L-C){,50}[:blankcntrl:]p[:gra(ph:]){66,}", 0, 0 },
+ { "[^[^]*4br]w[:digit(\?::]n99999999999999999)P[:punct:]pP", 0, 0 },
+ { "[:digit:]{67,247}!N{122})VrXe", 0, 0 },
+ { "[:xdigit:]^[:xdigit:]Z[:alnum:]^^^^1[:upperword:(\?=])[:lowerprint:]*JJ-", 0, 0 },
+ { "[[(\?imsximsx:^*e(){,3[6}](V~\?^[:asc(\?!ii:]I.dZ))]$^AAAAAAAAAAAAAAAAAAAAAAAA[:space:]k)]", 1, 0 },
+ { "W{,112}[:lowerp(\?<!rint:]$#GT>R7~t'\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"9,O).", 0, 0 },
+ { "[^{6((\?>\?:4}(\?<=G))f)KKKKKKKKKKKKKKKKKKKKKKKKKKKKKpppppppp(\?=ppppp]{,-101}|[:blankcntrl:]Z{-182})", 0, 0 },
+ { "([:punct:]@^,,,,,,,,,,,,,,,,,,,,,,,,,,0\?:-o8NPIIIIIIIII)pPKKKKKKKKKKKKKKKKKKKK", 1, 0 },
+ { "([^[[^[^]]]])", 1, 0 },
+ { "[([^[(333\"(\?#\\\\[)(\?isx-x:\"Tx]')", 0, 0 },
+ { "[[n>^>T%.zzzzzzzzzzzzzzzzz$&|Fk.1o7^o, ^8{202,-12}$[:alnum:]]G[:upperword:]V[:xdigit:]L|[:upperword:]KKKKKKKKKKKKYX\"\")xJ ~B@[{,-68}/][:upperword:]QI.", 0, 0 },
+ { "[^[]tN^hy3\"d@v T[GE\?^~{124,10(\?{2}]})\?[:upperword:]O", 0, 0 },
+ { "d.``````````````````````````[:up(\?=perword:]RRRRRRRRRRRRRRR)", 0, 0 },
+ { "[Z{{{{{{{{{{{{{(\?={(\?<!{{{{{{{{{(\?>{{J6N:H[tA+mN3Zmf:p\?]\?){-181,82}S4n.b[:lowerpri(\?{nt:]|ggggggggggggggggggggggggggggggg}))4)", 0, 0 },
+ { "[^((/////[^////[^/////////[(^/////]fI{240}{-120}+]R]GA)", 0, 0 },
+ { "[-(\?#.)(\?())[:alpha:](\?={(\?#}r)[:space:]PPW]o)", 0, 0 },
+ { "[:lowerp(\?{rint:]})201{46,}[:a[^scii:]0Q{37,}][:blankcntrl:]1331", 0, 0 },
+ { "[^(\?!(\?#)\\GIwxKKKKKKKKKK'$KKKKKKKK]l)bbb^&\?", 0, 0 },
+ { "[:ascii:]*[:sp(\?<=ace:])", 0, 0 },
+ { "({-66,}Z{})0I{-111,}[:punct(\?():])", 1, 0 },
+ { "[[^(\?!()%%%%%%%%%%%%%(\?:%%%%%%%%%%%%%%%%)t(\?{VX>B#6sUU(\?<!UUUUUU(\?=UUU[^UUUUUUUUUUUU(\?((\?:UPPPPPPPPPPP)PPPPPPPPPPPPPPP]ffffffffffffffffffffffff)^[:space:]wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww{243}9[:lowerprint:]Dv[:graph:])][:blankcntrl:]V%E[:graph:]})[:space:]{-83,}cQZ{}4{-23,135}", 0, 0 },
+ { "({,-76[}]O[:xdi(\?<!git:])\?5))))))))\?d[:lowerprint:]b666666[:graph:]c", 1, 0 },
+ { "{}{-145,}[:(\?(spa)ce:])f", 0, 0 },
+ { "[([^].{116,243}]T*[[^:punct(\?[{[^:(\?<!]]8()])[:alnum:])})]N{}{,243}*[n]][:graph:]", 1, 0 },
+ { "[^w]8888888888888888_________(__________[:ascii:]BdqTE$^0|MNto*i#############[^#################])", 1, 0 },
+ { "[^[[[<[()\?]GGG{,26[}[:alnum:]SSSSS.gggggggg[:graph:]CCCCCCCCCCC{79,}{138,191}][:di(git:]u]@]JJJJJJJJJJJJJJJJJJJJJJJ[:graph:(\?:][:alnum:]])[:alnum:])]", 0, 0 },
+ { "[^(((BBBBBBBBBB(\?>BBBZvvvvvvvvvv(\?m(sximsx:vvv)iiiiiiii)))j>Rs:Sm]0MMMMMMMMMMM|@F)Y]*^#EEEEEEE)*", 0, 0 },
+ { "([^([(U(\?!)<<<<<<<<<<(\?#<<<<(\?<!<<<)(\?=L.{73,})+]n9U}fk%Jn}'b Na<%yyyyyyyyyyyy)){-198,}]))[:space:].pP361U]3s@u_9AU Te/{s`6=IMZdL1|.ySRo", 1, 0 },
+ { "[[((\?<=\?>(\?#){}]{}`){1,82}){-143[,}]^G", 0, 0 },
+ { "[:digit:]W|[:up(\?<!perword:]{,-101}llllllllllllllllll[:upperword:])mmYYYYYYYYYYYYYYYYYYYYYYY*", 0, 0 },
+ { "@NHy)", 0, 0 },
+ { "([^[^]][:alnum:]222[^22222222(\?{2222222222222222][:lo(\?:werprint:][:xdigit:]^[:blankcntrl:]s+N)[:alpha:]-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNWxxxxxxxxxxxxxxxxxxxxxxxxxxD[:space:]U)TTTTTTTTTTfffffffffffzzzzzzzzzzzzzzzzzzzzzzzzz})", 1, 0 },
+ { "[^[^[[^[][^[]pP([^\?[^<=(\?=]){158,})]]]][:digit:]]K22222222222p^dUKJ`\">@]", 1, 0 },
+ { "[^[^[(\?imsximsx::p(\?{unct:][(\?>:ascii:]5w)]{159}\\Q\?@C]4(44444444}[^)|)[:graph:]]C:b)", 1, 0 },
+ { "[^[[(tYri[W<8%1(\?='yt][:lowerprint:[]))1r]][:alnum:][:digit:]{48}{-52,-183}+][:alpha:]r][:upperword:]\?{-105,155}{-55,-87}pPN#############################{63,232}]", 0, 0 },
+ { "[*(\?>L(\?<(\?>=))]&&&&&&&(&&&&&&&&&&&&&&&&&&))[|WIX]{-62,-114}S K=HW60XE<2+W", 1, 0 },
+ { "(00000000000)z\\\\*t{}R{88}[:alnum:]*", 1, 0 },
+ { "(([^(\?=\?gggggg[gLw)]{-250,}[:xdigit:]yZ[:g(raph:]8QNr[:space:][:blankcntrl:]A)][:digit:]D)[:xdigit:])", 2, 0 },
+ { "[^([^,(\?<!]*))]", 0, 0 },
+ { "[^(\?{[:alnum:]]}}}}}}}}}}}}}}}}}}}}}}}){-83}", 0, 0 },
+ { "WWWWWWWW[:alnum(\?<=(\?#:]{,-1})@OSSS)[:digit:]", 0, 0 },
+ { "[^(\?!*]+G)", 0, 0 },
+ { "[LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL>s8.>[^{}$(\?(]]XXXXXXX)XXXXXXXXXXXXXX[:alpha:]Whii\?p[:xdigit:])+", 0, 0 },
+ { "(7777[:blankcntrl:])", 1, 0 },
+ { "[^C[:digit:]]{}YYYY(YYYYYYYYYYYYYYYY)", 1, 0 },
+ { "on|,#tve%F(w-::::::::::::::::::::::::::::*=->)", 1, 0 },
+ { "([((\?=(\?!((\?=')))27(<{})S-vvvvvvvvvv(\?=vvvvvvvvvvvvvvvvv[:punct:][:alnum:]}}}}}}}}}}}}}}}}}}}}}}}PPPPPPPPPPPPPPPPPPPPPPPPPPPPPgggggggggggggggggggggggggg(\?#(\?#gggggg<X){}]{-164,61})>+))uQ)W>[:punct:][:xdigit:][:digit:][:punct:]{}[:digit:][:space:]){,-105}=xiAyf}o[:alpha:]akZSYK+sl{", 1, 0 },
+ { "[^[^]/S:Hq<[:upperword:(\?<=]W[:alnum:]X])1973", 0, 0 },
+ { "[[^[[^([^VVVV(\?!(VVVVVVVVVVVVVVVVVVVVV[VVVVX][^]2))98ppppppppppppppppppppppppppppppp/////////////////////b.]G{-101,}[:[ascii:]P].=~])AAAAAAAAAAAAA2{-153,}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]][:alnum:][:lowerprint:]WN/D!rD]|4444{180}]V_@3lW#lat]", 0, 0 },
+ { "[^[^([^TTTTT(\?:T(\?:T7777{,59}])[:graph:][:ascii(\?<=:]))f]AD{,-43}%%%%%%%%%%%%%%%%)S|[:digit:]FZm<[:blankcntrl:]QT&xj*{-114,}$[:xdigit:]042][:xdig[it:]{-180}027[:alpha:][:ascii:][:lowerprint:][:xdigit:]^|[:alnum:][^Mi]z!suQ{-44,-32}[:digit:]]", 0, 0 },
+ { ")", 0, 0 },
+ { "''''''''''[:a(\?imsxisx:lnum:])P", 0, 0 },
+ { "(([{20(\?<=8}[:alnum:]pP$`(\?#N)wRH[:graph:]aaaaaaaaaaaaaa(\?=aaaaaaaaaaaaaaaaP]a)))[:punct:]-\?)A^", 2, 0 },
+ { "[^(.//[:punct:]&-333333333333333333333333333(\?<!33)LLLLLLLLLLLLLLLLL[:alnum:]$1]~8]|^\"A[:xdigit:]\?[:ascii:]{128,}{,-74}[:graph:]{157}3N){-196,184}D", 0, 0 },
+ { "[^($(\?{(\?<=)[#)]})[:space:]]nWML0D{}", 0, 0 },
+ { ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,[^]x{213,-93}(\?{A7]V{}})", 0, 0 },
+ { "[k(\?=*)+^[f(])r_H6", 0, 0 },
+ { "[(\?#(\?{)]q})", 0, 0 },
+ { "([GLLLLLLLLLL(\?!((\?:LLLLLLLL]))C#T$Y))^|>W90DDDDDDDDDDD[^DDDDDDDDDDDDDDDDDDDD]B[:punct:]c/", 1, 0 },
+ { "[^(\?<!)(\?{b}){,199}A[:space:]+++++++(\?!++++++++{36}Tn])", 0, 0 },
+ { "()[:alpha:]a", 1, 0 },
+ { "[(\?(:blan)kcntrl:])lUUUUUUUUUUUUUUUUUUUUUUU", 0, 0 },
+ { "[^[^(s[[[[[[[[[[[[[[(\?#[[[[[[[)\?`````][:blankcntrl:(\?>]|)p1EmmmmmmmmmmmmmmmmmmmmmmmmmmmmL{-241}666666666666666666666)]^bLDDDDDDDDDDDDD]", 0, 0 },
+ { "[nn(\?<!nnnnn(\?#n8)=````````````````````{41,}]U,cb*%Y[:graph:]).[:alnum:]\\\\\\\\\\gt", 0, 0 },
+ { "()\?5{,-195}lm*Ga[:space:]Y", 1, 0 },
+ { "[(\?:].di)c", 0, 0 },
+ { "([([^([\?{})Za,$S(\?!p(\?{++(\?##V(\?<!Evuil.2(\?<![^[h|[^']C)*\"]5]", 1, 0 },
+ { "[((^24(\?#4[^Kkj{}))]]{232}47)077[:alpha:]zzzzzzzz{}", 0, 0 },
+ { "[^(\?:[^F]o$h)-iV%]", 0, 0 },
+ { "[[^[([((([^(\?{[^((\?=)kaSx(\?imsximsx:w3A[`%+A$I{,62}ns&Y!#ay o9YAo{Y>1((\?>\?#45)Z{,108}{}11111111111111111111111111qqqq)\?][:lowerprint:]mbo#)@", 0, 0 },
+ { "[^iii8(888888(\?<!8^]))s", 0, 0 },
+ { "([[(\?(\?:({^]}[)[(r)])G]{,-87}", 1, 0 },
+ { "([[^{249,}(\?>(\?=)]]T()[:bl(\?!ankcntrl:]=jjjjjjjjjjjjjjjj-)))t{}[:alpha:]-\":i! Gn[A4Ym7<<<<<<<<<<<<<<<<]", 2, 0 },
+ { "^{}{[^,241(\?#}(\?m(\?ixim:sximsx:]t))+oD)", 0, 0 },
+ { "5[(\?#:xdigit:])", 0, 0 },
+ { "[^f{(\?>,22(9}[^[^])6KKKKKKKKKKKKK)]RRRRRRRRfuK99999999C}osnNR]BgCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC[:blankcntrl:]", 0, 0 },
+ { "[^(\?=U){24,}W-{,17(\?:3[^}]q.nQ#PU_|i$$$$$$$$$$$$$$+)[:dig(\?<!it:]){-98}\?[:upperword:]]", -1, 0 },
+ { "[(\?<=[0(\?!72])euE.]{,-159}[:alnum:]t-:l\?)$yyyyyyyyyyyyyyyyyyyyyyyyyyfffffffffffffffffffffffffff", 0, 0 },
+ { "[^[^]q[:asc(\?imsxmsx:ii:]JJJJJJJJJJJJJJJJJJJJ[:graph:]]$)`#DdY^qqqqqqqqqqqqqqqqqqqqqqqqqqqu>4^4ta[:alpha:]", 0, 0 },
+ { "(((b0HN)q))p5<T())`7JJv{'cv'#L8BNz", 4, 0 },
+ { "[pFp2VttBg(\?<=7777777777777|TTTTTTTTTTTTTTT[:space:]Z]^p\"[:blankcntrl:])", 0, 0 },
+ { ")aM@@@@@@@@@@@@@", 0, 0 },
+ { "([^[(\?<![^])", 1, 0 },
+ { "()Z[:ascii:]", 1, 0 },
+ { "(fuPPo)..........................[:xdigit:]{}{,4}*kkkkkkkCx#,_=&~)|.2x", 1, 0 },
+ { "[+(\?<=){}++++++[:alnum:](\?=+]s)[:alnum:]~~~~~~XXXXXXXXXXXXXXX.[:digit:]", 0, 0 },
+ { "[{}[^^(\?(]))CCCCCCCCCCCCCCCCCCCCEg2cF]{}3", 0, 0 },
+ { "([[[^[^[^([[^[^([(\?<=G[[)=(\?!===(\?isximsx:==(\?#==[^=====(\?{==================$T[[^^u_TiC.Fo.02>X)uH]$})354b[:alnum:]]]EVVVVVVVVVVVVVVVVVVVVVVVVVVVVVz[:digi(\?(t:][:upperword:])", 1, 0 },
+ { "([:blankcntrl:]t-){121,}[:ascii:]444444{}[:graph:]E040", 1, 0 },
+ { "[^{134,}]DzQ\?{-30,191})z,\?1Vfq!z}cgv)ERK)1T/=f\?>'", 0, 0 },
+ { "@v)<yN]'l-/KKKKKKKBBBBBBBBBBBBBMa2eLA[:digit(\?<!:])\"\"e|l$&m`_yn[:blankcntrl:]uuuuuuuuuuuuuuuuuuu[:punct:]", 0, 0 },
+ { "[[999999999999999(\?<=(\?:(\?ixmx:(\?>))])Y]|){,10}\?{}", 0, 0 },
+ { "([[[(\?!^]P-AA[AAAAAA[A[^A)r]+B]])", 1, 0 },
+ { "3}|[:ascii:][:punct:]()", 1, 0 },
+ { "()dw", 1, 0 },
+ { "[N]{})))))))))))))))))))))))", 0, 0 },
+ { "[[[^([[(\?()(\?#)++([^\?{+++[^+++++++++++(\?!+(\?=+++++++r9/n]N7{-219}{-91}pP[:punct:]T]mROm+~[:digit:][:digit:])Y:", 0, 0 },
+ { "[^'Pu[(\?<!D&]_a[:alnum:]E<,F%4&[:xdigit:])][:lowerprint:]", 0, 0 },
+ { "tttt(tttttttttt*uKKUUUUU)", 1, 0 },
+ { "([:ascii:]GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG)+kX______________{}GGGGG\?TUH3,{67,77}|[:graph:]C{,-136}{}[:upperword:[]{,-6}&]T84]n={C", 1, 0 },
+ { "[:upperword:]DC[:u(\?<=pperword:]*d`H0\?m>~\?N|z#Ar--SO{,-141}076)G\?{,-110}M+-[:alpha:]", 0, 0 },
+ { "{,-214}{,10(9})", 1, 0 },
+ { "([^xxxxxxxxxxxxxxxxxMMMMMMMMMMMMMMXW])].[:punct:]Q`{-63,63}Uua[:alnum:]\?OQssb#L@@@@@@@@(@@@)[:graph:]", 2, 0 },
+ { "[[^(\?!```[^``````````````(\?<=``(\?>````````M/////(\?!////////////////////[^GD!|#li]~)*.$]))Tq!]C[:lowerprint:]Qk[{}]]JJJJJJJJJJJJJJJJJJJJJJJ{e])c", 0, 0 },
+ { "$[5(7ES])[:xdigit:]%{MRMtYD&aS&g6jp&ghJ@:!I~4%{P\?0vvvvvvvvvvvvvvvvvvvv\\\\\\\\\\\\\\\\\\\\\\\\x54[:lowerprint:][:upperword:]", 0, 0 },
+ { "[((([(\?((\?>[:alnum:][):as(\?<!cii:(\?:]Re))K|)|^){-28,89}l<H.<H:N)QKuuuuuuuuw8E136P)^)[:ascii:]][:xdigit:]-", 0, 0 },
+ { "(pjvA'x]=D\"qUby\\+'R)r\?C22[:ascii:]", 1, 0 },
+ { "[]*b~y C=#P\"6(gD%#-[^FBt{}]${-244}", 0, 0 },
+ { "[:up(\?!pe(\?=rword:])lA-'yb\"Xk|K_V\"/@}:&zUA-)W#{-178,-142}(){-202,}", 1, 0 },
+ { "()1.WldRA-!!!!!!!!!!!!!!!!!", 1, 0 },
+ { "lZZZZZZZZZZZZZZZ(Z[:al(\?:num:])ttttttttttttttttttttttttttttttg.)6$yyy", 1, 0 },
+ { "[([^([^[^(([([^[^(([[$(\?{P(\?=(\?<(\?!=(\?#P[^Y])<GA[:ascii:][(\?#(\?<!:alpha:](B{100,})]}))\?)XU=", 1, 0 },
+ { "[[dVw{6(\?{9,}2222kkkkkkkkkkkkkkkkkkkkkkkkkk|{}*E]]{}SB{35}-w%{eh})<{-178,}", 0, 0 },
+ { "(D(~))", 2, 0 },
+ { "[(:alpha:]{,90}Z|)[:ascii:]Du\?[:grap[^h:]^w+|{}][:ascii:]", 0, 0 },
+ { "[:p(\?<=unct:]kkkkkkkkkkkkkkkkkkkk)", 0, 0 },
+ { "{}[:((\?<!dig((\?#it(\?#:]())p))ZZZZZZZZZZ[:blankcntrl:]){}{-124,})[:ascii:]", 1, 0 },
+ { "[[:graph:]{168}lRRRRRRRRRRRRR(\?#RRRRRRRRRRRRRRRRR)rrrr(\?(rrrrrr)rrrrrrrS[(\?<!@f)6>{,-49})q${98,}J\?]){", 0, 0 },
+ { "([:pu(\?(nc)t:]F{-32,-102}+)\?cpP[:lowerprint:].^)", 1, 0 },
+ { "([{}{210,-238}]1:h)", 1, 0 },
+ { "([]QQQQ[QQQQQQQQQQQQQQQQQQ][:digit:]Z{-20,}Slllllll[:space:]C^(@{-174,-156}fx{cf2c}{-242,}rBBBBBBBBBBBBBBBBBBc[:alpha:]N\?))$[:graph:][:ascii:]P+nnnnnnnnnnnnnnnnnnnnnnn1N$r>>>>>>>>>>>>>>>>>>>>>>>>(>>{,88}{,-234}__________)[:upperword:]R.[:alnum:][:lowerprint:]^}\"", 3, 0 },
+ { "([^(\?=]-))$", 1, 0 },
+ { "([:ascii:]\?,D[:upperword:][:xdigit:]tttttttttttt[^tt(\?<!ttttttttt21f|.(pP[:punct:])])rrrrrrrr)", 1, 0 },
+ { "([{1(\?=16}iiiiiiiiii((\?<=iiiiiiiiiiiiiiiiii|ZZZZZZZZZZZ(\?(\?#{ZZZZZZZ))c}))<<<<<(\?#<<<<<<<<<<<d7CVq8]w{-148,-168}\\Gp){-230,}D3", 1, 0 },
+ { "[^8888(88888888888EX].[:alnum:]){}", 0, 0 },
+ { "([^][^)2]-[:lower(\?=print:]{,79}[:graph:]n)", 1, 0 },
+ { "[bSi\?x_mp(C)0{64}[:space:]hhh(\?(hhh)hhL){5,130}'w\"$l&[:xdigit:][:alpha:]IIIIIIIIIIIIIIIIIIIIIII+-SOOOOOOOOOOOO (\?( ) ]f)ed", 0, 0 },
+ { "[[^[(^(C.Jl[^X&Rb64a+Sd])'m[:alpha:])]]]{134,}", 0, 0 },
+ { "()L", 1, 0 },
+ { "[[(({224,(\?#88})@======(\?!=========(\?{=)PPP)i^@p(\?([:punct:]})^^[^^^^^^^^^^^^^^^^^^^^^@)m]|{CS{,-3}168)-[:xdigit:][:upperword:]hnD=Bns)z)AAAAAAAAAAAAAAAAAAAAAAA[^A{}ccccccccccc)SZ]Q-p.sD]]+P", 0, 0 },
+ { "[[^[^]{135,}66666666666666666666[6(666i2M9.!uhmT\?JMm.*(\?!+)[:alpha:]eeeeeeeeeeeeeeeeeeeeeeeeeee]]])ZZ[:blankcntrl:][:ascii:]", 0, 0 },
+ { "(13[3Ux>{,10}[(\?<=:xdigit:]))PL9{-89,-181}F'''''''''", 1, 0 },
+ { "[^.|(\?{af]})^$XE!$", 0, 0 },
+ { "(WWWWWWWWWWWWWWWWWWWWWWWWWWWW#J)", 1, 0 },
+ { "({}}M7we-216)L[:digit:][:upperword:]", 1, 0 },
+ { "([:aln[^u(\?=m:]))].z", 1, 0 },
+ { "([:alpha:]{(92})%6{41,136})Vij@[:alnum:][:lowerprint:]", 2, 0 },
+ { "[[[++(\?{+++{}})n{{137,}{51,-177}Z[]M*[:ascii:]{(-29,-47}2)$e^{,-195}{-156,}^]{}{-225,69}A]{-222,}{,20}m[:blankcntrl:]", 1, 0 },
+ { ")l)[:alnum:][:graph:]g8TTTTTTTTTTTTTTTTLLLLLLLLLLLLLLLLL", 0, 0 },
+ { "[([(\?<=.(\?{)/})mmmmmmmm(\?(mmmmm]{-154,-176}*S)I]", 0, 0 },
+ { "[(([{(\?(\?<!im(\?imsix:sim(sx:,141}])D)l{,42}ttttt[(\?::punct:])){-162,-141}{-26,})dU@@@@@@@@@@@@@@@ S)\\A\?w|VVVVVVVVV)X.kN{,21}{-208,-52}>[:lowerprint:][:ascii:]e-]]]]]]]]]]]]]]]]]]]]]", 0, 0 },
+ { "[^({}(){(66(\?=,}[^]'''''QQQQQQQQQ).P#>^){86,168}Z[(\?<!:lowerprint:]{-166,-70}<k", 0, 0 },
+ { "APP[:alpha:][:alnum:]nd[:upperword:(\?(]^xxxxxxxxxxxxxxxxxxx)xxxxxxxxx{-70}[:punct:]l)U-", 0, 0 },
+ { "[^(.\"od~(6({[^(\?<!228}\?)\?)######(\?:#########z )c(\?<!aQ`(\?{UKSwu[})][^-17]{11,}}][:ascii:]))^RiH+WyspP[qi&)=p6])[:space:]{-221,}]6p", 0, 0 },
+ { "{-78}()[:xdigit:]{155}{,-92}", 1, 0 },
+ { "[(\?>Q{,147}_____________(\?!______uuuuuuuuuuuuuTr]){74,179}{}){,103}{-209,16}*RRRRRRRRRRRRRRRRw{,87}9{144}[:ascii:]'<Ab", 0, 0 },
+ { "([666c] {-171}yc,8-k_)EEEEEEEEEEEEEEEEEEEEE<", 1, 0 },
+ { "[^(\?>(\?<!)2(\?imim:)6HwN)^|fc!(\?(d]75))065)G", 0, 0 },
+ { "[[^xDB[:alnum:][:xdigit:]][:digit:]jW]([:alpha:])", 1, 0 },
+ { "[ds~T+[x55[:digit:]X[JJJJJJJ.[(\?::upperword:]){,-14}][:xdigit:]bbbbbbbbbbb", 0, 0 },
+ { "[qqqqq(\?<=qqqq(\?(qqq)^G[):ascii:]])W", 0, 0 },
+ { "[:space:]JJJJJJ[:alph(\?<!a:]|[:ascii:(\?(])[:x)digit:]- XSstG[:g(\?>raph:])^)Ny6RF_ndoU9@*rxW{4,41}4{}", 0, 0 },
+ { "[:punct:]{162,}j[:aln(um:].....................[^...]\?>z[:l[owerprint:]){55,222}]", 0, 0 },
+ { "(>vWa)OXcccccccccccccccccccccccc[:alpha:]C{,-10}81|m1D^T)[:lowerprint:]''''[:alpha:]l", 1, 0 },
+ { "(XZcgM/UI-/mZq-222){-85,-196}[:alpha:]{114}rrrrrrrrrrrrrrrrrrrrrrrr{,157}ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZLkD-&&&&&&&&&&&&&&&-][:alnum:]{}{,111}[:digit:]", 1, 0 },
+ { "[^(\?:]MMMMMMMMMMMMMMMMMMMMMMMMMMM)cK[KKKKKKKKKKKKKKKKKKKKKKKK]P{146}", 0, 0 },
+ { "([^[^wqesa)n\?L(\?<=FH+G[^rCGmfD]w)m1D\"%}]])", 1, 0 },
+ { "[((\?:[^.HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH|S)xd)*[:space:](])[:xdigit:]ngr'G#/B]-----------------------------", 0, 0 },
+ { ")[:lowerprint(\?<=(:]l))G p", 0, 0 },
+ { "[^[^(\?<(\?<(=(\?imsximx:![(((\?<!\?(^))\?]^)[:xdigit:][:graph:]{-104,})Gf+GD*qc)c]f))])", 0, 0 },
+ { "[^([\?())P[:alnum:]w]{-186,-139}-[:space:]RN3w[Fmvpl[:space:][:digit:]&&&&&&&&&&&&}(\?#}}}}}}}}}}}}}}}}}}}])z", 0, 0 },
+ { "([[^^*C[()f][(\?=:punct([\?#:]o)]V)]%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[^x{1f948})]]", 1, 0 },
+ { "[(:xdigit:])zE", 0, 0 },
+ { "[:pu(\?(nc)t:])(a*){-51}", 1, 0 },
+ { "[^(.NKKKKKKKKKKKKKKKKKKKKKKKK-[:upperword:][:space:]`MPi>", -1, 0 },
+ { "Nvvv[vv.][:alnu[^m:]+|Crrrrrrrrrrrrrrrrrrrrr[:xdigit:]j1n)v#]", 0, 0 },
+ { "[^#}[(\?>:alnum:]).QQQQ[^QQQQQQ!!![!!!!!!!-s.n]se]{-238,}Tf]p4721", 0, 0 },
+ { "([((\?#\?<=)+)Hr:-H]z[:graph:].{}oooooo(ooooooooo][:punct:]k<gXG@@@@@@@@@@@@@@@@@@@{,-176}){}L`)$", 2, 0 },
+ { "({,249}{-73,}Z&&&&&&&&Ds35MB<v)qqqqqqqqqqqqqqqqqqqqqqqqq", 1, 0 },
+ { "[^.N][:blankcntrl:]))))))))))))))))))))))))))))))", 0, 0 },
+ { "(()*){198,}", 2, 0 },
+ { "{-237,}220{}[:ascii:]```````(`````````````\?{-115,185}){,-18}[:punct:]'|Kk", 1, 0 },
+ { "[(\?()])", 0, 0 },
+ { "([(\?#[:alnum:]CQ)}}}}}}}}(\?>}}}}}}}(}}}}}\?310[|))xA5r][[^:ascii:]^{,-156}{])CCCCCCCCCCC-145]FzwOD_u\?", 1, 0 },
+ { "[^[^[]{-163}{(-203}[(\?!:upperword:]PPGjZ[:xdi(\?=git(\?#:]{-73}s)qqqq(qqqqqqqqqqqqqqqqqq{173,210}[:xdigit:(\?<(\?>=]WW[^WWWWWWW\?*O)))Q){}08)[(\?(\?<=#:blankcntrl:]{90,}]U)])L)ooooooooooooooooooooooooooox--^c[:ascii:]])s)", 2, 0 },
+ { "[(\?!:punc(\?imximx:t[^:]4F<}!)]'M-)tKKKa4904", 0, 0 },
+ { "[^^{}\\(\?<!\\\\\\\\\\\\\\\\\\(\?#\\\\\\\\[:punct:](\?>)T000000000(\?(000)00000))+])", 0, 0 },
+ { "L[:p(\?#unct:])", 0, 0 },
+ { "[:upperw(\?<!ord:])", 0, 0 },
+ { "@$\"\"\"\"\"\"\"[\"\"\"\"\"\"\"\"\"\"[^(\"\"\"\"\"(\"\"][]))*U{223,138}*o```````````````(\?=[```````````````]{238}mmmPPPPPPPPPPPPPPP&&&&&&&&&&&&&&&&&&)sF$[:digit:[]]", 0, 0 },
+ { "[^#Txx[xxxlPB(\?><[^U/)]]{}X3333333333(3333333f*])", 1, 0 },
+ { "<<<<<<<<<<<<<<<[^<<<<<<<<<.][(\?#:ascii:])[:xdigit:]|^", 0, 0 },
+ { "([:punct:]{}){-167,}{-59,}Pd\"", 1, 0 },
+ { "[((\?#{,214})t$)VVV[:xdigit:]{104(\?<=}D][:graph:])|H){1,}{-176,}", 0, 0 },
+ { "[[([[^N,,,,,(\?=,,(\?#(\?:,,,,,,,,,,,[^,,,,,,,,,,]<,~4::_.A]){-52,}-[:alnum:]Pnnnnnnnnnnnnnnnnnn)d", 0, 0 },
+ { "{-18(3,})uT{4,}", 1, 0 },
+ { "[^[^[(p+c(\?<!b$))(\?:EU(\?(.][^{}]3[:xdigi[^t):][:punct(\?>:])[])][:s[^pace:]][:alnum:][:alpha:]]kw06E", 0, 0 },
+ { "[^^^^^^JJJJJJJJ(JJ(\?=JJ(.6[:space:]H]{231,}A^eqqq)[:ascii:(\?>(])[(\?>:spa(\?:ce:]xxxxxxxxx)@_t-))138GNNNNNNNNNNNNNNNNNNNNNNNNNN[:digit:]no!`#E\?&[:lowerprint:].)[:graph:]{86,}[:digit:][:alnum:]", 0, 0 },
+ { "[:g(\?<=raph:]a{114,146}(){}0Y[:bl(ankcntrl:])D)\?", 1, 0 },
+ { "[^[^]*H{-192,96}S|]G)6B-kLB", 0, 0 },
+ { "[[^[^][/NS8`um(\?{82&{((\?{\?<!-[110,-88}]m)})kkkkkkkk$$$$$$$$$$$$[^$$$$$@n%BuK@X!P)y0v!^]YY[YYY[YYYYYYYYYYYYYYYYYY///////{}{{{{{{{{{{{{{oiiii})]8{-2[53}w{82,}]{,245}]{-134}]fffffffffffffffffff]\"I>DW>9tN%{113}{unE", 0, 0 },
+ { "[:(\?(alpha:]`))Y2sCqWQ104", 0, 0 },
+ { "(([^()Wcccccccc(\?{cccccccccccccccccc(\?<!c(ccccc[:space:]$)(\?>)FZ{}{}`|||||||||||||*````````````````````````````'=dLQmx/Y.A7j'o}jn{}:})][:punct:]$|,-)!&Y:Ys#ykL7JJJJJJJJJJJJJJJJJJJJJJJJJ8yex>#mv[:punct:](x@)$[:uppe(\?<!rword:])_)", 3, 0 },
+ { "[[(^HHHHHHHHHHHH(\?imsximx:HH(HHHHHH(\?{HH[HH])qjR>9))i})]a!lBW3p{A=or)ShE%[:punct:]{}]5r", 0, 0 },
+ { "[:pu[nc[^t:]]]}}}}}}}[}}}}}}}(\?#}])@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDD\?]xA2\?", 0, 0 },
+ { "(.[:alpha:]xB7[:alnu(\?{m:]})RRRRRRRRRRRRRRRRRRRRRRRRRRRL)[:space:]G\?", 1, 0 },
+ { "[:blan(\?<!(\?=kcntrl:]){71,})!ooooooooooooN", 0, 0 },
+ { "()e$$$$$$$$$$$$$$$$$$$$iiiiiiii", 1, 0 },
+ { "(b[:ascii:]67777777777777777777777777)({-106}kkk^F-------------------------------{13}A)f00000000sBAddddd{-66}kd!D'", 2, 0 },
+ { "(Q ^])[^lf][:space:][:lowerprint:]\?", 1, 0 },
+ { "[[^]\\S{152}W![:digit:][[^:space:(\?(]=pEhwY][:alnum:][:digit):][:graph:]])QQIC9h-oowf[:xdigit:]{-52}{,190}1111111111111111111fX{-189,226}W", 0, 0 },
+ { "[^(\?!(\?<=)]).h[:as(\?>cii:])[:alnum:]$$$$$[:space:]3$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1", 0, 0 },
+ { "[[$zQ================(\?<!=(\?>=========(\?====D[^))|i{}\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?)][:s(pace:]]))]", 0, 0 },
+ { "[^{,-[15(\?#6}]Vwjjjjjjjj[jjjjjjjjjjjjjjjjjjS9999)]q]rWWWWWWWWWWWWWWWW[:punct:]@@@@@@@@@@@@@@@@@@@@@@@@gO[:blankcntrl:]>L[:ascii:]:::::::::::::::::::x11uuuuuuuuuuuuuuuuuuuuuuuuuuuuu{-124,114}[:graph:]C#{tcg[:xdigit:]gZZZZ[:lowerprint:]nA(_{{{{{{{{{{{{{{{{{{{{SS)\\D[:alpha:]", 1, 0 },
+ { "[^(\?())]!T\?[:asc[^ii:]E:4},,]I[^b(\?:n4(njj~+{\?'k{7}{189,-194}{ig.[[[[[[(\?#[[[_bs6,JD`1(\?<!WBo]F+{d*VO22z2K1][:xdigit:]))Suuuuuuuuuuu[^u{,117}\?YYYYYYYYYYYYYYYYYYYYYYYYB^]|q]:eY1GGGGGGGGGGGGGGGGGGGGGGGGGGGGe\?)bU[:punct:]", 0, 0 },
+ { "[\?UA(\?:]\?)[:xdigit:]A^mmmmmmmmmmmmmm>>>>>>>>>>>>>>>>>>>>>>>>>>>>[^>>>(\?(>)){,-165}]", 0, 0 },
+ { "([^[][^n(\?{[[p]#})|][^]L|66666666666[:graph:]][:graph:]2[:xdigit:][:space:]9b})[:digit(\?imsximsx::]+PZ):{}|E)[:xdigit[^:]|>]^[:alpha:]::::::::[:ascii:]````[:ascii:]:", 1, 0 },
+ { "[:lowerprint(\?<!:])", 0, 0 },
+ { "[[^[]{-47}[:lowerprint:][:punct:]L[(\?::g(raph:]lY[:alnum:])qWYU)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}[c%$dp5[:alnum:]DDDDDDDD^^%&{,-94}E]{-8,175}[:alpha:]-.^[:digi(t:]CCCC(CCCCCCCCC]).ax72)", 1, 0 },
+ { "[[^($$$$$$$$$$$$$$$$$$[^$I((\?{\?(u)\"YuK ZpOHq[!(\?>t|LQT(|)L[(:ascii:])", 0, 0 },
+ { "[^[^([:graph:](QpPdyDQ`[:alpha:](.X[:digit:]wwwwwwwwwwwwww(\?imxims:wwwwwwwe(\?<!z)ONNN(\?#)[^])[:space:](KKKKKKKKK{113,}327[:xdigit:]k)]CeeeeeeeeeeeeeeeeeMMMMMMMMMMMMMMMMM)[:lowerprint:]]HHHHHHHHHHHHHHHHHHH]]]]]]]]]]]]]", 1, 0 },
+ { "[Q(r(\?=)v]dm[:alnum:][:b(\?{lankcntrl:][:xdigit(\?=:])})P[:graph:]bd/Rx){50}{-150,-172}", 0, 0 },
+ { "[(\?(im(\?:sxims:))9]))L", 0, 0 },
+ { "[[^[(\?{^Z][^0[:alpha:]]\\XB*{-151}t})][:alnum:]]", 0, 0 },
+ { "[([(D\?/////////////////////.'yvYysU&5AU-]kV)*){,123}z]", 0, 0 },
+ { "[:alnu(\?{m:][:a(\?=lpha:][:alpha:])n}))7[:ascii:][:xdigit:][:punct:]-", 0, 0 },
+ { "[^[:graph:]IIIIIIIIIIIIIIIIIIIIIII][:sp(\?<!ace:])", 0, 0 },
+ { "[[[(\?=[[[cDD(\?<!D(\?:DDDDDDDDDDDD(\?<=DDD(DDDDDD(\?:DDDDDDD(\?<=D(\?()])rvp{243,}D$<[:space:]([:lowerpr)int:])])Ea{}U[:upperword:][:xdigit(\?#:]or}Z+34gD{/P NJ", 1, 0 },
+ { "[^(,H>)*d2K0DNX5)T(].)[:digit:].", 0, 0 },
+ { "([:punct:(\?#])})JJJJJJJJ[:xdigit:]PPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU.......................0hSk{,89}[:xdigit:].[:xdigit:]Z", 1, 0 },
+ { "(LGTTTTTTTTTTTTTTTTTTTTTTTTTT[:alpha:]){-106,113}[:punct:]d|[:digit:]kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\?wP", 1, 0 },
+ { "([^[^<N_-k\?{(\?#18}]i]::::::::::::::::::::::::::)1+LLLLn{}/){-198}", 1, 0 },
+ { "([[^(AAAAAAAAAA(\?(AAAAA)AAAAf).LzHHHHHHHHHHHHHHHHHHHHH(\?#HHHHH|)[ZEEEEE(\?#EEEEEEEEE(\?<!EEEEEEEEsG)q[:punct:]{}][:upperword:]D)[:space:][:digit:]+e[:ascii:]].i|JJJJJJJJ+n][:xdigit:]Se)P[:lowerprint:]_______________________________.[:punct:]pP{-172,86}iiiiiiiiiiiiiiiiiiiiiiiii){,-178}", 1, 0 },
+ { "([\?=[[^,BDRRPZ{129}*D-[:punct:]]])([:upperword:]ud)\?][:punct:]A", -1, 0 },
+ { "(([(\?#((\?{\?=^])c-)C[:lowerprint:]xvkR}k\")ccccccccccccccccccccNNNNNNN[:alp[ha:]{,93}vhlX:|A]2})nSw)]N.", 2, 0 },
+ { "()g/qzyiV(x3d|A0wllllll){162}[:space:]", 2, 0 },
+ { "qqqqqqqqqqqqqqqqqqqqvvvvvvvvvvvv8[:x(\?imsxmsx:digit:][:alpha:]''''''''''''''''''''''''''')", 0, 0 },
+ { "({,226}nf^W=vs$xK^=A=M#b,)V", 1, 0 },
+ { "(_T 2BC9N'cccccccccc-87EF#&^eQfDDDn._,m&c`tjAwR #~A)[:(\?imsimx:alpha:])/yHYL6|{-40,47}", 1, 0 },
+ { "[[^]{-8(4,138})z[:xdigit:]{180,}]", 1, 0 },
+ { "[([^T____________________(\?:__C(\?<=]-)])+[:ascii:])r[:graph:].----------", 0, 0 },
+ { "[f{}LLLL(LLp((((\?<!((((((((((((((({,56}]BR`{,52}){-22,}\?[:space:]h>Sow", 0, 0 },
+ { "{-179}^[:alpha:(\?!].a'5wacA3\\\\\\\\AAAAAAAA)~^]wC", 0, 0 },
+ { ">[:digit:]{,-212}+(`)LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL[:ascii:][:digit:][:space:]", 1, 0 },
+ { "[[^[[^RBW{,255(}(\?(\?>=(W)_]uu][:blankcntrl:])O)]]", 0, 0 },
+ { "(C_______________________________)2", 1, 0 },
+ { "([/ntf_a3].)", 1, 0 },
+ { "[:space:]+[(:upperword:],c7[:asci(\?<=i:]ggggggggggg)[:ascii:]/1$$$$$$$$$$$$$$$$$$$$$$$$$$)", 0, 0 },
+ { "Xq{109}~EEEEEEEE[:upper[^word:]lgB:X(h[:alpha:]B[:space:]].)IkaH@3}}H'yK~\?[:upperw(\?#ord:(\?:]){=================[:blankcntrl:])", 1, 0 },
+ { "(([[^]]$3Xr^$%%%%%%%%%%%%%%%%%%%%%================U[:ascii:])X).FFFFFFFFFFgO[:punct:]oooooooooooooooooooBC[:blankcntrl:]mmmmmmmmmmmmmmmmmmmm[:lowerprint:]rBM~<HAc#Sb&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Cy", 2, 0 },
+ { "([([([^(\?:)D]-{M#H >rERRRRRRR[^RRRRR(\?>RRRRR])[(\?=^)X]{207,}U])))Z[:blankcntrl:]]yyyyyyyyyyyyyyyy\?", 1, 0 },
+ { "[Q(\?{*[^(\?(\?!!])[:graph:]]})[:alnum:]iE)dGGGGGGG[^GGGGGGGGGG[:xdigit:]w]", 0, 0 },
+ { "[^Z(\?!6(\?(\?><=)[:graph:])]BBBBBBBBBBBBBBBB^)", 0, 0 },
+ { "[[^([^[^][[[[[[[(\?({[[(\?(\?imsxmsx(\?imsi[ms:::[[[[[[[[[}))]$)){12,})|:::::::::::::::::::[:lowerprint:]{}{-96,-147}){13,}`[:digit:]]\"^Ca%%%%%%%%%%%%%%%%%%%%%%%%%%UUUUUUUUUUUUUUUUUU]]9", 0, 0 },
+ { "[^(\?(\?(\?#!<=))JLBS\"zi)'''''''''''['''''''''''''piiiiiiiiiiiii(\?<=iiii]])ZZZZZZZZZZZZZZZZZZ[:space:]", 0, 0 },
+ { "({})[:punct:]", 1, 0 },
+ { "E9[:blankc(\?{ntrl:]})N", 0, 0 },
+ { "[:alph(\?#a:]){198,}sq\?X0B7", 0, 0 },
+ { "[^\\\\\\\\(\\\\\\[\\\\\\\\\\\\[(\?<(\?isximsx:={11(\?(9,}\?0])]]))\?FN3M\?{-128,}Z444444)444fbLiVN8)", 0, 0 },
+ { "[[^[^([[[[[[[[[(\?>[[[[[[[[[[[[[[[[[[[[[{53(\?<=,-175(\?>}ggggggggggggggggg%))[:alnum:])[:punct:]kkkkkkkkkkkkkkkkkkkkkkkkk)+Soooooooooooooooooooooooooooooooo](WR+--)x36+llllllllllll{,35}]Fqb^=F]KKKKKKaaaaa{,131}", 1, 0 },
+ { "(g\"Ssqw<&{Cl{82,}Mdf|9cIlmCW{}[:digit:]4C{}[:alnum:]PP)", 1, 0 },
+ { "OOOOOOOU[*evVIIIIIIIIIIIIIIIII(\?#(\?#IIII)]PP[:xdigit:]2222222222222222[:xdigit:]Kx)p[:digit:]", 0, 0 },
+ { "([[{248,16(\?=5(\?#}][:alpha:])|[:p(\?!unct:(\?(]", 1, 0 },
+ { "[pP((\?=S)(\?#)]$[:aln(\?(um:)]2\?)$GGGGGGGGGGGGGGGGG({-U:c){-61,}[:ascii:]{-202}G", 1, 0 },
+ { "()$D[:alnum:]", 1, 0 },
+ { "[(\?#^]){}[:ascii:]", 0, 0 },
+ { "[uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu]FFFFFFFFFFFFFFFFFFFFFF&2e\?)%oP'mc@z2b}n{<b4_Laz^0LLLLLLLLLLLLLLLLLLLLLLL,,,d", 0, 0 },
+ { "{}(^________________''|$)RRRRRRRRRRRRRRRRRRR", 1, 0 },
+ { "(H)####################bbbbbbbbbbbbbbbbVSSSSSSSSSSS|tdU\"goeAbPP{-248,81}", 1, 0 },
+ { "[^[(\?ims(\?>xisx:)UHpP*n{}]{}fx14<7OEpE>n2150)8888888888888888]^GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGS", 0, 0 },
+ { "(d)+", 1, 0 },
+ { "[^.(\?(>)(\?=e)])al[:space:]x", 0, 0 },
+ { "[^256c(\?!]){-19,}", 0, 0 },
+ { "Q)", 0, 0 },
+ { "[^s\?\?(\?{\?\?\?(\?#\?(\?<!\?\?\?\?\?\?\?\?\?\?\?(\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?{}]F\?j(jjjjjjjjjjjjjjjjjjn)kTI1f[{1|(\?<=^[^+[:digit:]{}^s^))})))T]{-17}{CCCCCCCCCCa{-21,}{,-146}^uZQB]YuLu-|tUGRMz^^", 1, 0 },
+ { "([^.{}.EE[EEEEEEEE(\?<=EEEEEEEEEEEEEEEU]]-@s))$", 1, 0 },
+ { "[^([((\?#[#])|a)])[cccccccccccccccc][:digit:]LLLLLLL[:alnum:]}[P%vzl{}^]&", 0, 0 },
+ { "({}[:space:]E)101+A{-35,11}", 1, 0 },
+ { "(va:7)u[:alpha:]", 1, 0 },
+ { "([^[[rrrrrrrrrr(\?:rrrrrrrrrr(\?<!rrrrrrrrry|D'*AH@a{}\?[:space:][:alpha:]^]$ {-225}[(\?(:as)(\?(>cii:])){-107,-139}6/{^[:upperw(\?imsxmsx:ord:]{,-47} ]wuH#nAn)GGGGGGGGGGGGGGGGGr[)]T{91}lJ))[:lowerprint:][:xdigit:][:lowerprint:])]*", 1, 0 },
+ { "()[:space:]~!$[:alnum:]JJJJ[:ascii:]", 1, 0 },
+ { "[^(\?<=)-]()k", 1, 0 },
+ { "(()W){,8}ea", 2, 0 },
+ { "({,-56}5G&&&&rrrrrrrrrrrrrrrrrrrrrrrrrrk.8) hWJ,TM)0Yd-", 1, 0 },
+ { "(Z-fddddddddddddddddddddddd)-{9}", 1, 0 },
+ { "[^<[(\?!:asc(\?:i(\?<!i:])F])[:alp(ha:]b))-}Wwx8B", 0, 0 },
+ { "[^[^[^([(\?{}(\?=)(\?())-CCCCCCCCCCC(\?=CCCCCCCC(CCCCC(\?:CCCCCCCC(\?{l[(\?!:space:]})[:upperwor(\?:d:]{-27}[:al[^pha:][:xdigit:]^f", 0, 0 },
+ { "[[^]G@>2!+[:punct:(\?<!]{,189}6ZF[:blankcntrl:][:digit:]{,214}){-115,-14}l[:upperword:]{101,}Z[:ascii:]Ld&02|c]<0~<bc", 0, 0 },
+ { "(Q)[:digit:]x", 1, 0 },
+ { "hT[[:alnum:]\?]O[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOxFF%^(\?(_LN 8uXQT\"*/L)+l)>qQ[^]e[:ascii:]PP()[:digit:]NQ8%6d=&2I{-62,-142}w]].e{}*", 1, 0 },
+ { "{,-219}xxxtEEEEEEEEEEEEEEEE[:pun(\?(ct:])qqq)nnnnnnnnnnnnnnnnnnnnnnnnnnn", 0, 0 },
+ { "[:di(\?>git:])W4", 0, 0 },
+ { "([^y])Fkvto$", 1, 0 },
+ { "[^($$$$$$(\?!$$$$$(\?{$$$$$$(\?<=$$$$$$$$$$$+===)[:alnum:]MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM)Z]{}^[:blankcntrl:]--xxxxxxxxxxxxxxx[^xxxxxxx)\?tVG\?{232,81}{121,}xn{,-226}})tttttttttttttttttttttttmu(\?<!&&&&&&&&&&&&&&&&&&&&&&0b]z)$87{,-192}{}{-242,}", 0, 0 },
+ { "l[:dig(\?(it:]|s*)aA[:digit(\?<=:].^.))x[:digit:]", 0, 0 },
+ { "[:grap[^(\?#h:]').]Z", 0, 0 },
+ { "[:gra[^ph:]t[:digit:]222222222222(22222222222222222H qM]pWZr[:ascii:]-hRb_.)Q{-228,-204}{}", 1, 0 },
+ { "AAAAAAAAAAAAAAA(AA)YeX", 1, 0 },
+ { "(!dqqqF*^){(,-79}s!!!!!!!!!!!!)", 2, 0 },
+ { "[^(\?msxm(\?#sx:]|)ZHYup)j{95}0L:vXB#')d'DX\?m.T034\\\\\\\\\\\\\\\\\\\\\\y5rV{}S", 0, 0 },
+ { "(W*O+yl([\?!P(\?:)I]${}{-195,-14}[:upperword:]{}[:xdi[^git:][:space:]X[:grap[^h:]~]zzzzzzzzzzzzzzzzzzzzzzzL)+)Y b.-=jf{-216,}${/!}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|]", 2, 0 },
+ { "[^\\\\\\\\\\(\?<=\\\\\\\\\\\\\\\\m]{-48,234}[:alpha:]s)", 0, 0 },
+ { "[(\?{U}(\?<!)])LLLLLLLLLLLLLLsssssssssssssssssssssssssss[:ascii:][:blankcntrl:]---------b", 0, 0 },
+ { "[^[^[(\?#)(\?imsxims[x:)<<<<[<<<<<<<<<<(\?<!<<<<<<<([^\?(<<<<<<<<<<z(\?(zu(\?<=~83}aZpIE)[:alnum:](\?imsximsx:(\?!jrE6(\?<!\?V(SzDU)000[000000000((\?=\?)=0])L|lOYuWXk", 0, 0 },
+ { "$o[:dig(it:]nnnnnnnnnnnnnnn{-94}|G)[:alpha(\?!:] {,-108}D=\?>[:digit:]S[:space:]t", 0, 0 },
+ { "()n", 1, 0 },
+ { "[:upp(erword:]$)<}.vZM<lEY5Y*", 0, 0 },
+ { "[^([^\?>)rCD&{5(\?msxisx:7,}qqqqqqqqqqqqqqqqqq{31,}@w#W:(@(\?:zp$YYYYA[:alpha:]{1}A)*dZJ\"5OG|\?(\?#a])]|){-150}[:xdigit:]", 0, 0 },
+ { "[($)gwo{`\"]{-160,}\\\\\\\\\\\\\\\\\\\\\\\\\\66666666666666888888888888", -1, 1 },
+ { "((}DA+Rc000000000000000000)%vvvvvvvvvvvvvvvvvvvvv%C&emZ*[:alnum:]#m/D[:graph:][:blank[^cntrl:]E{,168})kkkkkkkkkk000000000000000]", 2, 0 },
+ { "[^[u*(\?#x01234)oxGGGGG(\?([GGGG)GGGGGGGGG]^U)!!CCCCBM`4QB^XEN]{,-60}[:upperword:]G]", 0, 0 },
+ { "(%)~t{S,K^MI3PMo)=b", 1, 0 },
+ { "[[[^]{}eU([:xdigit:]&&&&&&&&&&&&&&&&&)\"W|43[:alpha:][:graph:]J8b[:blankcntrl:]gggggQ{,183}{,-254}\?[:ascii(:]{,134}", 1, 0 },
+ { "[[([^[^([^(\?=)1RRRRRRRRRRRRRRRRRRRRRR(\?:(\?(\?(\?!=#RRRRR(\?=RRRR(\?<[^!Ru)])]o[:[graph:[^]{,7})[:digit(\?::]{-215,}e[:space:]]", 0, 0 },
+ { "({{{{{{{{{{{{{{{{{{KKKKKKKKKKKKKKKKKKKKKKKKKKKKBBBBBBBBBBBB)[:space:]0[:alnum:]HcctQA", 1, 0 },
+ { "[^(pP7(HsN[^g{186,-87}\?\?]EQ%u:-Y)+>>>>>>>>>>>>>>>>>>>>>pP][:alpha:]", 0, 0 },
+ { "[(.{141}h|)((\?:\?=@Q} ghcC{+*(R)D+][:lo(\?#werprint:]zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz))", 0, 0 },
+ { "[^({}S)PPFl(])-216", 0, 0 },
+ { "[([[^(((([(\?#^[^[^\?4[(:[dig[^it(\?(:]{122,})y\?", 0, 0 },
+ { "[[2${188}u{1(4(\?(1,1(\?{98}e{&tbaoI]q)[:punct:])d}))Nqffffffffffffffffffffffffffff[:ascii:]+]", 0, 0 },
+ { "()K-", 1, 0 },
+ { "[[{2(2((\?(\?!()2})])[:alpha:]fVVVVVVVVV{-47}):::::::::::)\?vwyyyyyyyyyyyyyyyyyyyyyyyyy-]{}", 0, 0 },
+ { "ivcs)g", 0, 0 },
+ { "(hhhh[^hhhh(\?{h\?]})%%%%%%%%%%%%%%%)\"+38mbY:s9{/d# zaNnbQb)b:*zpKI{-26,-189}", 1, 0 },
+ { "S*(#)[:graph:]lllllllll&G)t", 1, 0 },
+ { "([^[(([\?=\?<!)]]___{-63,})]nt", 1, 0 },
+ { "[:b(lankcntrl:][:alpha:]*[:pu[^[nct:][:alpha:]A]$aaaaaaaaaaaa*)A[:digit:]U][:alnum:]", 0, 0 },
+ { "[^f[^p000{68(\?isxmx:,}(\?!vvvvvv)$)]PP#*{(})[:punct:]&&&&&&&&&&&&&[:punct:]\?][:blankcntrl:]", 1, 0 },
+ { "[^(((\?(\?(()))GGGGGGGGG{(\?!($)))((\?!)V^{228,145}))]{-229}Qjjjjj[:punct:]R)", 0, 0 },
+ { "[(Q[^((\?{(\?:]~z)})gE(.<){}|)Kuuuuu$*222222222222222222222D]", -1, 0 },
+ { "([^`(\?<=`````[^`````````M]\?)=L74A[:upperword:]]P", 1, 0 },
+ { "(({}[:space:]qv-T){,-192}{-45}{65}9\?X).d", 2, 0 },
+ { "_[(:upperword:]mU(P}qX>\?%)$Lwq[:alpha:]{-115,}================================{127,}", 1, 0 },
+ { "e)", 0, 0 },
+ { "[{,2[5}Klen+D0'YX(\?<=|_H]I,Y\"*/<3sM[:digit:]])#.", 0, 0 },
+ { "[:(xdigit:]){[:digit(\?mxmsx::][:as(\?<=cii:]d!{135})#)pP[:space:]Syyyyyyyyyyyyyyyyyyyy\"Gg8", 0, 0 },
+ { "[(\?()])", 0, 0 },
+ { "[^([^[^[[^[:alpha:]SIus[^f<f]}}}}}}}}}}][:xdigit(\?=:]Z{-13}*]_[]LLLL)]E[:alnum:]b$)]]]]]]]]]]]]]]]]]]]]]]]]][:lowerprint:][:ascii:]{,40}{86,}333333333999999999999999999999999999*fffffffffffffffffffffffff99999999U9|[:digit:][:upperword:]oowwwwwwww[wwwwwwwwww{195}[:xdigit:]]H{-73,153}R+zAz{}r/////////////{232,}kAoffffffffff[:blankcntrl:]xxxxxxxxxxxxxxx]KKKKKl0,[:alpha:]|{,-165}Qc{96}CCCCCCCCCCCCCCCCCCCC/", 0, 0 },
+ { "{}:V(7O-)[:ascii:][:graph:]PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#", 1, 0 },
+ { "[^(\?<[^=CC(CC$)]* c)BBBBBBBBBBBBBBBBBBBBBBB]z{-18,}", 0, 0 },
+ { "[[qqqqqqqqqqq(\?(qq235|ttttttttttttttttttttttttttttt[[ttt<<<<(\?{<<<<<<<<<<<<)<<<<<<<<p)/S9(\?{OOOOOOO(\?<!OOOk)})]nIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIb]Z})", 0, 0 },
+ { "[^[^(\?>][^((\?<!C(\?!+(\?=)]^8)6nx).)){,-13}[:blankcntrl:]\"(L{}){,29}nnnnn{-83}]l[:upperword:])", 1, 0 },
+ { "[(ZZ\"#(\?#Nb(\?<!:U)oRRRR])Zei${Ec/)s", 0, 0 },
+ { "[^[^[(\?(t(\?:3```````)`````)|#CB)/////////////////////////////*!liB#|CCCCCCCCCCCCCC(\?=CCCCCCa7N]weTTTTTTTTTTTTTTTT1{}o\?{}BBBBBBBBBBBBBBBBBBBBBBBB.])u{-218,126}.,[:space:]]", 0, 0 },
+ { "[[([:alnum:])yyy(\?!yyyyyyyyyy(\?!yyyyyyyyyyyyyyyyyyy[:graph:]I])Uw*X.^[:ascii:]{,-63}[:digit:]{-88})&&&&&&&&&&&&&&]*", 0, 0 },
+ { "[[[^K(\?=KKKKKKKKKKKK(\?:KKKKKKKKK[KKKKKK]]U[:digit:])]dd)({,16})xy+Pu)JJJJJJJJJJJJJJJ[:space:][:ascii:][:upperword:]ql_jywmt4B+]{-30,}^555555555Xza[:punct:]", 1, 0 },
+ { "[[^^XXX(\?:XXX((XXXXXXXXXXXXXXXXXXXX)v)$N9$r\"\"\"\"\"\"\"\"\"\"\"\"\"].{,239}$[:punct:]\"9999][:alpha:]{}c){,55}s[:upperword:][:xdigit:]310", 0, 0 },
+ { "[@([^I8oNl)]-{-203,-224}{-78,}KKKKKKKKc{-66}[:xdi(\?=git:]==========){}f{-124,}[:upperword:][:lowerprint:]]{}--------l+", 0, 0 },
+ { "[^]ozp+0(\?#\"[(\?()X]))[:blankcntrl:][^e{99,222}JJJJJJJJJJJJJJJ3F]\?[:blankcntrl:]l$ot", 0, 0 },
+ { "[[^[[((\?isximx:)2222222222(\?=22222[:graph:])+U)((\?{\?<=(\?()iYv8qc@#y)G])+}))FvnP\"7OZ-b273[:ascii:]Ak6*`S[:digit:][:graph:]]{2}^G{79,}DDDDDbbbbbbbbbbbbbbbbbbbbbbbb(bbbbbbb)|tP48y{wNJ_S hJbY]]dc", 1, 0 },
+ { "[:alph(\?{a:]p1[:lowerprint:]}){163,}", 0, 0 },
+ { "W()", 1, 0 },
+ { "()``````````````````````````[:ascii:][:alnum:]{,26}[:graph:]", 1, 0 },
+ { "[:al(\?<!num:]|byyy,*)U5%u${190}-{-221,-33}k7777777777777777777777777777777+eXXXXXXXXXXXXXXXXX[X(\?(XX)XX)S'vEAa]*e", -1, 0 },
+ { "[^(([R_AC[lE'{2(\?{28(]8LTt[]b[:punct:]]O)|2[:graph:][:space:]}) x3C[:alpha:])uI+dddddddddddddddddddddddd{-165,}FFFFFFFFFFFFFFFFFFFFFFF)cccc*[:upperword:]]G{,-38}{24,}555555555555555555555555555VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVZ[:blankcntrl:][:ascii:]", 0, 0 },
+ { "[^QQQQQQQ(\?#QQ(QQQQQQ[:punct:][:space:]){(\?(\?:!}[:graph:]t}}[^}}(}}}}}444444[^444444444444444444444]\?]G)E)L{,-103}{84,}r$ii]-[:alp(\?<=ha:]S5G~9>n*)P<3tttttttttttttttttttttttttt)n{}[:graph:]eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee{,83}[:digit:])0BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[:alpha:]{-155,}{151,}", 0, 0 },
+ { "Ue{,254}+f[:lowerp(\?<=rint:]U.fff)", 0, 0 },
+ { "QQQQQQQQQQQQQQQQQQQQQQQQAY<J)'MPi_u%#2doopqU7/{103}[:graph:]e!7{GOr", 0, 0 },
+ { "[^({,[^233}[^d)BBBBBBBBBBBBBBB=======(\?>===========[^=S|[^[:alpha:]G/]qqqqqqqqq{}[:xdigit:])..k", 0, 0 },
+ { "[([^[[:space:]ffffff(\?=ff]M]))[:xdigit:]UbCI,CzalLU*y5I[:digit:]r{-30,180}{-209,-45}Paf]", 0, 0 },
+ { "[^[h(\?{hhhhhhhhhhhhhhhhhhhhh})]{,143}[:lowerprint:][:ascii:((\?(\?=])[:asc)ii:])zp]", 0, 0 },
+ { "[[(\?{]})]", 0, 0 },
+ { "[[1\"3m^,(\?<!2((\?!\?#t```````````````````````````)\?)|c^)A^~]{61}W\\\\\\vvvvrrrrrrrrrrr[:digit(\?#:])]F[:upperword:]dX\\\\", 0, 0 },
+ { "([${144,}(\?<!)-RAk_F(\?imsxisx:=9]z/))", 1, 0 },
+ { "[[^[[[^([[^[^[^([[^([[Uiiiii#####(\?(\?{(\?<!#########(\?=#####).^)(.|>2m[M/2222222222222222222222222222(\?:22222222222(\?#22(\?:(\?=22222{,243}]x68+I/K)11111111111]\\pP[:graph:]$[:space:]^{}A)[:xdigit:]-={>", 0, 0 },
+ { "[(\?>[(^()Vty2vvvvvvvvvvvvvvvvz^])ZZZZZZZZZZZZZZZZZZZ----------------5\\dVLSp8UE2m+z3X/Sd", 0, 0 },
+ { "[}}}}}}}}}}}}}}}}}}}(\?#}}(\?<=)|*C ]*29JW7O9mEB]pE_OoxN)[:alpha:]", 0, 0 },
+ { "([^((\?<=\?)D{,200}.[(\?#:ascii:])[:space:].)[:alpha:]D|[:graph:]{,-41}*LLUUUUUUUUUUUUU{-189,-131}]qHR<k2@P{27}<^e,ub%\?/4){-243}+[:digit:]%*x9lA^", 1, 0 },
+ { "([:alpha:]bT&+_)$Z{,212}x26`", 1, 0 },
+ { "[^([^(A{[^}g(\?()A9p#54b]-------------------------------).wzD#=f\\)A)8a]]DNNNNNNNNNNNNNNNNNNNNNNNNNN", 0, 0 },
+ { "(W000000000000000000000000000000)", 1, 0 },
+ { "www(wwwwwwwwwwwww)", 1, 0 },
+ { "()555555555555{18}i+[:alnum:]E {}U", 1, 0 },
+ { "SqbHoooooooooooo[^oooooo([^ooooooo])\\N[:xdigit:]]oooo`", 0, 0 },
+ { "[999999999999999999uE{193,0}lx{7917}[:punct:]4&d]{221,}[:digit:]{49,156}[:lowe(\?<=rprint:])[:space:]{-33}w+", 0, 0 },
+ { "[^(\?{})<{220,-193}[(\?=:xdigit:]UUUUUUUUUUUUUUUUUUU'{-18}])", 0, 0 },
+ { "b[(\?<=:upperw(\?{ord:][:digit:]})EEEEEEEEEEEEEEEEEEEEE//////////////////){177}C", 0, 0 },
+ { "(^).[:alnum:][^[(\?=[(\?{[})DA5{)[[I~y&O\?9>])]][:blankcntrl:]M[:alpha:]x9[:upperword:]|[:xdigit:]b", 1, 0 },
+ { "()[:digit:][^[U}-]]{,206}V*WJ@R]\?", 1, 0 },
+ { "[^](\?#{}(\?[<=)yv)]r", 0, 0 },
+ { "({,-192}//////////////////////7!eW_0eoL){}", 1, 0 },
+ { "^[:punct:(]+)IIIIIIIII[:punct:]P$pP", 0, 0 },
+ { "[(\?=|U)^-]{-52,-72}[:digit:]*6666666666\?{{{", 0, 0 },
+ { "([^f(\?:+{1((\?=34,}]))^)s0bux7\?5`Bwr[:upperword:])Dy+", 1, 0 },
+ { "AL{}:::::::::::::::::::::::::::::::{,(104}~@,Ysey@h).", 1, 0 },
+ { "[^((.)))(\?()))))))))))))))))))))(\?msxims:))))))))))[)][:upperword:][:alpha:])", 0, 0 },
+ { "[^(()f])G^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^T{}N*nK[G]{,61}^^^^^^^^]", 0, 0 },
+ { "[(N::(\?<=[:digit:][:graph:][:space:]xB5[(:xdigit:]|Yv{}HHHHHHHHHHHHHHHHHHHHHHHHd).[:g(\?<=raph:])[:digit:]<<)[:digit:])[:space:]Q[:punct:]x7C]", 0, 0 },
+ { "[^((\?(\?(())a)(\?!){})W)pP3333333333(33333333333333333333hhh]{})", 0, 0 },
+ { "[^ [ a*FFFFF[^FFFFFFFFFFF(\?<[^!FFFF(\?=FF])])L1]{,-52}{B-bxsPKg{,8}[:digit:][:punct:][:upperword:]DD${,-131}", 0, 0 },
+ { "($$$$$$$$$$$$$$$$$$$$$$$$$$$$$^pP),,,,,,,,,,,,,(,,,,,,,,,,,,)QQQQQQQQQQQQQQQQQQQQQQQQ", 2, 0 },
+ { "[:lowerprint:]|l{(,-54}C{}*-)IIIIIIIIIIIIIIIII", 1, 0 },
+ { "()+", 1, 0 },
+ { "[(([(\?{[:punct:]]|))[[[[[[[[[[})]WWWWWWWW&$$$$$$$[:graph:]", 0, 0 },
+ { "[^(\?{}){(107[(^,}][:space:[]))^w,&aPPPPPP[^PPPPP{117,-213}s\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?]]]222222[:d(\?(igit:]NNNNNN)NNNNNNNNNNNNN8)I", 0, 0 },
+ { "[^(\?<!$)|TTTTTTTTTTTTTTTTTTTTTT(TTTT]a8)2<", 0, 0 },
+ { "([^[]%[^[^]-][:alpha:]37*:[:space:]]lQvu)[:xdigit:][:blankcntrl:]", 1, 0 },
+ { "[[Bl_>9C^:\?X_KK]2sw@hHZT!],uuuuuuut|lFW()'''''''''''''''''''''[:graph:]<~v{-251}0[:digit:]C[{222,}]{,41}{}*g^UuS/{-114}", 1, 0 },
+ { "(D{,-79}[:gra(ph:(\?(]C[:ascii:]))I[tC.%tkllll[^llllllllllllllll]&&&&&&)&&&&&&&&&&&&&&&&&&&&&&)]10435", 1, 0 },
+ { "[:al(\?{[^num:]]})}x'[:(\?#xdigit:])xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKKKKKKKKKKKKKKKKKKKKKKKKKKKKTTTr*%{~f", 0, 0 },
+ { "[ZQKEEEEEEEEEEEEEEEEE(\?<!]3|.~~~~~~~~~~~~~~303)33333333333333333", 0, 0 },
+ { "(-62([:ascii:]5555){-230,}<<<<<<SM[:punct:]{72}|E{160,})Pfqba!{,-188}DS{ +2tRu\"0JG$", 2, 0 },
+ { "([^(\?:(Ea00000000000000[:punct:][:graph:]{}]))[:xdigit:]{-65}t){164,}", 1, 0 },
+ { "[\?$$$$$$$$$$$$$$$$$$$$$$$$$F......(\?(.).q#R:j6%TTLCdtuM|8*54<GHoqEh9FBW0:W]L0)o][:upperword:]", 0, 0 },
+ { "[(\?>[:alnum:]W[:space:]]D)|L", 0, 0 },
+ { "(M(MM)[:alnum:]|[:lowerprint:]4)", 2, 0 },
+ { "[[^(\?:{}{2[2(\?>0,})]]]Etu)-)", 0, 0 },
+ { "([^[^^z[:graph:]]#{-144,96}[:punct:]!4LY//////////////////SSSSSSSSSSSSSSSSSSSSSSSSS[[^:xdigit:]\?`-!L#p0{52}]%{-121,}[:graph:]]WqJ>$6UBg{,7}[:blankcntrl:])[:upperword:]y2wW!A[:blankcntrl:]0CN\?", 1, 0 },
+ { "[[^(\?:|+bII(IIIIIII(\?(\?>!)275SIIIIIIIIII(IIIIIII(\?=IIIIII[:graph:]|)`]S\?.}A)[:alnum:]Jgggggggggg{-150,}{-89,})[:alpha:]Q)|07be5:j)]", 0, 0 },
+ { "([(\?i(ms(\?=x-x(\?>:))C)]){})>eIqm~lFb[:upperword:][:blankcntrl:]w=[:digit:][:graph:]", 1, 0 },
+ { "([HHHHHHHHHHHHHHHHHHHHHHHHHH[^HHH(\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?!!!!!!!!!!!!!!!!!!!!{23}]~J=[:ascii:]tttttttttttttttt])-216", 1, 0 },
+ { "B{[^-32,246}{13(\?!0}q>GVQw*[:digit:][:punct:].77777777777777777777`T(-t01odD]\?${}{-247}+gV{131})+[:lowerprint:]m/z~d", 0, 0 },
+ { "[t[$FV+(\?=E=[^])]-$U{-22[5,}{253,}08g]$[{}][:xdigit:][:punct:]{-18}{-173,}]{,-191}V_|90", 0, 0 },
+ { "()$", 1, 0 },
+ { "[^[^((((((((((((((W[(\?::blankcntrl:]&-JH]J){93}LLLLLLL|r{,221}tY/172]-AS", 0, 0 },
+ { "[^()(\?{qqqq(\?msimsx:qqqqqqqqqq3999999999999GGGGG|S*W%{,128}][:xdigit:]AJt]}\"Zf!lRpr{>){,36}})", 0, 0 },
+ { "[([]^]^)", 0, 0 },
+ { "([.(\?#){}[:alpha:]\?S{2}P%Gw]nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnYiq5)>i*r<", 1, 0 },
+ { "[ggggggggggg$PPP:S (:]N{239,}|A[:lowerprint:]vvvvvvvvvv[:lower(print:]{-184}({-133,}+)[:punct:]P/Q.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", 1, 0 },
+ { "(RRRRRRR[^RRRRR[RRRRRRRRR])]", 1, 0 },
+ { "[(\?:^])D%", 0, 0 },
+ { "()[]#C[+[j]{,29}-]", 1, 0 },
+ { "(([(\?(((\?{\?!(\?=\?=#[Es*){02$r'}(\?:3pz)uPPPPPPPPPPPPPPPP(\?(\?>:PPPP][:graph:][:ascii:]`.)[:punct:][:a(\?mxi:lnum:])r)$)[:xdigit:]$[:(\?=digit:])aa[^]a)\?])sQQQQQQQQQQQQQQQQQQQQQQQQQQ^|$)-}))", 2, 0 },
+ { "z@@@@@@@y${}[:(\?:upperword:]l\?{,144}-)", 0, 0 },
+ { "[:aln(\?:(\?>um:(\?imximsx:]){})FGGGGGGGGGG|-p){,105}", 0, 0 },
+ { "[[{17}llllllllllllllll(\?:lllllllll{,(\?#-94}OUUUUUUU(\?#UUUUUUUUUUUUUAA]p[:digit:]{-1(57,}5yyyyyyyyyyyyyyyyyyyyy[:alnum:]v{-185}^^^^^^^^^^^^^)d[[[p)]))", 1, 0 },
+ { "()|[:digit:].E2o", 1, 0 },
+ { "()3[:lowerprint:]", 1, 0 },
+ { "[(\?{(\?#(\?>SN}[^)z+r^t[:digit:]seP[:alnum:]$b1ZY[U(\?<!U4IIIIIIIIIIIII(\?<=IIIIIIIIII]m)]))]4)", 0, 0 },
+ { "{,74} qkk[^p]kbi6>{}000000000000000000000000000000$|)", 0, 0 },
+ { "[:(\?=digit:])v{164}", 0, 0 },
+ { "[:graph:]h[:upper(\?(wo(\?{rd:)])00000[^000000000000}).4OEVf{,-46}]A", 0, 0 },
+ { "[](((((((((((((((N{{{{{{{{{{{{{{{{,-1}e]a{-166,-44}", 0, 0 },
+ { "([[^[^[(^[]]YYYYYYYYYYY]D.cQ{}[:alpha:]ttttttt000000[^0000(\?<!0000000000000000N::::::::].][:alpha:]#5\?{}{-253,-193}]\\[:ascii:]tS{,35}B)ffffffffffffffffffffffff))/", 1, 0 },
+ { "(G)[:alpha:(\?#])W{-197,-220}w8", 1, 0 },
+ { "{-2[^00,(\?#-([84}ig+)]]l[:graph:][:graph:][:space:])aaaaaaaaaaaaaaaaaaa{-208,}ea{,224}", 0, 0 },
+ { "[^[W(\?<=[B[:xdigit:]{255,}FAAAAAAAAAAAAAAAAAAAPP])[:xdigit:]+][:lowerprint:]${-195}", 0, 0 },
+ { "[v{104,}BB].HHHHHHHHHHHH[:ascii:]bbbbbbbbbbbbbbbbbbbbbbbbbbbb(btttttttttttttttttttttttttt){180}", 1, 0 },
+ { "[^(i[^iiiiiiiiiiiiiiiiii(ii)n])#######################]", 0, 0 },
+ { "(([:space:])[:g(\?>raph:])[:punct:][:upperword:]LV\"t+t!)[:ascii:][:lowerprint:]q", 2, 0 },
+ { "[[[^([7(\?[<!)\\PP~D7L (\?imsimsx:(\?= $GS26L3-J(\?()!)]]{-178}%$[:p(\?!unct:]))yyyyyyyyyyyyyy@w,[11!R86:)G*[(\?(:blankcntrl:]267$~L\?{-108}k[:alnum:]So\?Y/eq]-|[:xdigit:]555555555555555555555555555)55555........W*O))][:alnum:]]I{,-126}[:lowerprint:]8\?[:xdigit:]u%wHc6\?:Pc...........................,,,,,,,,,,,,,,,,,,,,,,,,,,,]", 0, 0 },
+ { "((3pPp))QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 2, 0 },
+ { "[[^]{-244[}(\?([^|W0E4]UUUUUUUUUUUUUU[:upper)word:][:space:]{-57,})+L>R]]$PeFuufcBA`qr!!!!!!!!!!!!!!!!!!!!!!!!!", 0, 0 },
+ { "[[(\?#F^(\?<!)|)fff(\?!fffffffffffffffff(\?{ffffff(\?:ffffff[:alnum:])]]c.\?-}))", 0, 0 },
+ { "[^[^((\?:)ww[wwww(\?>wwwww)3z/57z){34}]/(/////////////[^//////////////////)]E%)L{-133}]*$]", 1, 0 },
+ { "(!)GS[:ascii:][:punct:]{235}T'&-_h\"", 1, 0 },
+ { "(){}", 1, 0 },
+ { "[[^((\?!(\?<=)*QF[:alpha:])([^[^\?<!x60t(\?<!UUUUUUUUUUUUUUUUUUUU)K&d{118}z7nM.G)```````````````````````````E:(\?(){31,}){}]k]){,109}[:space:]]ZZ[:xdigit:]]{-68,}`{}{}e\?[:alnum:]", 0, 0 },
+ { "[^{223}.^,-qqqqqqqqq((\?!\?>qqqqqqqqqqqqqqqqqqqqqqqP6W0_'O)Bur*'6&*t)]{65})+", 0, 0 },
+ { "([(\?=)]wr$7f5ru){100,}[:xdigit:]y{}[:digit:]{}2n@P|9#mru~97{-189,73}$a", 1, 0 },
+ { "({-113,213}){-172,221}B[:ascii:]{,-48}", 1, 0 },
+ { "[^[[Xf`````((\?{(\?<=\?imsmsx:`````````(\?!`````````[```(\?mximsx:``(\?(&|o{xIaO][:)space:]3))\?])+)*<|@@@@@@@@@@@@@@@@@@@@@@){-251,}{}]*[:graph:]1!azE\?|-120u*][:lowerprint:]})", 0, 0 },
+ { "[[[^##(\?################(\?>(\?(##t)][:punct:])b))<<<<<<<<<<<<<<<<<<<<<<<<<<[:alnum:]y >u=l:rp8i3Ci#]46%NIO-W[:space:]IIIIIIIIIIIIIIIIII]W[:space:]f]l{-253}", 0, 0 },
+ { "[:graph:]L{-136,175}{[^}h(\?=t)Q]ooooooooo(ooooooooooooooooo_)[:space:]q\?", 1, 0 },
+ { "()$.", 1, 0 },
+ { "[(\?<!^$.\?{197}B]$)", 0, 0 },
+ { "[:di(git:])[:low(erprint:])qqqqqqqqqqqqqqqq[:digit:]", 0, 0 },
+ { "((zzzzzzzzzzzzAUUUU)l$]VD z~)n", 2, 0 },
+ { "([^[(\?<=^[]{}][.WWWW)044444444444(\?=44(\?{444(\?{(444444444444e{(\?=}}))..t]+[:(\?<!xdigit:]P]-N}))))|)", 1, 0 },
+ { "\\ce[:(\?#asc(\?{ii:])})[:upperword:]`^", 0, 0 },
+ { "[:graph:(\?<=])[:alpha:]", 0, 0 },
+ { "([:upp(\?=erword:])pC)lp\?", 1, 0 },
+ { "(oooooooooooooo\?fN)-[:alpha:]{-213}[:alnum:]qHEu", 1, 0 },
+ { "[:punct:]TTTTTTTTTTTTTTTTTTT[:d(\?#igit:])[:alpha:]", 0, 0 },
+ { "([^[^[^J4(+++++++++++++++++++++SgDE(\?>\"y8].]:::::::::::::::)pP5-]p)O{,199}xxxxxxxxxxxxxxxxxxxxxx[:ascii:]%", 1, 0 },
+ { "([:alpha:]Fs)Z", 1, 0 },
+ { "[()]{209}[:alpha:]hhhhhhhhh(hhhhhhhhhhhhhhhhhhhhh)pP<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", 1, 0 },
+ { "-{-8,}.[:(\?imsxx:ascii(\?<!:]{-231}aa*{}K^UQL\?)d\?[:lowerprint:]W)q>D9'", 0, 0 },
+ { "[#(\?msximsx:#########################-IIIIIIIIIIIIII(IIII(\?#IIIII((\?#[^III{})N.[(\?=:lowerprint:]))CwT,,,,,,,,,,,,,,,,,,,,Sq]$CCCCCCCCCCCCCCCCCCCCCCCuuuuuuuu])))", 0, 0 },
+ { "[:xdigit:][(\?#]){13}{,75}lllllllll", 0, 0 },
+ { "[c]QQQQQQQQ1+{-252[(\?#}33333])[:upperword:]", 0, 0 },
+ { "P@i #>>PF!@8G<[(\?:^P]-)D", 0, 0 },
+ { "uZZZZZZZZZZZZZZ[^ZZZZZl*-211{199}(\?!p])EEEEEEEEEEEEEEEEEEEEEEEEEEED[:lowerp(\?msximsx:rint:])", 0, 0 },
+ { "[(\?!^])021[:graph:]'", 0, 0 },
+ { "\\(\?>[(\?<=:ascii:]{}[:alpha:]d8}G))", 0, 0 },
+ { "[^[((\?!1)[^,a|]\?{,242}[:alnum:])X\"a", 0, 0 },
+ { "pP[((\?simx::a(\?!lnum:]vvvvvvvvvvvvvvvvvvvvvvvvv)|O0)[:digit:]ooooooooooooooooooooo)\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"", 0, 0 },
+ { "_ L:8J-~ Y$[:uppe(rword:]{,-184}]{}6.A)", 0, 0 },
+ { "{,105}.(9]]{-12})N@0nOOE", 1, 0 },
+ { "HHHHHHHHHH[:xdigit:]uuuuuuuuuuuu{}E^X\\\\\\12601", -1, 1 },
+ { "( o)=\"OU7h{V>", 1, 0 },
+ { "[[:xdigit:])))))$[:xdigit:]+{152}{,-50}(c),,,,,,!!!!!!!!!!!!!!(\?>!!!!!!!!!!!!!.[:digit:]i>\"O'i9])-175d_", 0, 0 },
+ { "[([^[^[^([[Eeee[^eeeeeee(\?(\?<!(eeeeeeeeeeeeeeeeeef|]][:alph()\?>(\?!(\?>a:]a{,166})/////////////////////[:gr[^aph:])Gpu", 0, 0 },
+ { "(7)NNNNNNNNNNN132", 1, 0 },
+ { "[([\?#^[]{QKm$v])][:alp[^ha:]]", 0, 0 },
+ { "(:{86})7{K|[:alpha:]{O", 1, 0 },
+ { "([Y(\?{[[^:alnum:][:alnum:][:digit:][:a(\?(lpha(\?(:].})", 1, 0 },
+ { "[[({29,-30}([[^:digit:])Y]]J=~{,220}[:blankcntrl:])0ooooooooooooooooooooooooooooooo[:punct:]&]", 0, 0 },
+ { "[^1Dx32[:alnum:]]{[(\?::punct:]MMMMMMMMMM)12759", 0, 0 },
+ { "([[[]]*|(_])[:u(\?{pperword:]})", 2, 0 },
+ { "[:upper(\?(wo)rd:]){-16,250}", 0, 0 },
+ { "([^{194}i(\?({161)}PP\\S{}{,-14}]))z{208,225}BpPEt", 1, 0 },
+ { "[(\?m-ms:)}&!@29k0sUqzt9}<-x|A$!+G>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CCCCCCCCCC-][[:space:]][:space:]El", 0, 0 },
+ { "()[:digit:(\?isx(\?>ix:]K^WQQQQQQQQQQQQQQs)[:lowerprint:])", 1, 0 },
+ { "[a|(\?imix:S(\?(SSSS)SS(\?>S)]W)8t[:ascii:]f$)[:alnum:]111111111111111111111[^[:space:]x{12729}+'''''''''''''''']", 0, 0 },
+ { "[^(\?!(\?(\?#=)a)[:punct:]=2)(){}$$$$$$$$$(\?ims(\?#-isx:$$$$$$$$$$$$$$$$(\?#$$s)x{294b}##############################slllll)]){,209}333333333333333333G:v2/K", 0, 0 },
+ { "[^]ub(\?<=)vQ6(\?#Z\"3.)[:space:]u[[:digit:]]7777777777777777U'{}sssssssssss", 0, 0 },
+ { "(([(])`[:ascii:]b)", 2, 0 },
+ { "[[[^[^([^[^(\?=(\?imxisx:[[^w])", 0, 0 },
+ { "pppp(pppppppppp-{-175}Nb>k&)sssss{-190,-54}", 1, 0 },
+ { "()OJ@`'%[:(as(\?!cii(\?#:]))+pffffffffffffffffffffffffffff{,162}[:ascii:]5)s-[:graph:]", 1, 0 },
+ { "[(M{}Ux5{jaW/{}[^u[:alpha:]s^{84,}PPb@Wt$(\?>nha<Yf41a)]{}[:lowerprint:])*[:lowerprint:]][:upperword:]^1gS.^=pp{}FFFFFFFFFFFFFFFFFFFFFFFFFFF33333333333{}", 0, 0 },
+ { ")\?L9~h4BQnNp F\\Q{}", 0, 0 },
+ { "($)[:upperwor(\?:d:])N[:alnum:]bcccccccc5555555555555555555555555.N[:blankcntrl:]", 1, 0 },
+ { "2222222222222222222ppppppppppppppppp[:lowerprint:]))[^B\\e{{{{{f]6#+{,-104}{{{{{{{{{{{{{", 0, 0 },
+ { "<[(\?>:al[^pha:]])\"O\"vN", 0, 0 },
+ { "[(\?>d8E@b.{(\?<=,-250}(\?=mx48[:punct:]^&)]nAeYY)W)-13272", 0, 0 },
+ { "22222222222222222222222222///////////////////[:digi(\?#t:]eM)[:lowerprint:][:alpha:][:alpha:]EEEEEEEEEEE", 0, 0 },
+ { "[(\?={38,223})^\\\\\\\\\\\\\\\\L(\?:{,-50}3|)}r]aW\\x70U{-110,}8LUf)w]4+oav", 0, 0 },
+ { "G[:upperword:]v[:lowerprint:]-tu)j8CK", 0, 0 },
+ { "[([([^().(\?(\?><=c)'(\?<(='(\?<!''''''''(\?(\?<!!'''''''''''(\?=''''''/(|dHj(P>L\?q!G))|)(\?=n(\?(^tk)T-z$q!D|2<rc[^{,53})]jZy))))6)[:bla)nkcntrl:])010])7pE`l[:space:]([:lowerprint:]eXXXXXXXXXXXXXXXXXXXTTTrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr]+[:alph(\?!a:]7)444444444444444444444444l{34,}]J{}yyyyyyyyyyyyyyyyyyyyyyyyyyy)\?'z9~9s.mA", 1, 0 },
+ { "().", 1, 0 },
+ { "{-205(,}[:al(ph(\?>[^a:]W,[4DLR[^^8THMtVv~KKw(\?>)pPF)].{-245,}]))fffffffffd[:alpha:]zzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 1, 0 },
+ { "[^[[^]{-[1(\?imximx:83,}{,182}][:graph:]]^])-bTO X0P", 0, 0 },
+ { "[11111111111(\?#11111111]U[:asc([\?!ii:]{,37}+{-89}){-170,218}{-21,})f[:xdigit:]]P.[:xdig(\?:it:]145)YYYYYY$S@:@@@@@@@@@{-150,-109}", 0, 0 },
+ { "{-40}<o][^D[(:graph:]]d).Q", 0, 0 },
+ { "()APPLn[:xdigit:]", 1, 0 },
+ { "[([^\?+++++++++++ [ (\?> (\?( (\?{ (\?!]E{-29})pP)})ZpP", 0, 0 },
+ { "(t|{}c[^z^\?(@YLD]bSSSSSSSSSSSSSSS)+{{{{{{{{{{{{{{{[:xdigit:]n>1)WkF}7", 1, 0 },
+ { "W22[0Q[^d-d{}PPPPPPPPPPPPPPP<^FZ(\?<=\"[U]Yo}9H'cYy]S[:alnum:]^8wTDH)^u", 0, 0 },
+ { "([^[(\?:(\?>((\?#$)(\?{^(\?>))///////////(\?>/ggggggggggggggggg{1(\?!90,-13}\\D)Dyyyyyyyyyyyy(\?!y(\?<!yyyyyyy)})]]$)[:xdigit:]|{}-)#a))nPpP[:lowerprint:]AA)V+q^[:blankcntrl:]", 1, 0 },
+ { "([^(\?!]))D{,97}", 1, 0 },
+ { "(c){,141}", 1, 0 },
+ { "nn[:s(\?<=pace:])[:upperword:]ooooooooooooooooooo*^[:space:]`{-188,129}mmmmmmmmmmmmm^.", 0, 0 },
+ { "[[G{(\?imsximsx:2(49}{,-46}r(\?(\?=#Gw]u))[:bl(\?>ankcntrl:]))(^m+)zSiZ F4[!]VV$E{-9,-100}''''('''''''''\?DEOOOOOOOOOOOO###############[:space:])HHHH)[:digit:]'////////////", 2, 0 },
+ { "[^*}(\?>)(\?:7Q=#+]KKKKKKKKKKKKKKKKKKKKKKKKKKKG)]]]]]]]]]]]]]]]]]]]]]]]]]][:alpha:]-{}", 0, 0 },
+ { "[n(\?<(\?#!nnnnnn55555{205,}!)[:alnum:]^]!!!!!!!!!!!!!!!!!!!!!!![:punct:])[:x(\?(digit:]vr)|'n6W5 D&jk[:punct:]5)", 0, 0 },
+ { "[^P(P{(\?i(msxisx:235,}))***])[:alpha:]^", 0, 0 },
+ { "[([t(\?<!(\?<!4])[:u(\?=pperword:]))-])}}}}}}}}}}}}}}}}}c{-39,}[:digit:]$-", 0, 0 },
+ { "([^)]{241}[:xdigit:][:upp(\?=erwo(\?(rd:]-xF5b{})q[:ascii:])T4U{185}9999999999)()X&Ny[:alpha:]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@{69,}[:alnum:]x{d7f8}p-[:digit:]", 2, 0 },
+ { "(f)(${,111}{25,}!\\d{,94}[:blankcntrl:]@[:space:][:ascii:])-237{,232}DQVVVVVVVVVVVVVV)-", 2, 0 },
+ { "PP[:g(\?!raph:]){}", 0, 0 },
+ { "([[^-][^4[:digit:]NNNNNNNNNNN]TVU:])[:ascii:]", 1, 0 },
+ { "(([^(\?[[^<=)][:graph:]+iiiiiiiiiiiiiiiiiiiiiiiiii0INFX[:xdigi(\?(t:][:blankcntrl:]][:graph:]qM6A[:alpha:][:graph:])1*]eFvvvvvvvvvv)v-)U))t{89}", 2, 0 },
+ { "[^ZZZZZZZZZZZZZZZiiiiiiiiiiiii(iiiiiiiiiiiiiii{}))))))))))))))))))]))))))))))))))))))))))))[:digit:]-", 0, 0 },
+ { "ddddddddd+zzzzzzzzzzzz[:graph(:])ssssssM{-223}[:graph:]", 0, 0 },
+ { "[:alph(\?>a:])x11{-144,45}.", 0, 0 },
+ { "[]{#y.^(\?{{}&&&&(\?:[^&&&&&&&&)[:punct:]n{190}OylBQ{(\?!-73})2u',x(\?#Ds(\?#{})j(\?{-})})u0(((((((\?{(((([:alnum:])MC})b=71TncyE>[:xdigit:]*\\f]{}]\"p#!8twZT\")[:punct:][:space:]", 0, 0 },
+ { "[^(Z6]8)|'@p8{}[:upperword:]MMMMMMMMMMMMMMMMMMMMMMMMMMMM{}7c", 0, 0 },
+ { "$0)@#vp,VcJ.Bdh", 0, 0 },
+ { "[[^(-])nnnn+s`[:alpha:][:blankcnt[^rl:][:upperword:]{-15,}][:g(raph:]c]){,-177}6[:upperword:]##################{,-14}", 0, 0 },
+ { "[[(5C{86(,}PPrrrrrrrrrrrrrrrrrrrrr{150,182})N{}LSC|)-[:alnum:]{}KKKKKKKKKKKKKKKK<4=~7K3PPPPPPPPPPPPPPPPPPPPPPP[:lowerprint:]]]", -1, 0 },
+ { "([^(x{145b[5}^hfc.0)+]z@_&lA{-34,}])X\?", 1, 0 },
+ { "([(\?<=)(\?!])l)L", 1, 0 },
+ { "({-104,}DrPPDF4444444444444[:space:])[:space:]", 1, 0 },
+ { "())))", 1, 0 },
+ { "[[^((\?>\?(\?[{})q5v}r7t(P)xtffffffffffff))]{,-66}kdExX&-SCeCzzzzzzzzzEc)E,\"^I]x{e629}|{}]", 0, 0 },
+ { "[h[:punct:]p\\[\\\\(\?:\\\\[^\\\\)Eo#:C$u[^T/ysA[*%nM:f]{,221}[:lowerprin[^t:]{]bx{f285}E]E[:alnum:]+]1oe3B][:alp(ha:]]fh7}M$l)D{17}", 0, 0 },
+ { "IIIIIIII[^IIIIIIX]-_S[:digit(\?#:])33333333333333333333333333[:punct:]iiiiiiiiiiiiiiiiii", 0, 0 },
+ { "[^[[:punct:](\?((\?:^ #Q_po(\?=[:alpha:]{}z()(\?!======'wq$Q2)LLLLLLLLLLLLLLLe(C9gggggggggggggggggg[(\?<=:alnum:]()\?<!{-85,}W[[[[[[[[[[[[[[[[(\?{[[[[[[^)(]\?])|uuu[uuuuuuuuuuuuuuuuuu{,-20}p${}]MHI&7s:\?$[:digit:]-:)_V`*{-52,}{250}$:ME9izF/uP[:blankcntrl:]})''''''''''''''''''''''''''''')CCCCCCCCCCCCCCCCCCCCCCCCdd[:ascii:][:lowerprint:].Mcccccccccc2B{-230,}$[:digit:]", 1, 0 },
+ { "()|mOAuK~P144[:space:]^9dddddddddddddddddddddddddddddd[:blankcntrl:]", 1, 0 },
+ { "[^[^[^.L[^-vEUl(\?>(\?=a!Ib1P]])])~~~~~~~]xE9", 0, 0 },
+ { "X()", 1, 0 },
+ { "[^()(\?#G(\?<!)(\?=^r])*,XXXXXXXXXXXXXXXXX@)444444444", 0, 0 },
+ { "([[((\?<=({,-70})-[:xd(\?=igit:]{,138})", -1, 0 },
+ { "[(^]{62,67})", 0, 0 },
+ { "([((])[:space:]))", 1, 0 },
+ { "(a{(109,})[:alpha:]{,-121}{})]RRRRRRRRRRRRRRRRRRRRRRRR{}{125,}ttttttttt{46,}`[:space:]", 2, 0 },
+ { "[^[^([q[8]~.IPmiBSspP)]QpX[pT==8@lulANS]]{,-98}]", 0, 0 },
+ { "[^77777777777777777777777(\?>777777])", 0, 0 },
+ { "(),e<^X~{[:alpha:]{}G{70}", 1, 0 },
+ { "({-211,}'){}", 1, 0 },
+ { "[^(\?imsxsx:{}[*])cccccccccccccccccccccccccccccccc<z0W8]$", 0, 0 },
+ { "(){2,89}$z", 1, 0 },
+ { "((050[^\"\"\"\"\"\"\"\"z]8|j{}{,-112}$).pP)qq1~hW}L", 2, 0 },
+ { "[[^[(+xx(\?<!xxxxxxxx(\?!xxxxxxxxxx(\?#(\?>[x))(\?:]r.]]]))[:graph(\?<=:])))", 0, 0 },
+ { "[^([(\?#)(\?(\?(<=)l|\?(\?!])kkkkkkkkkkkkkkkkkkkkkkkkkk", 0, 0 },
+ { "[:xdigit:]K(KKKKKKK)^3c.OOO{-240,-10}2{-97,-139}*{-34,}[:xdigit:]", 1, 0 },
+ { "[([^66666666F(\?>FFFFFFFFFFwpP)LLLLLDeDA&Am$l[:xdigit:]!T5#]n[:alpha:]U*)))))))))))))PP]", 0, 0 },
+ { "[[[:punct:]u^[:xdigit:]L(\?:[:xdigit:][[:graph:]PP{21}A[:alpha:]8%I(M%b<eE~#C@r=uG~~~~~~~~~~~~~~~~~~~~~~~~~~~~+w]pP)T]]$$$$$$$$$$$$$$${-121,}|l", 0, 0 },
+ { "([(107{,-4(\?=}~[^D)])f]{,46}+ri<)", 1, 0 },
+ { "[(\?<=]{,208}+~)", 0, 0 },
+ { "[^444(\?<=4444444[:alnum:]&[,i]0)[:alpha:][:upperword:]", 0, 0 },
+ { "[^([^(\?()*+)SS(\?>SSSSSSSSSSSSSSSSSSSSSS]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]{,-1}])[:blankcntrl:]===============================[:punct:][:blankcntrl:]Z[:space:][:ascii:]$|$[:blankcntrl:] JR.{,133}[:alpha:]$\?)<]", -1, 0 },
+ { "(OL[:u[pperword(:][:s[^pace:].[:spac(e:],,,,]*])$)\?)", 1, 0 },
+ { "(VI[:digit:][:alpha:]6)EG", 1, 0 },
+ { "({}){-2,-40}rrrrrrrrrrrrrrrrrrrrrrr[:punct:]", 1, 0 },
+ { "()q", 1, 0 },
+ { "[^([^[([^C|])]{,-56}[:xdigit:]{-144,}V])fYv{-[40,-58}$@@@@@@@@@@@@@]|Y(-]-.]h-[:dig(it:])>>>dddddddddddddddddddddddddd{101,}", 1, 0 },
+ { "([P,{1(\?(\?(<=28,-218[^)}LoZX)])!!!!!!!!!!!!!!*[:blank(\?!cntrl:]ed)\\\\\\\\\\\\\\\\\\\\[\\L\?][:graph:]:*Y{-108,120}xCC)]", 1, 0 },
+ { "(A[:space:]PP{185}a^!!!!!!lllllll)*db\?$Pfr", 1, 0 },
+ { "{-21,-118}kG[(\?{:xdigit:]})[:punct:]{69}Qyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy5{}TTTTTTTTTTTTTTTTTTTTT", 0, 0 },
+ { "[[^[P(\?<=P$X>0^d.[:punct:](\?#ccccccccccccccccccccccccc{}3N000(\?>00000000000000000000000000000]f[:punct:]5)).R================{,222}^wwwwwwww$)]-{} ]{,-22}CjP{242,}", 0, 0 },
+ { "[(\?#^]{})", 0, 0 },
+ { "[^([[([([[([^[^(\?:(\?(\?(!)]\"))h>\"RRRRRRRRRRRRRRRR[^RRRRR{68,-65}7Q(\?{]", 0, 0 },
+ { "(P{}){175,}PP{}rttttttttttt", 1, 0 },
+ { "[:bla(\?{nkcntrl(\?#:]})))))))))))))))))))))))!!!!sR{})", 0, 0 },
+ { " [:digit:]dAAAAAAAAAAAAA^[:ascii(:]55)^", 0, 0 },
+ { "($*)dZY", -1, 0 },
+ { "[:graph:][:lowerprint:]S[:gr(\?=aph:]{-128,}666666666666666666666{}[:upperword:]|nnnnnnnnnnnnnnnnnnnnnnnnnnB)c[:xdigit:]{-225,}{-4,}{-192,}QQQQQQQQQQQQQQQ@@@@@@@@@@@@@@@@@@@@@@.", 0, 0 },
+ { "([:digit:]s{44,}{}{-31,}c{,-130}pP){-241,}UeN", 1, 0 },
+ { "([^)((\?>\?#{}hK\"V2\?d][KKK(\?imsxim:KKKKKKKKKKKKKKKKKKKK[^KKKKKKKKKWWWW[WWWWWWWWWWWWWWWWW)B])_l_3", 1, 0 },
+ { "[(^[(\?!*){[^,91}].j]*]L)*c|[:alpha:]&", 0, 0 },
+ { "[^[[[^[777GGG(\?:W_U(\?imsxms:[:punct:]A]-)[:digit:][:blankcntrl(\?(:]][:alnum:)])]WRRRRRRRRRRRRRRRRRRRRRRRRRRR]{31,}[:xdigit:]][:xdigit:]))))))))))))))))))))))$[:xdigit:]", 0, 0 },
+ { "[:ascii:]m*[:punct:]#[(\?<!:punct:][:alpha:]-,7vyXeeeeeeeeeeeeeeeeeeeeeeeee^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^%%%%%%%%%%%%%%%%%%%%%%%%%%%%[:digit:]''''''''''''''''')", 0, 0 },
+ { "([^*[(:punct:]9999999999999999999{147,}]j{,193}{171}Z-)){208}0[:graph:]yDt", 1, 0 },
+ { "(dw[[:alpha:]U]ttt[tttttttttttttttttttt]Q^171e)[:xdigit:]/", 1, 0 },
+ { "[[^((\?#)Tqqqqqqqqqqqqqqqqqqqqqqqqq105++++++++++++++++++++++++++b7V+7dit]])|D", 0, 0 },
+ { "{}P7.Ajh[:xdigit:]^[:blankc((\?(\?<=nt[rl:]FFF)-]){}o|a[:grap(\?!h:]))PsssssssssssssssssssssssssssssssN^{-60,}Kb", 0, 0 },
+ { "[:alpha(\?(:]$!_+777777777777777777777777O)666)lll[^llllll[^l{{{{{{{{{{{{{{{{{{{{{{|]{-217,}MoEl`7)^)LlU[:alph[a:]({-241,27})]]{-212}{,249}n)X", 1, 0 },
+ { "[U|ajP[:alnum:]n[(:digit:]]W)[:graph:]b[:xdigit:].P", 0, 0 },
+ { "(([:low(\?-imsx:erprint:]|{}[:ascii:][:gr(\?:aph:])>>>>>>>>>>>>>{,-129}))\?{-226,}^P)R", 2, 0 },
+ { "[^[[nnnnnnnnnn(\?=nnnn(\?!nnnnnnnnnnnn(\?#nnnnnn{,-38}N){202,}]$[:alnum:])]t][:alnum:[]^=w){237}][:alpha:]-[:alpha:]+e", 0, 0 },
+ { "()[(\?(:digit):]+qc)O88888888{,151}aJ", 1, 0 },
+ { "([^([(\?!sv(\?=)d]{-200,})N))]Z{-73,15}", 1, 0 },
+ { "([\?\?\?\?|||||||||||(\?{||(\?=||||||||-}[))Ehhhhhhhhhhhhh{,202}&TcfL((\?:>)((\?!\?>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$8[:alpha:]\\d])]C[:graph:]h*,\"\?u{|mU,a)[:blankcntrl:][:lowerp(\?>rint:])PPnP+9.[:xdigit:]*PPjjjjjjjjjj~y<#*scf_\"^e[:xdig(\?(i)t(:])~$y)^){-131,77}^L%", 1, 0 },
+ { "[^[(((\?>)$}h9$B5+yhU/Nqh$YYYYYYYYYYYYYYYYYYYYYShK)3WHw1vMMMMMMMMMMMMM(\?=MMMMMMMMMMMM[:alnum:]/)dddddddddddd(dddddd\"e5zLW)+![:space:]+BHGHfAS]\?IIIIIIIIIIIIIIII*&&&&&&&&&&&&&&&&&&)NNvwDteepjdm<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<${61,219}D][:digit:]0", -1, 0 },
+ { "[:punct:][{177,(\?=234}]ix9*)", 0, 0 },
+ { "([^K{,3(\?<=4}]I)\?U)", 1, 0 },
+ { "[([^[[[^([([^[^(\?=])X", 0, 0 },
+ { "[:blankcntrl:(])qd_R\?{\?r[=\"[^[^6]vX8)a+{C%H84CK6Uy#E]sE{208}", 0, 0 },
+ { "PPPPPPPPPPPPPPPPPPPPPPPPPPnnnnnnnnnn()[:upperword:]us", 1, 0 },
+ { "x{,46}[:graph:]LU{}CU)", 0, 0 },
+ { "()-t|[^W{}][:lo[^werprint:]{}]\?b5", 1, 0 },
+ { "()x5A", 1, 0 },
+ { "[([^]-217)]s{-47,135}0000000000000000000000000000000{,-108}", 0, 0 },
+ { "[^((\?{[^L\?u]})f", 0, 0 },
+ { "()[[^^(\?{y(\?=VF_(\?<=]D}))]-= {46,})^5bIEQ{,-96}Z", 1, 0 },
+ { "([^{}f[:punct:]\"X%%%%%%%%%%%%%%%%%%%%]5{-194}A[:punct:]mnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn+AAAAAAAAAA-)", 1, 0 },
+ { "(CCCCCCCCCCCCCCCCCCCC{-230}352{-182,-68}O4{})", 1, 0 },
+ { "([^[^\?[:space:]$TTTTTTTTTTTTLLLLL[^LLLLLLLLLL[^({}{4,-179}]]J] C]){}C{}{-224,})QQQQQQQQQQQQQQQQQ^", 1, 0 },
+ { "([[:alnum:]].){-155,-82}dzI{55,}^", 1, 0 },
+ { "([[:alnum:](\?#{88,-178})[:graph:]NC\"pI[:punct:]rmWd5y^p+gUP]YYYYYYYYYYYYYYYYYYYY~{,-62}{,200}{-109}{}+333333333333333333333333333333{}p)^.hhhhhhhhhhhhhhh", 1, 0 },
+ { "[000000(\?mmsx:00000000000000000000000)M]]]]2*`[^]QQQQQQQQ(\?<=QQQQQQQQQQQQQQQQQQQQQQQ])\"<h\?", 0, 0 },
+ { "[^((<g(\?>5j[bbbbbbb(\?{bb)o{}3(\?imxisx:E]g})YYYYY[:blankcntr(\?#l:].(()w264[:ascii:]^)[:ascii:]G)&(n {^PGn[:xdigit:])nv_e|]{-103,30}", 3, 0 },
+ { "[^(([(\?!{}@[^HCO[[^^D[|]{,-49}][:xdigit:]]c`4[:ascii(\?<!:])$66666666666)*)]PP$Z[:alpha:]{,-235}UK],(aT/+6rbMqs60EloA)[:g(\?isx:raph:]!)]z$o{-24,}x1E[:blankcntrl:]ZDFvk", 1, 0 },
+ { "[:blank(\?=cntrl:]US@.!\"[:digit:]*E)$16182", 0, 0 },
+ { "[-{}x{3772[}][:(\?<=xdigit:][:u(\?#pperword:].W)aD)<pfN<b=C|-{-38}EZdOP|!>ggggggggggggggg\\\\\\\\\\\\\\\\\\\\\\\\\\Ef[:space:]\?][:ascii:]{21,}", 0, 0 },
+ { "([:xdigit:]W[:u(pperword(\?::]jS [:upperword:]*)[:alpha:]nnnnnnnnnnn))-148}SSu", 1, 0 },
+ { "([^(\?!\?)[(:upperword:])Bx^x$~lCr6*)6", 1, 0 },
+ { "[{,-78}Y[:xdigit:][^s(\?>]P[:space:])]YYYYYYYYY[:punct:][:alnum:][:blankcntrl:]", 0, 0 },
+ { "([MMMMMM(\?(MMM)M(\?<=MMMMMMMMMMMMMMM[^M)]en][:punct:]-[:alpha:]))Nr[:space:]", 1, 0 },
+ { "~=1([^(\?=(\?:l){}])j{-44}{-18}[^u[:graph:]]{-187,}[:xdigit:]w[:alpha:])", 1, 0 },
+ { "[ccccc(\?>c(\?{cccc[ccccwetoCei+)w&-+{,-142}[:alpha:]PP66io4(|zkA=],,,,,,,,,,,,,,,,,,,,,Lx5Cx{d2bb}]{188}U~~~~~~~~~~~~~~~~~~~~~~~})", 0, 0 },
+ { "Q|0\"[:d(\?:igit:]^{,-174})", 0, 0 },
+ { "[^[(\?>rh])]", 0, 0 },
+ { "[ees{{{{{{{{{{{{{{{{{bbbbbbb4`ml******(\?=****+])", 0, 0 },
+ { "((hdG[((\?<=:dig(it:])[^[:alpha:]$(\?sxi:)x{11390}[(\?{:upperword:]~)i 8[:blankcn[trl:(])]+{,-183}Zqp", 2, 0 },
+ { "Dd{D8`+DW={-[53,1(\?<=71}])", 0, 0 },
+ { "[:(\?(alpha:][:punct:])", 0, 0 },
+ { ".LLLLLLLLLLLLLLLLLLLLLLLLLLLL{}pP[:punct:]x0CZ{30,}!!!(!!!!!!!!!!!!!!!!!!!!!!!!!==@77.%[:graph:]D)", 1, 0 },
+ { "[^[^[[r(\?#]){-237,}RRRRRRRRRRRRRRRRRRRRRRRR[^Rll(\?!(\?{lllll]", 0, 0 },
+ { "()*ooooooooooooooooooooyyyyyyyyyyyyyyy", 1, 0 },
+ { "{,4(}D)JJJJJJJJJJJJJJJJJJJJJJJJJ", 1, 0 },
+ { "((b.D{}[:al[pha:]{64}]{})==========================[:alnum:]h>77b)!Ab", 2, 0 },
+ { "([^[^[^oooooooooooooooooooooo][:space:][:punct:]PeniKe*~$g\?${>[:lowerprint:]w))))))))))))))){}yyyyyyyyyyyyyyyyyy]pP.|QhZ]{,190})sssssssssssssr+=[:blankcntrl:]WWWWWWWWWWWWWWWWWWWWW", 1, 0 },
+ { "([*(\?{})hhhhhhhhhhhhhhhh]G{,-170}QdErrrrrrrc-jjjjjjjjjjjjjjjjjjjjn+{-130,-10})PpDS@Bee", 1, 0 },
+ { "([:b(\?=lankcntrl:]))T[:alnum:]{-224}ywt", 1, 0 },
+ { "([633(\?<=333(\?<=3333333333(333333)^\?]aGA)[:digi(\?>(\?{t:])$[[:space:][:xdigit:])|8T\?',_{171}{}{113}b\?5kAv0/7{})`huh>xM]C8pYRz]s$Eu08)", 1, 0 },
+ { "-(pP)[:alnum:]$^", 1, 0 },
+ { "[^x(\?{{17681}]P*)U(_t/8E_\"iN})3333333", 1, 0 },
+ { "(([^([[r(\?=[[^^*kx$][:alpha:]:::[:::::[^[^::::::::((\?{\?{::]).^p[:space:]}){52}{}]W{}fn", 2, 0 },
+ { "[:(\?>punct:]Ef[:xdigit:]x{c07b}{-50}Z{129,}YL1T`\\A)x[:punc(\?=t:]e[:xdigit:]2c6E46Y)+n ", 0, 0 },
+ { "[^(\?!{,-79}[:punct:]'|}>,)][:blankcntrl:]{-118,-231}{-119,-50}:XXXXXXXXXXXXXXXXX-~{}$txlB)3KFL", 0, 0 },
+ { "[^(([^fccccccccccccccccccc(\?<!ccccgQeKMfKzz]X$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$[:l(\?<=(\?<=owerprint:]))s{-97}{}))EUi${,-132}'{79}---------{,-93}77777777777777777[:lowerprint:].:H)[:punct:]nnnnnncP\?s1:dGed{186}N@pppppppppppppppppppppP{-212,-110}[:space:][:lowerprint:]$S}7{-112,164}-*.{-184,}OOOOOOOOOO]f\?", 0, 0 },
+ { "(([\?#(\?>)])qcU$Q7|82\?{})", 2, 0 },
+ { "[^yyyyyyyyyyyyyyyyyyyy(\?#yyyyyyyyyyya][:ascii:]\?)", 0, 0 },
+ { "(([((\?{)EEEE(\?<!EEEEE(\?:EEEEEE~)}){244,}QQQQQQQQQQQQQQQQQQQ(\?>QQQQQQ(\?!QQQQQ][:digit:]\?))99999999999999)[:digit:][:upperword:]b))PP{}{}", 2, 0 },
+ { "(K(c=B))", 2, 0 },
+ { "(G`*s\?b[:g(raph:]))", 1, 0 },
+ { "[^[([[[*QQQQQQQQQQQQQQQQ(\?=(\?=QQQQQQ(\?<!QQQQQQQQZddddddddd((\?{\?>ddddddddddc{22,}iiiiiiiii(iiiiiiiiiiiiiii(\?#iiiiiii[^i))\?\?\?\?\?\?]WWW)[:lowerprint:])]{-60,202}+[:upperword:]f[:xdigit:][:alnum:]{,-214})1~~~~~~~MMMMMMMMMMMMMMMMMM.", 0, 0 },
+ { "({-102,})A.", 1, 0 },
+ { "[((((\?<!(\?[^>(\?#\?()))p\"JD.{}(\?>)))((\?{l(\?<=).'053][:xdigit:]N+)})]WWWW%[:asc(\?{ii:]}))B[:alnum:]X){}s[:digit:]", 0, 0 },
+ { "x7&{139}WWWWWWWWWWWWWW[:blankcntr[^(\?<!l:]-71]\"{-167}cqkI)[:dig[^it:]{}{}[:digit:]*[:punct:]-[l11111111111111111(\?(111111111{175,-216}~[:alnum:]`+X1F)vCpWSp(\?>~[^n@f`````````````)````````P])Y,N{}{}]{}pXF@)", 0, 0 },
+ { "G[([(\?(^)$])P]^[:alnum:]){,-48}[:blankcntrl:]{}", 0, 0 },
+ { "[[^[^f(\?=f(\?<=fffffff[^fffffffff[^fffffffff(\?<=fff]){-194,150}fx{e5a4}V", 0, 0 },
+ { "9[:xdigit(\?{:]})", 0, 0 },
+ { "[^([[(\?>()$xxxxxxxxxxxxxx[xxxxxxxxxxxxxxxx((\?=aA)s13]])pp[(\?>pppppppppppppppp|{}){20,}]b)]{-179,183}{-204,}[:ascii:])]-11111111{}{,132}qooooooooooooooooooo{}${}|9t", 0, 0 },
+ { "([^[{}]\"[^6]*-{,-106}{}u]BR~8WG,U-)[:blankcntrl:]", 1, 0 },
+ { "[''''''''(''''''''''z])c", 0, 0 },
+ { "[^[(\?>])[:alnum:]r[:alnum:]+{,215}D]", 0, 0 },
+ { "([({,127}7Qr(\?:z)pPNev%}(\?msximsx:4(\?<!){}&.D5555(\?<=55555555555555555555i$[:xdigit:]){,-157}[:graph:]U[:punct:]nn(\?=nnnnnnnnnnnn(\?>nn(\?:nnnnnnnn_U{}]E)):^oooooooooooooooooooooooooooo)", 1, 0 },
+ { "[^(\?#)(\?<!k2z]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]BW[:alnum:][:graph:]{157}Y]s$C)[:graph:]{,-189}", 0, 0 },
+ { "$+CCCCCCCCC[^CCCCCC(\?<=Ca=]r{-81}[:alpha:][:alpha:])E=", -1, 0 },
+ { "[(((\?=\?{([^(\?<=)])>!(([:alnum:]{252}{}})ffffffffffffl){}A2r\?~ImE\"[:punct:]){}[:digit:]", 2, 0 },
+ { "([:blank[cntrl:]].t^P)", 1, 0 },
+ { "[^[(\?:X])|rrrrrrrrrrrrrrrrrrrrrrrrrr*P]Q", 0, 0 },
+ { "[[[^(\?{((\?<!))s})(\?<!A){14}(\?:L*+TTTTTTT]U{[^-12([\?!,}\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?)Y`Y)L]|]]|]", 0, 0 },
+ { "hkXzf',]yP$+[:u(pperword:])", -1, 0 },
+ { "(#[:blankcnt(\?iximsx:rl:])$QQQQQQ{}[:digit:])\?A", 1, 0 },
+ { "(B{-34,})*{,106}", 1, 0 },
+ { "[(\?{:graph:]})", 0, 0 },
+ { "((){}{,63}[:punct:]^t[:space:])^17737", 2, 0 },
+ { "([^[SSSSSSSSS[SSSSSSSSSSSSSSS[([[[{38,}]Jn][:alpha:]])])$'", 1, 0 },
+ { "[^({}{95})B{1(\?>15}]x{f779}ZZ,Wo)O[:alpha:][:lowerprint:]{81,228}Q[:upperword:]", 0, 0 },
+ { "[[^[^()n[[[[[[[[[[[[^[[[[[[[[[[(\?: G)(\?{K![^m) j(\?:C|((\?:n*Xlaa908:n$m,))[:xdigit:]x(\?{{1a5cd}pppppppppppppp(\?(pppp)p(pQ)))ddddddddddddddddddddddddddddddd]q[:alnum:(\?{]Ga})\?})@[:lowerprint:]{,169}[:blankcntrl:][:graph:]]n{-76,}|U\"{,-54}t]I{}{-64,-232}]\?].\?{-111,227}) @hFp\?j=H$Wbu<{,209}De{,145}{206}-})[:blankcntrl:]", 0, 0 },
+ { "[^[^(LLLLLLLLLLLLLL[^L[L[:alpha:]3{,189}(\?#(\?>n){}^EXXXXXXXXXXXXXXXXXXXXXXXXX]c*)^r=$WWWWWWWWWWWWW", 0, 0 },
+ { ")w###################", 0, 0 },
+ { "{,121}[:d(\?(i)git:])E\?[:punct:]LLLLLLLLL[:ascii:]+", 0, 0 },
+ { "([]]]]]]]]]]]]][:space:]Jrt3o.]b)pwwwwwwwwwwwQfm~", 1, 0 },
+ { "[+-{,-120}*(\?!()t*(\?(\?{>G)F)yd]V{}f<\?}){245}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[:upperword:]", 0, 0 },
+ { "(DDDDDDDDDDDDDDDDDDDDDDDDDDDDDc[:space:][:pu[^nct:]{-11,12}[:ascii:][:alpha:]{,155}P])", 1, 0 },
+ { "()ggggggg{-136,-21}", 1, 0 },
+ { "([^((\?<=U\?)(\?=^^^^^^^^^^^[^^^^^^^^^^^^^///(\?#//[////////////////////(\?()#######b+]$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$^[:digit:])\\U]Q8@}4d)\\U", 1, 0 },
+ { "A[:graph(\?::])-mo=U[:upperword:]ttttttttttttttttttttttttttt", 0, 0 },
+ { "[^(((\?=\?im-m(sx:)c~~[^~~~~~~~~~~~~~(\?>~~~~~~~~~~~~~SSSSSSSSSSSSSSSSSSSS]{51,}[:digit:]{,-179}N))kk[kkkkkkkkkkkkkkg$)[(\?::punct:]zWl)]|)*", 0, 0 },
+ { "[((\?=()+A)][:graph:]x0B)[:graph:]", 0, 0 },
+ { "(nR%B[:blankcntrl:]C=|en-[:digit:]n[:graph:]HHHH[HH]D\?%[:digit:]MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM.z(oF9zW8A7cfff(f))-[:blankcntrl:][:blankcntrl:]A[:digit:])D{,-243}", 3, 0 },
+ { "([[()]]{,-251(})\?L)uw@", 2, 0 },
+ { "\"|{(,-144})A.ooooooooo(ooooooFFFFFFFFFFFFF\?)n{,-18}", 2, 0 },
+ { "([^([(([[^([000000[0(0(\?!0(\?=0000000])45|E]", 1, 0 },
+ { "[B[[[[[[[[[[[|{}*oKqv%(\?<=wsQ{1pMeK1^6%nLNqi<@ge][:punct:]= M@* D|NwL\\-117\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"~Qnd]h.O\"01x:[:alpha:]^){}D}\"", 0, 0 },
+ { "([[RRRRRRRRRRRRRRRRRRRRRRRRRRRRxpSrx{7d79}*oJ2`Ft{n1,3g:1H@bT$D &[n/Cg)=ld@Ir{Fk>*4*`(\?>````````````````````(\?:`````.....................]]{,246})7 \"F4[^F|/g)]+e`rw@{,-69}H)", 1, 0 },
+ { "([(\?<=)X[:digit:]PP.[(\?#:((\?#\?#graph:])[:digit:][Q+)(N][:alpha:]]f)[:graph:])+Elllllllllllllllll[:digit:]=)pP{uU-20bzY|ZKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKt<c", 1, 0 },
+ { "[^(([^$(\?:(\?#w)[(\?::punct:]]d{-149,}[:ascii:])[:blankcntrl:]@@@@@[@@@@@@@@@@@@@@[:graph:][:xdigit:]O[:alpha:]2$-[:graph:])[:lowerprint:]-\?#S[:blankcntrl:][:alnum:]){-77,}]d[:digit:]N5v+Sqqqqqqq^% -I4]*.)^[:alnum:]JDfjMRU7ttttttttttttjjjjjjjjjjjjjjjjjjjjjjCCCCCCCCCCCCCCCCCCCD{,21}{0,67}[:graph:]{,208}B", -1, 0 },
+ { "(%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[:ascii:])i{}[:lowerprint:]epxxxxxxxxxxxxxx[:lowerprint:]r-", 1, 0 },
+ { "([(^w(\?!)()])-s", 1, 0 },
+ { "[aIIIIIIIIIIIII(\?imsxims(\?=x:IIIIIIIm^NXXXXX(\?!(\?isximsx:XXXXXXXXXXXXXS0]F)z))+rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr{,-237})ZZZZZZZZZZZZZZZZZZZZZZ", 0, 0 },
+ { "(Z)[:alpha:]", 1, 0 },
+ { "U#Z(=)", 1, 0 },
+ { "([:lowerprint:][:punct:])1cVb*[:xdigit:]&&&&&&&&&&&&&&&&&&&&&&&&O", 1, 0 },
+ { "()~K`3/[^*h[]G6[:upperw(\?()ord:]w)[:punct:]]{}", 1, 0 },
+ { "[[[]V[:digit(\?>:])|l*KKKKKKKKKKKKKKKKK,,,,,,,[,,,s.{148,}P33333][:lo(\?<!werprin(\?!t:]ZZZZZZZZZZZZZZZZZZZZZZZ]{,-229}{-160,}){,-211}XPPP].{}z[:alnum:][:alpha:(\?=]t{166,}uuuuu6]i*p(m))[:space:]E|S", 1, 0 },
+ { "[^(h(\?(\?({#2})(\?(\?#>Q){,57}%[:digit:]\?\?\?\?\?\?\?\?\?\?.[)]]d{)-49,}f)^O{,68})\?C", 0, 0 },
+ { "(}u])18621", 1, 0 },
+ { "[:as(\?=cii:][^(\?=)(S-{.F-[:punct:]3-105^[:lowerprint:]111111111111111111111111---)][:alnum:][:ascii:]JJJJJwHSk", -1, 0 },
+ { "[^3>>>>>>-sZ^^^^(\?>]Y[:di(\?(\?imxim:#git:]{-158,-102}[:punct:]{}{87,})))[:upperword:]", 0, 0 },
+ { "[(\?<!^r]$W){}*[:alpha:].[:digit:]", 0, 0 },
+ { "[:ascii(\?::[^])X]-", 0, 0 },
+ { "[([^]Z)[:upperword:]N{}*[:graph:]*^", 0, 0 },
+ { "([[(\?#^[(:graph:]]){205,}[:gr(aph:]T%]^MMMMMMMMMMMMMMMMMMMM){) <v\\[:digit:])", 1, 0 },
+ { "[^Y.h~b(\?<=~P{(\?=169,65}\?[^\?\?\?\?\?\?\?\?\?[\?\?\?\?\?\?\?\?\?K\"s`[yT7oP[:alpha:]{})]zrrrrrrrrrrrrrr)]KKKKKKKKKKKKKKK[:digit:]S][:lowerprint:][:digit:]", 0, 0 },
+ { "(s)", 1, 0 },
+ { "[u(\?!uuuuuuuuuuuuuuuuuuuu[:digit:]{,48}[:graph:]WL[:alnum:]]v=_)VN>{AjBBBBBBBBBBBBBBBBBBBBBBB[:upperword:]`'W)", 0, 0 },
+ { "[^([[()DN1[^][|]\?]{-104,}])[:space:]][:lowerprint:]r[:alpha:].DU", 0, 0 },
+ { "[^((33333333333333333333333(\?<=3333333D))kkkkkkkkkkkkkkkkkkkkkkk[k[:alpha:]])]X+", 0, 0 },
+ { "[({,-17})[@e{220,(\?#41}])]]{-213,-225}", 0, 0 },
+ { "[[^(\?#[(\?:^[[(\?(^]))]])]vvvvvvvvvvvvvvvvvvvvv{,96}|m]{-79,248}[:alpha:])", 0, 0 },
+ { "([[(\?imsisx:^}$,-[:al(\?>num:]Xqqqqqqqqqqqq{-185,154}]b#+T){-241,})A{-27}[(\?<!:lowerprint:]X)[:punct:]ME-]+BBBBBBBBBBBBBBBBa|{-40}M8mhgD 0HU]{16})", -1, 0 },
+ { "[^(\?>([\?()(\?#))]--R1rk^UnP.[(\?!:digit:]])^)[:upperword:]{}0000000000000000000000000000000~U{-139,-19}z<L-228", 0, 0 },
+ { "()-:=3uE$[:alnum:]bP%{-210,}", 1, 0 },
+ { "(U)7777]]]]]]]]]]]]]]]]]]]]]]]]]]]]]c::AA[:alpha:]{,3}f1{NzH@3lTf{}{", 1, 0 },
+ { "[C{(\?>})RR(\?=R<]p'N~&.-})6]", 0, 0 },
+ { "[^\?[^(\?(lFt]).[^7Q-])kkkkkkkkkkkk]XTFy\"1Deiv!,'xVK", 0, 0 },
+ { "[^$[^[:xdigit:](\?{*{245,99}h8v(\?!)]]u)Z[:punct:]})[:alnum:]+|[:blankcntrl:]u{}[:lowerprint:]+bBJ4+k-v{-116}", 0, 0 },
+ { "S)f{,180}[:graph:]&{12,244}", 0, 0 },
+ { "(([[(.()[^^{80(\?>(\?<=,235})ddddddddd[^ddddddddd(\?<=d.__B{36}````````````````(\?:```(\?>```````,,,,,,,(\?:,,)P$U,[:xdigit:])zzzzzzzzzzzzz]UUUU[uB]n<&[(:ascii:].][:alnum:])\?S]{})d{138,}s9========[:lowerprint:]]OOOOOOOOOOOOOOO|yyyyyyyyyyyyyyy$LZ[:lowerprint:]EEEEEEE[:ascii:][:punct:]VpP^{-48}D){,46}x))2P))a[:lowerprint:]r", 2, 0 },
+ { "[^(((\?<!):())PPPPPPPPPPPPPPP(\?=[PPPPPPP(\?{PPPPPPPP$)})77777777777777777]{,-57}::::::::::::(::::::::::::::::)]g{89}__________________[:xdigit:]l[:punct:])N", 1, 0 },
+ { ":02-k\?p3I7aEhJ\\265-[:space:]pP[:space:]x0F[:alnum:]aM4[:lowerprint:]sA@@@@@@@@@@@@@@@@@@@@@@@@@@@@", -1, 1 },
+ { "a[:upper(\?{word:]})X{-173,}-2F[:lowerprint:]", 0, 0 },
+ { "u,w<g*Q002S{,130}{239}[:lower(print:]cr{-165,}#$k<L/&)[:blankcntrl:]aaaaaaaaaaaaaaaaaaaaaa[:ascii:]", 0, 0 },
+ { "(xFA^{-161,93})U[:xdigit:]", 1, 0 },
+ { "[^(\?=]{})mE`", 0, 0 },
+ { "[[((\?(\?#:alnum:]])x6CS[:digit:]{-197,}.)N", 0, 0 },
+ { "[^(\?![])C*[:upp(erword:])-176]", 0, 0 },
+ { "[[^[[^[55555555555555555555555555(\?>555(\?<!555)S][]]A[:l(\?>owerp(rint:]])]*", 0, 0 },
+ { "Au)khgzAfXIZoZ=g[:digit:]){,186}Upvf=x<]Tbd5Rq\?.", 0, 0 },
+ { "b{-176,}B^[:bla(\?(<!nkcntrl:]{-6,133}#B :)<<<<<<<<<<<<<<<<<<<)[:alnum:]$}}}}}}}}}}}}}}}}}}}}}}}[:xdigit:]tw", 0, 0 },
+ { "(4IIIII(IIIIIIIIIIIIIIIII{})W{-152,-238}){,-56}^{-142,}", 2, 0 },
+ { "[^([[(\?(\?(!)>>>>>>>>>>>>>(>>>>>>>>D)Ix{(1(\?imxmsx:762)c}))A)[[[[[[[[[[[[[[5Rp]DDDDDDDDDDDDDDDDDDDD]Us+\\w[:digit:]{-47}[:xdigit:][:blankcntrl:])ddddddddddddddd[^ddddddddddddd[:digit:]|]]*{-165,-230}{-212}{53,}]\?", 0, 0 },
+ { "[^[^]]|[:(\?:alnum:])}}}}}}}}}}}}}}}}}}}}", 0, 0 },
+ { "VVVVVVVVVVVVVVVVVVVVVVVVVVVV[:d(i(\?#git:])){{{{{{[:digit:]ZfQ55555555{}Z", 0, 0 },
+ { "[L][:blankcnt(\?((\?=rl:(\?=]){-35,[^}){)eJb>>>>>>>>>>>>>>>>>>>>>>$ [:xdigit:]l0Tv2Tw2@C[:space:]Zc/{*)>]N3j~.dMBBBB", 0, 0 },
+ { "[[^(\?>(([]))])[:graph:]]{65,}as#Q:lQ", 0, 0 },
+ { "[^[fPPUUUUUUUUUUU(\?#UUU[^UUUUUU(\?<=UUUUUUUUUGGGGGGGGGGGGGGGGGGG((\?{\?=GGGGGG.MK))+]+)&UxFW)rwv\?@D.", 0, 0 },
+ { "{-(60,})m", 1, 0 },
+ { "b[(])^w", 0, 0 },
+ { "[][^qVs(\?:(p])X)\?'", 0, 0 },
+ { "()8", 1, 0 },
+ { "(t[:punc[^t:(\?{][:blankcntrl:])})[^8\?]z*]", 1, 0 },
+ { "[:lowerprint:])[:graph:]lppppppppppppppppppppppppppppf", 0, 0 },
+ { "[:alph(a:])[:ascii:]g +z-Bc-U{,%Gk", 0, 0 },
+ { "u[:graph:(\?=]*)W:::", 0, 0 },
+ { "([:alnum(:])l)", 1, 0 },
+ { "[[[}}}}}}}}(\?<!}}}}}}}+(\?{),,,,,,,,,,,,,,(\?!,,,,,,,,]99999999999&R[:ascii:]ZZZZ-{-10,}{96}Ed*][:graph:])]}){}{}G{-9,}", 0, 0 },
+ { "([^[{}]]Z[[^:graph:]{-47}55555555555555555555555555555[:ascii:]s]6,$:3qAew1Y)+)[:punct:]", 1, 0 },
+ { "[[[[[([[[[[[[[[[[[[[[[[[[[[[[[8!1i]')", 0, 0 },
+ { "([((\?(\?#>)(\?{,)At]%M9FSq5)EB", 1, 0 },
+ { "(}````````````````(``{210,})[:(\?#space:]P[:digit:])PP.{-227,}$pK~mm ImR|{,51}[:alnum:]<)[:alpha:]", 2, 0 },
+ { "[^(\?<=])[:digit:]", 0, 0 },
+ { "[^'''''''{(\?:178,}e{,16}$QQQQQQQQQQQQQQQQQQQQQQQ$])", 0, 0 },
+ { "[^(\?>@K*)(\?#d18]{78,}B)[:digit:]{-193,}=wg{,59}", 0, 0 },
+ { "[^.{156,}!(\?<=!!!!!!!!!!!!!!(\?{!(\?(!!!!!!!!!!!!!)})TTTTTTTTTTTTTTTTTTTTTTTTTTTTT[^}}}}}}}}}}}})}}}}}}}}}}}}}]]){}^L#%-{}FC", 0, 0 },
+ { "(eeeee{-169,-100}-fa[:upperword:]N)$Nellllllllllllll", 1, 0 },
+ { "[[(\?!())\?[(\?!:alnum:]e{,28}M])[:punct:]CCCCCCCCCCCCCCCCCCCC]{-150,}{-167}", 0, 0 },
+ { "[[@[@(\?#@[@]P]Z{')]{-186,117}]+)7f-", 0, 0 },
+ { "\\Q+kD}]AEM)u ", 0, 0 },
+ { "([(\?{(\?=:::::::::::::&){,210}]^})P{-31,}8[:space:]C[:alnum:][:a(scii:]z|[:upperword:])[:alnum:][:graph:])zr~Zk", 1, 0 },
+ { ".[:space:]e[:g(\?{(\?{raph:]})})@@@@@@@@@@@@@wb|~k", 0, 0 },
+ { "()ooooooooo\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"[:graph:]", 1, 0 },
+ { "[^64h(\?(@Eyw][:xdi[git:]pP%%%%%u(uuu[:up[perword:]`8Utdh{)}]]))lW[:punct:]W.hhhhhhhhhhhhhhhhhhhhhhhh'm<<}O8`ZXtG.$", 1, 0 },
+ { "BPP[:digit:]bbbbbbbbbbb(bb)S+[:alnum:]", 1, 0 },
+ { "um.[:ascii((\?#\?!:])*)+KKKKKKKKKKKKKKKKKKKKKKKKKS.=<Bf", 0, 0 },
+ { "", -1, 0 },
+ { "(()$[:lowerprint:][:s[pace:]2]bbbbbbbbbyoooooooooooooooooo*{39,}$')qV`AcH>,eDl", -1, 0 },
+ { "(()[^])e{-241,}", -1, 0 },
+ { "()[:alpha:]rliiiiiiii[:alnum:]Mb*QW9N.>\?{115,}&u*j", -1, 0 },
+ { "()[]p", -1, 0 },
+ { "(I[^]pfL)$[:punct:]", -1, 0 },
+ { "([])>>>>>>>>>>[:alnum:]", -1, 0 },
+ { "([])O\\\\\\\\\\\\\\fffffffffffffffffffffff=s6jCZy/b+ir2'*{151,}", -1, 0 },
+ { "([])nnnnnnnnnnnnnnnnnnnnnnnnnn[:xdigit:]^N$f", -1, 0 },
+ { "([]M)[:lowerprint:]a(pg$Z[:punct:])77777777777.", -1, 0 },
+ { "([]XXXXXXXXXXXXXXXXXXXXXX-===========)", -1, 0 },
+ { "([]lkX{-224}[:blankcntrl:]$gPKIZlSC#F@XX I'^}{234}yZm)uuuuuuuuuuuuuuuuuuuuuurS", -1, 0 },
+ { "([^0kYkg9])IIIIIIIIIIIIIIIIIIIIII/{(192,-118}l+FoSD6\?A)c[:xdigit:]`````````````````e-{-4,-170}x{4620}Z[:upperword:]", -1, 0 },
+ { "([^[^[^()(\?>){}B]XYF+#[:alpha:]{-85((,-55[^}t]n).{,-33}]](bQJ!|O+{175,})RFh)Z+^.{137,}:VpP[:alpha:]-MceqVVkkkk(kkkkkkkkkkkkkkkkkk)\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?{-115,-67})``````````````````````````````", -1, 0 },
+ { "([^]EzU[:alnum:]+^^^^^^^^^^^^^^^^^^^)[:xdigit:]HHHHHHHH$66666666666666666666666666666666UUUUUUUUUUUUUUUUUUUUL{}iiii{-76}X", -1, 0 },
+ { "([^]~~~~~~~~~~{240,})]NOp", -1, 0 },
+ { "(sb)[:digit:]VVVVVVVVx{9569}52,|]", -1, 0 },
+ { "(x{19762}){}", -1, 0 },
+ { "-[:xdigit:][]", -1, 0 },
+ { "121|", -1, 0 },
+ { "141[:xdigit:][:lowerprint:]{24}{59,191}[:digit:]/", -1, 0 },
+ { "G[^],,,,,,,,,,,,,+\"DiX", -1, 0 },
+ { "Gm(ho9:\"8{-188,-200}Z[:blankcntrl:]{,171}\?\?\?\?\?\?\?\?\?\?\?[:blankcntrl:]LLLLLLLLLLLLLLLLLLLLLLL{}^[:graph:][:blankc(\?#ntrl:])w", -1, 0 },
+ { "N\"\"\"\"\"\"\"-------------------------|[:alnum:]AAAAAAAAAAAAAAAAAAAAf\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?", -1, 0 },
+ { "U{-30,}^\?\?\?", -1, 0 },
+ { "W^*04rAY(Ee*>[^o3[]]_)", -1, 0 },
+ { "X[^]}*C[:alnum:]", -1, 0 },
+ { "[${,-3}]+^\?[|x8A|][:space:]'''''['''''JJJJJJJJJJJJJJJJJJJJJJJJJJJJJyl}.Y7G]", -1, 0 },
+ { "[()&[&&&]\?\?[\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?pg%k8ug`Wqk4|NR{h[CK5Ez=]jHpQw&`{:]{,91}D", -1, 0 },
+ { "[(\?#(\?:)[)([\?>)(\?>(\?:[:alnum:])]G]{85}[^)w]N]gYrUs|", -1, 0 },
+ { "[(\?<=)[:digit:]\?]{152,}VR|", -1, 0 },
+ { "[****(\?>**********(\?<!*******Q)Vr){[^25,}*:FFFFFFFFFFFFFFFFFFFFFFFF(\?{FFFF(({}D]|", -1, 0 },
+ { "[:ascii:]+{124,}:*]\?$-{92}D[:lowerprint:]`````````````````````", -1, 0 },
+ { "[:ascii:]\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?A<", -1, 0 },
+ { "[:blankcntrl:]p\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?$\?TTTTTTTTTTTTTTTTT[:ascii:][:upperword:]", -1, 0 },
+ { "[:punct:]{254}DDDDDDDDDDDDDDD@[:alpha:]Z\?\?-----R", -1, 0 },
+ { "[:upperword:]J\?\?nqCAdfyW5", -1, 0 },
+ { "[:upperword:]{-39}|", -1, 0 },
+ { "[:xdigit:]^\?", -1, 0 },
+ { "[Z*e ]NdmP\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?", -1, 0 },
+ { "[[:punct:]q]ex{15625}-", -1, 0 },
+ { "[[[^([^L((\?{b(\?=C\?]-134{,-207}[:ascii:]Hz}XIz}|", -1, 0 },
+ { "[[^V(\?:(\?<!(\?>))TTTTTTTTTTTTTTTTTTTTTTT)[:punct:][:digit:]]GGGGGGGGGGGGGGGGGGGGG,]|.{-224}{96}{239,}1", -1, 0 },
+ { "[[^^PP]{,-222}{182}{141}]zFD}-.", -1, 0 },
+ { "[] Hn&[:xdigit:][:upperword:]f", -1, 0 },
+ { "[]$.B", -1, 0 },
+ { "[]&&&&&&&&&&&&&&&&&&&&&&&", -1, 0 },
+ { "[]()[:xdigit:]er063{132,140}$", -1, 0 },
+ { "[]+1434", -1, 0 },
+ { "[]-", -1, 0 },
+ { "[]-#yyK", -1, 0 },
+ { "[]-(S$5)AxbdTKO[:alnum:]", -1, 0 },
+ { "[]2883", -1, 0 },
+ { "[]2dhd-[:alpha:]sssssssssssssssss55555555555555555555555555555555Z[:punct:]", -1, 0 },
+ { "[]4", -1, 0 },
+ { "[]44444444444444444G", -1, 0 },
+ { "[]\?", -1, 0 },
+ { "[]A", -1, 0 },
+ { "[]Gap8bc", -1, 0 },
+ { "[]OOOO", -1, 0 },
+ { "[]PP", -1, 0 },
+ { "[]QQ", -1, 0 },
+ { "[]WaFaGO,o", -1, 0 },
+ { "[]Z", -1, 0 },
+ { "[][:alpha:]|[:digit:]Ls$I-Ff~+xA3e", -1, 0 },
+ { "[][:ascii:]-218", -1, 0 },
+ { "[][:ascii:]N}}}}}}}}}}}}}}}-{137,}8682", -1, 0 },
+ { "[][:lowerprint:]Ur", -1, 0 },
+ { "[][:space:]15097", -1, 0 },
+ { "[][:xdigit:]", -1, 0 },
+ { "[]dpSSSSSSSS", -1, 0 },
+ { "[]e13768", -1, 0 },
+ { "[]gT", -1, 0 },
+ { "[]h", -1, 0 },
+ { "[]n", -1, 0 },
+ { "[]vvvvvvvvvvvvvvvvvvvvvvvvvv*[:xdigit:]", -1, 0 },
+ { "[]{,-212}1111111111111111111C3821", -1, 0 },
+ { "[]{-128,}hc", -1, 0 },
+ { "[]{-181,}&[:xdigit:].\?}}}}}}}}}}}}}}}}}}}}}}", -1, 0 },
+ { "[]{}F&}i`7|ZAH", -1, 0 },
+ { "[^(\?())u{196,}pP][r^ndddddddddddddddddddddd]{31,246}\?J", -1, 0 },
+ { "[^.ii.1-S]lwwwwwwwwwwwwwwwwww[^wwwwwwwwwwwwww[:alnum:]DOpP+<N][^]44{179}{-194,56}", -1, 0 },
+ { "[^2[:alnum:]]\?t\?\?", -1, 0 },
+ { "[^[((\?{[^^<<<<(\?(\?<!{)})(\?<!]{,184}{-213}|", -1, 0 },
+ { "[^[^[]\?{89,}PPsvf{[:space:]]]vd{161,}", -1, 0 },
+ { "[^[^].]+{0}s", -1, 0 },
+ { "[^]${}", -1, 0 },
+ { "[^]([:punct:]),%[:xdigit:]w^0\?{-233}", -1, 0 },
+ { "[^]-", -1, 0 },
+ { "[^].^", -1, 0 },
+ { "[^]6743", -1, 0 },
+ { "[^]JD", -1, 0 },
+ { "[^]N=[:upperword:]zzzzzzzzzzzzzzzzz.", -1, 0 },
+ { "[^]OLz_6", -1, 0 },
+ { "[^]PP[:digit:]0eBEx=", -1, 0 },
+ { "[^]SHzuKp", -1, 0 },
+ { "[^][:upperword:]{111}-TpmXw", -1, 0 },
+ { "[^]^''''''''z{-73,}", -1, 0 },
+ { "[^]^{,141}e", -1, 0 },
+ { "[^]aaaaaaaaaaaaaaaaaaa{-98,43}", -1, 0 },
+ { "[^]f", -1, 0 },
+ { "[^]l", -1, 0 },
+ { "[^]n\"Wt", -1, 0 },
+ { "[^]pPZ\?q+m0LJ+", -1, 0 },
+ { "[^]p[:upperword:]L:", -1, 0 },
+ { "[^]q\?{,-18}-", -1, 0 },
+ { "[^]s[:space:(\?<=]$", -1, 0 },
+ { "[^]{,58}t", -1, 0 },
+ { "[^]{255,}JJJJJJJJJJJJJJJJJJJJJJJJJJ", -1, 0 },
+ { "[^]{45}", -1, 0 },
+ { "[^]{W", -1, 0 },
+ { "[^]{}{-22}", -1, 0 },
+ { "[^]{}{}{}[:xdigit:]+", -1, 0 },
+ { "[^]|9{,-108}{}.LVIJJJJJJJJJJJJJJJPP", -1, 0 },
+ { "[^{,-254}]|", -1, 0 },
+ { "[o(\?{(\?<=}[))f++++++++++++++++777777777777777777777777yzPPs]\?\?dRRRRRRRRRRRRRRRRRRRRRRRRRRRR&]>%fffffffffff", -1, 0 },
+ { "aW|", -1, 0 },
+ { "cT{}[]C^r2``tm", -1, 0 },
+ { "kkkkkkkkkkkkkkkkkkkkkkk[:blankcntrl:]|{}3{26,}{151,}[:punct:]JJJlH$gP%(2WUE%%%%%%%%%%%%%%%%%%%%a){ibf{}\?", -1, 0 },
+ { "lZ\?\?\?\?\?\?\?\?\?\?\?-P2eZt[:punct:]", -1, 0 },
+ { "vF3qn[^]N.", -1, 0 },
+ { "wwwwwwwwwwwwww{-176,}275[^]>.UUUUUUUUUUUUUUUUUUUUeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee2$Yd", -1, 0 },
+ { "{-197,223}bf]]]]]]]]]]\?&}/s\?\?~c", -1, 0 },
+ { "{-37,}EpP|", -1, 0 },
+ { "{}@]a[][:xdigit:]z{a", -1, 0 },
+ { "}02|", -1, 0 },
+ { "}}}}}}}}}(}}){}[llll]^N|", -1, 0 },
+ };
+ unsigned int i;
+ int r;
+
+ UNUSED(tc);
+
+#ifdef HAVE_REGEX_H
+ /*
+ * Check if we get the expected response.
+ */
+ for (i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
+ regex_t preg;
+
+ memset(&preg, 0, sizeof(preg));
+ r = regcomp(&preg, tests[i].expression, REG_EXTENDED);
+ if (((r != 0 && tests[i].expect != -1) ||
+ (r == 0 && tests[i].expect == -1)) && !tests[i].exception)
+ fprintf(stderr, "regcomp(%s) -> %s expected %s\n",
+ tests[i].expression, r != 0 ? "bad" : "good",
+ tests[i].expect == -1 ? "bad" : "good");
+ else if (r == 0 &&
+ preg.re_nsub != (unsigned int)tests[i].expect &&
+ !tests[i].exception) {
+ fprintf(stderr, "%s preg.re_nsub %lu expected %d\n",
+ tests[i].expression,
+ (unsigned long)preg.re_nsub, tests[i].expect);
+ tests[i].expect = preg.re_nsub;
+ }
+ if (r == 0)
+ regfree(&preg);
+ }
+#endif
+
+ /*
+ * Check if we get the expected response.
+ */
+ for (i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
+ r = isc_regex_validate(tests[i].expression);
+ if (r != tests[i].expect)
+ fprintf(stderr, "%s -> %d expected %d\n",
+ tests[i].expression, r, tests[i].expect);
+ ATF_CHECK_EQ(r, tests[i].expect);
+ }
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, regex_validate);
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/result_test.c b/lib/isc/tests/result_test.c
new file mode 100644
index 0000000..cfaabb3
--- /dev/null
+++ b/lib/isc/tests/result_test.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <string.h>
+
+#include <isc/result.h>
+
+ATF_TC(isc_result_toid);
+ATF_TC_HEAD(isc_result_toid, tc) {
+ atf_tc_set_md_var(tc, "descr", "convert result to identifier string");
+}
+ATF_TC_BODY(isc_result_toid, tc) {
+ const char *id;
+
+ id = isc_result_toid(ISC_R_SUCCESS);
+ ATF_REQUIRE_STREQ("ISC_R_SUCCESS", id);
+
+ id = isc_result_toid(ISC_R_FAILURE);
+ ATF_REQUIRE_STREQ("ISC_R_FAILURE", id);
+}
+
+ATF_TC(isc_result_totext);
+ATF_TC_HEAD(isc_result_totext, tc) {
+ atf_tc_set_md_var(tc, "descr", "convert result to description string");
+}
+ATF_TC_BODY(isc_result_totext, tc) {
+ const char *str;
+
+ str = isc_result_totext(ISC_R_SUCCESS);
+ ATF_REQUIRE_STREQ("success", str);
+
+ str = isc_result_totext(ISC_R_FAILURE);
+ ATF_REQUIRE_STREQ("failure", str);
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_result_toid);
+ ATF_TP_ADD_TC(tp, isc_result_totext);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/safe_test.c b/lib/isc/tests/safe_test.c
new file mode 100644
index 0000000..f721cd1
--- /dev/null
+++ b/lib/isc/tests/safe_test.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+
+/* ! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/safe.h>
+#include <isc/util.h>
+
+ATF_TC(isc_safe_memequal);
+ATF_TC_HEAD(isc_safe_memequal, tc) {
+ atf_tc_set_md_var(tc, "descr", "safe memequal()");
+}
+ATF_TC_BODY(isc_safe_memequal, tc) {
+ UNUSED(tc);
+
+ ATF_CHECK(isc_safe_memequal("test", "test", 4));
+ ATF_CHECK(!isc_safe_memequal("test", "tesc", 4));
+ ATF_CHECK(isc_safe_memequal("\x00\x00\x00\x00",
+ "\x00\x00\x00\x00", 4));
+ ATF_CHECK(!isc_safe_memequal("\x00\x00\x00\x00",
+ "\x00\x00\x00\x01", 4));
+ ATF_CHECK(!isc_safe_memequal("\x00\x00\x00\x02",
+ "\x00\x00\x00\x00", 4));
+}
+
+ATF_TC(isc_safe_memcompare);
+ATF_TC_HEAD(isc_safe_memcompare, tc) {
+ atf_tc_set_md_var(tc, "descr", "safe memcompare()");
+}
+ATF_TC_BODY(isc_safe_memcompare, tc) {
+ UNUSED(tc);
+
+ ATF_CHECK(isc_safe_memcompare("test", "test", 4) == 0);
+ ATF_CHECK(isc_safe_memcompare("test", "tesc", 4) > 0);
+ ATF_CHECK(isc_safe_memcompare("test", "tesy", 4) < 0);
+ ATF_CHECK(isc_safe_memcompare("\x00\x00\x00\x00",
+ "\x00\x00\x00\x00", 4) == 0);
+ ATF_CHECK(isc_safe_memcompare("\x00\x00\x00\x00",
+ "\x00\x00\x00\x01", 4) < 0);
+ ATF_CHECK(isc_safe_memcompare("\x00\x00\x00\x02",
+ "\x00\x00\x00\x00", 4) > 0);
+}
+
+ATF_TC(isc_safe_memwipe);
+ATF_TC_HEAD(isc_safe_memwipe, tc) {
+ atf_tc_set_md_var(tc, "descr", "isc_safe_memwipe()");
+}
+ATF_TC_BODY(isc_safe_memwipe, tc) {
+ UNUSED(tc);
+
+ /* These should pass. */
+ isc_safe_memwipe(NULL, 0);
+ isc_safe_memwipe((void *) -1, 0);
+ isc_safe_memwipe(NULL, 42);
+
+ /*
+ * isc_safe_memwipe(ptr, size) should function same as
+ * memset(ptr, 0, size);
+ */
+ {
+ char buf1[4] = { 1, 2, 3, 4 };
+ char buf2[4] = { 1, 2, 3, 4 };
+
+ isc_safe_memwipe(buf1, sizeof(buf1));
+ memset(buf2, 0, sizeof(buf2));
+
+ ATF_CHECK(memcmp(buf1, buf2, sizeof(buf1)) == 0);
+ }
+
+ /*
+ * Boundary test.
+ */
+ {
+ char buf1[4] = { 1, 2, 3, 4 };
+ char buf2[4] = { 1, 2, 3, 4 };
+
+ /*
+ * We wipe 3 elements on purpose, keeping the 4th in
+ * place.
+ */
+ isc_safe_memwipe(buf1, 3);
+ memset(buf2, 0, 3);
+
+ ATF_CHECK(memcmp(buf1, buf2, sizeof(buf1)) == 0);
+ }
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_safe_memequal);
+ ATF_TP_ADD_TC(tp, isc_safe_memcompare);
+ ATF_TP_ADD_TC(tp, isc_safe_memwipe);
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/sockaddr_test.c b/lib/isc/tests/sockaddr_test.c
new file mode 100644
index 0000000..fd6494f
--- /dev/null
+++ b/lib/isc/tests/sockaddr_test.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <isc/netaddr.h>
+#include <isc/sockaddr.h>
+#include <isc/print.h>
+
+#include "isctest.h"
+
+/*
+ * Individual unit tests
+ */
+
+ATF_TC(sockaddr_hash);
+ATF_TC_HEAD(sockaddr_hash, tc) {
+ atf_tc_set_md_var(tc, "descr", "sockaddr hash");
+}
+ATF_TC_BODY(sockaddr_hash, tc) {
+ isc_result_t result;
+ isc_sockaddr_t addr;
+ struct in_addr in;
+ struct in6_addr in6;
+ unsigned int h1, h2, h3, h4;
+ int ret;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ in.s_addr = inet_addr("127.0.0.1");
+ isc_sockaddr_fromin(&addr, &in, 1);
+ h1 = isc_sockaddr_hash(&addr, true);
+ h2 = isc_sockaddr_hash(&addr, false);
+ ATF_CHECK(h1 != h2);
+
+ ret = inet_pton(AF_INET6, "::ffff:127.0.0.1", &in6);
+ ATF_CHECK(ret == 1);
+ isc_sockaddr_fromin6(&addr, &in6, 1);
+ h3 = isc_sockaddr_hash(&addr, true);
+ h4 = isc_sockaddr_hash(&addr, false);
+ ATF_CHECK(h1 == h3);
+ ATF_CHECK(h2 == h4);
+
+ isc_test_end();
+}
+
+ATF_TC(sockaddr_isnetzero);
+ATF_TC_HEAD(sockaddr_isnetzero, tc) {
+ atf_tc_set_md_var(tc, "descr", "sockaddr is net zero");
+}
+ATF_TC_BODY(sockaddr_isnetzero, tc) {
+ isc_sockaddr_t addr;
+ struct in_addr in;
+ struct in6_addr in6;
+ bool r;
+ int ret;
+ size_t i;
+ struct {
+ const char *string;
+ bool expect;
+ } data4[] = {
+ { "0.0.0.0", true },
+ { "0.0.0.1", true },
+ { "0.0.1.0", true },
+ { "0.1.0.0", true },
+ { "1.0.0.0", false },
+ { "0.0.0.127", true },
+ { "0.0.0.255", true },
+ { "127.0.0.1", false },
+ { "255.255.255.255", false },
+ };
+ /*
+ * Mapped addresses are currently not netzero.
+ */
+ struct {
+ const char *string;
+ bool expect;
+ } data6[] = {
+ { "::ffff:0.0.0.0", false },
+ { "::ffff:0.0.0.1", false },
+ { "::ffff:0.0.0.127", false },
+ { "::ffff:0.0.0.255", false },
+ { "::ffff:127.0.0.1", false },
+ { "::ffff:255.255.255.255", false },
+ };
+
+ UNUSED(tc);
+
+ for (i = 0; i < sizeof(data4)/sizeof(data4[0]); i++) {
+ in.s_addr = inet_addr(data4[i].string);
+ isc_sockaddr_fromin(&addr, &in, 1);
+ r = isc_sockaddr_isnetzero(&addr);
+ ATF_CHECK_EQ_MSG(r, data4[i].expect, "%s", data4[i].string);
+ }
+
+ for (i = 0; i < sizeof(data6)/sizeof(data6[0]); i++) {
+ ret = inet_pton(AF_INET6, data6[i].string, &in6);
+ ATF_CHECK_EQ(ret, 1);
+ isc_sockaddr_fromin6(&addr, &in6, 1);
+ r = isc_sockaddr_isnetzero(&addr);
+ ATF_CHECK_EQ_MSG(r, data6[i].expect, "%s", data6[i].string);
+ }
+}
+
+ATF_TC(sockaddr_eqaddrprefix);
+ATF_TC_HEAD(sockaddr_eqaddrprefix, tc) {
+ atf_tc_set_md_var(tc, "descr",
+ "isc_sockaddr_eqaddrprefix() returns true when "
+ "prefixes of a and b are equal, and false when "
+ "they are not equal");
+}
+ATF_TC_BODY(sockaddr_eqaddrprefix, tc) {
+ struct in_addr ina_a;
+ struct in_addr ina_b;
+ struct in_addr ina_c;
+ isc_sockaddr_t isa_a;
+ isc_sockaddr_t isa_b;
+ isc_sockaddr_t isa_c;
+
+ UNUSED(tc);
+
+ ATF_CHECK(inet_pton(AF_INET, "194.100.32.87", &ina_a) >= 0);
+ ATF_CHECK(inet_pton(AF_INET, "194.100.32.80", &ina_b) >= 0);
+ ATF_CHECK(inet_pton(AF_INET, "194.101.32.87", &ina_c) >= 0);
+
+ isc_sockaddr_fromin(&isa_a, &ina_a, 0);
+ isc_sockaddr_fromin(&isa_b, &ina_b, 42);
+ isc_sockaddr_fromin(&isa_c, &ina_c, 0);
+
+ ATF_CHECK(isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 0));
+ ATF_CHECK(isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 29));
+ ATF_CHECK(isc_sockaddr_eqaddrprefix(&isa_a, &isa_c, 8));
+
+ ATF_CHECK(! isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 30));
+ ATF_CHECK(! isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 32));
+ ATF_CHECK(! isc_sockaddr_eqaddrprefix(&isa_a, &isa_c, 16));
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, sockaddr_hash);
+ ATF_TP_ADD_TC(tp, sockaddr_isnetzero);
+ ATF_TP_ADD_TC(tp, sockaddr_eqaddrprefix);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/socket_test.c b/lib/isc/tests/socket_test.c
new file mode 100644
index 0000000..3f3f249
--- /dev/null
+++ b/lib/isc/tests/socket_test.c
@@ -0,0 +1,923 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <isc/platform.h>
+#include <isc/socket.h>
+#include <isc/print.h>
+
+#include "../task_p.h"
+#include "../unix/socket_p.h"
+#include "isctest.h"
+
+static bool recv_dscp;
+static unsigned int recv_dscp_value;
+static bool recv_trunc;
+
+/*
+ * Helper functions
+ */
+
+typedef struct {
+ bool done;
+ isc_result_t result;
+ isc_socket_t *socket;
+} completion_t;
+
+static void
+completion_init(completion_t *completion) {
+ completion->done = false;
+ completion->socket = NULL;
+}
+
+static void
+accept_done(isc_task_t *task, isc_event_t *event) {
+ isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
+ completion_t *completion = event->ev_arg;
+
+ UNUSED(task);
+
+ completion->result = nevent->result;
+ completion->done = true;
+ if (completion->result == ISC_R_SUCCESS)
+ completion->socket = nevent->newsocket;
+
+ isc_event_free(&event);
+}
+
+static void
+event_done(isc_task_t *task, isc_event_t *event) {
+ isc_socketevent_t *dev;
+ completion_t *completion = event->ev_arg;
+
+ UNUSED(task);
+
+ dev = (isc_socketevent_t *) event;
+ completion->result = dev->result;
+ completion->done = true;
+ if ((dev->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) {
+ recv_dscp = true;
+ recv_dscp_value = dev->dscp;;
+ } else {
+ recv_dscp = false;
+ }
+ recv_trunc = (dev->attributes & ISC_SOCKEVENTATTR_TRUNC);
+ isc_event_free(&event);
+}
+
+static isc_result_t
+waitfor(completion_t *completion) {
+ int i = 0;
+ while (!completion->done && i++ < 5000) {
+#ifndef ISC_PLATFORM_USETHREADS
+ while (isc__taskmgr_ready(taskmgr))
+ isc__taskmgr_dispatch(taskmgr);
+#endif
+ isc_test_nap(1000);
+ }
+ if (completion->done)
+ return (ISC_R_SUCCESS);
+ return (ISC_R_FAILURE);
+}
+
+#if 0
+static isc_result_t
+waitfor(completion_t *completion) {
+ int i = 0;
+ while (!completion->done && i++ < 5000) {
+ waitbody();
+ }
+ if (completion->done)
+ return (ISC_R_SUCCESS);
+ return (ISC_R_FAILURE);
+}
+#endif
+
+static void
+waitbody(void) {
+#ifndef ISC_PLATFORM_USETHREADS
+ struct timeval tv;
+ isc_socketwait_t *swait = NULL;
+
+ while (isc__taskmgr_ready(taskmgr))
+ isc__taskmgr_dispatch(taskmgr);
+ if (socketmgr != NULL) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000 ;
+ if (isc__socketmgr_waitevents(socketmgr, &tv, &swait) > 0)
+ isc__socketmgr_dispatch(socketmgr, swait);
+ } else
+#endif
+ isc_test_nap(1000);
+}
+
+static isc_result_t
+waitfor2(completion_t *c1, completion_t *c2) {
+ int i = 0;
+
+ while (!(c1->done && c2->done) && i++ < 5000) {
+ waitbody();
+ }
+ if (c1->done && c2->done)
+ return (ISC_R_SUCCESS);
+ return (ISC_R_FAILURE);
+}
+
+/*
+ * Individual unit tests
+ */
+
+/* Test UDP sendto/recv (IPv4) */
+ATF_TC(udp_sendto);
+ATF_TC_HEAD(udp_sendto, tc) {
+ atf_tc_set_md_var(tc, "descr", "UDP sendto/recv");
+}
+ATF_TC_BODY(udp_sendto, tc) {
+ isc_result_t result;
+ isc_sockaddr_t addr1, addr2;
+ struct in_addr in;
+ isc_socket_t *s1 = NULL, *s2 = NULL;
+ isc_task_t *task = NULL;
+ char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
+ completion_t completion;
+ isc_region_t r;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ in.s_addr = inet_addr("127.0.0.1");
+ isc_sockaddr_fromin(&addr1, &in, 0);
+ isc_sockaddr_fromin(&addr2, &in, 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_bind(s1, &addr1, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_getsockname(s1, &addr1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr1) != 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_bind(s2, &addr2, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_getsockname(s2, &addr2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr2) != 0);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ completion_init(&completion);
+ result = isc_socket_sendto(s1, &r, task, event_done, &completion,
+ &addr2, NULL);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+
+ isc_task_detach(&task);
+
+ isc_socket_detach(&s1);
+ isc_socket_detach(&s2);
+
+ isc_test_end();
+}
+
+/* Test UDP sendto/recv with duplicated socket */
+ATF_TC(udp_dup);
+ATF_TC_HEAD(udp_dup, tc) {
+ atf_tc_set_md_var(tc, "descr", "duplicated socket sendto/recv");
+}
+ATF_TC_BODY(udp_dup, tc) {
+ isc_result_t result;
+ isc_sockaddr_t addr1, addr2;
+ struct in_addr in;
+ isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
+ isc_task_t *task = NULL;
+ char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
+ completion_t completion;
+ isc_region_t r;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ in.s_addr = inet_addr("127.0.0.1");
+ isc_sockaddr_fromin(&addr1, &in, 0);
+ isc_sockaddr_fromin(&addr2, &in, 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_bind(s1, &addr1, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_getsockname(s1, &addr1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr1) != 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_bind(s2, &addr2, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_getsockname(s2, &addr2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr2) != 0);
+
+ result = isc_socket_dup(s2, &s3);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ completion_init(&completion);
+ result = isc_socket_sendto(s1, &r, task, event_done, &completion,
+ &addr2, NULL);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ snprintf(sendbuf, sizeof(sendbuf), "World");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ completion_init(&completion);
+ result = isc_socket_sendto(s1, &r, task, event_done, &completion,
+ &addr2, NULL);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "World");
+
+ isc_task_detach(&task);
+
+ isc_socket_detach(&s1);
+ isc_socket_detach(&s2);
+ isc_socket_detach(&s3);
+
+ isc_test_end();
+}
+
+/* Test TCP sendto/recv (IPv4) */
+ATF_TC(udp_dscp_v4);
+ATF_TC_HEAD(udp_dscp_v4, tc) {
+ atf_tc_set_md_var(tc, "descr", "UDP DSCP IPV4");
+}
+ATF_TC_BODY(udp_dscp_v4, tc) {
+ isc_result_t result;
+ isc_sockaddr_t addr1, addr2;
+ struct in_addr in;
+ isc_socket_t *s1 = NULL, *s2 = NULL;
+ isc_task_t *task = NULL;
+ char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
+ completion_t completion;
+ isc_region_t r;
+ isc_socketevent_t *socketevent;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ in.s_addr = inet_addr("127.0.0.1");
+ isc_sockaddr_fromin(&addr1, &in, 0);
+ isc_sockaddr_fromin(&addr2, &in, 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_getsockname(s1, &addr1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr1) != 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_getsockname(s2, &addr2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr2) != 0);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ completion_init(&completion);
+
+ socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
+ event_done, &completion);
+ ATF_REQUIRE(socketevent != NULL);
+
+ if ((isc_net_probedscp() & ISC_NET_DSCPPKTV4) != 0) {
+ socketevent->dscp = 056; /* EF */
+ socketevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
+ } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV4) != 0) {
+ isc_socket_dscp(s1, 056); /* EF */
+ socketevent->dscp = 0;
+ socketevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
+ }
+
+ recv_dscp = false;
+ recv_dscp_value = 0;
+
+ result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+
+ if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) {
+ ATF_CHECK(recv_dscp);
+ ATF_CHECK_EQ(recv_dscp_value, 056);
+ } else
+ ATF_CHECK(!recv_dscp);
+ isc_task_detach(&task);
+
+ isc_socket_detach(&s1);
+ isc_socket_detach(&s2);
+
+ isc_test_end();
+}
+
+/* Test TCP sendto/recv (IPv4) */
+ATF_TC(udp_dscp_v6);
+ATF_TC_HEAD(udp_dscp_v6, tc) {
+ atf_tc_set_md_var(tc, "descr", "udp dscp ipv6");
+}
+ATF_TC_BODY(udp_dscp_v6, tc) {
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(WANT_IPV6)
+ isc_result_t result;
+ isc_sockaddr_t addr1, addr2;
+ struct in6_addr in6;
+ isc_socket_t *s1 = NULL, *s2 = NULL;
+ isc_task_t *task = NULL;
+ char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
+ completion_t completion;
+ isc_region_t r;
+ isc_socketevent_t *socketevent;
+ int n;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ n = inet_pton(AF_INET6, "::1", &in6.s6_addr);
+ ATF_REQUIRE(n == 1);
+ isc_sockaddr_fromin6(&addr1, &in6, 0);
+ isc_sockaddr_fromin6(&addr2, &in6, 0);
+
+ result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp,
+ &s1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_bind(s1, &addr1, 0);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_getsockname(s1, &addr1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr1) != 0);
+
+ result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp,
+ &s2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_bind(s2, &addr2, 0);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_getsockname(s2, &addr2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr2) != 0);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ completion_init(&completion);
+
+ socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
+ event_done, &completion);
+ ATF_REQUIRE(socketevent != NULL);
+
+ if ((isc_net_probedscp() & ISC_NET_DSCPPKTV6) != 0) {
+ socketevent->dscp = 056; /* EF */
+ socketevent->attributes = ISC_SOCKEVENTATTR_DSCP;
+ } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV6) != 0)
+ isc_socket_dscp(s1, 056); /* EF */
+
+ recv_dscp = false;
+ recv_dscp_value = 0;
+
+ result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+ if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) {
+ ATF_CHECK(recv_dscp);
+ ATF_CHECK_EQ(recv_dscp_value, 056);
+ } else
+ ATF_CHECK(!recv_dscp);
+
+ isc_task_detach(&task);
+
+ isc_socket_detach(&s1);
+ isc_socket_detach(&s2);
+
+ isc_test_end();
+#else
+ UNUSED(tc);
+ atf_tc_skip("IPv6 not available");
+#endif
+}
+
+/* Test TCP sendto/recv (IPv4) */
+ATF_TC(tcp_dscp_v4);
+ATF_TC_HEAD(tcp_dscp_v4, tc) {
+ atf_tc_set_md_var(tc, "descr", "tcp dscp ipv4");
+}
+ATF_TC_BODY(tcp_dscp_v4, tc) {
+ isc_result_t result;
+ isc_sockaddr_t addr1;
+ struct in_addr in;
+ isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
+ isc_task_t *task = NULL;
+ char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
+ completion_t completion, completion2;
+ isc_region_t r;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ in.s_addr = inet_addr("127.0.0.1");
+ isc_sockaddr_fromin(&addr1, &in, 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_socket_bind(s1, &addr1, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_getsockname(s1, &addr1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr1) != 0);
+
+ result = isc_socket_listen(s1, 3);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ completion_init(&completion2);
+ result = isc_socket_accept(s1, task, accept_done, &completion2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ completion_init(&completion);
+ result = isc_socket_connect(s2, &addr1, task, event_done, &completion);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ waitfor2(&completion, &completion2);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK(completion2.done);
+ ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS);
+ s3 = completion2.socket;
+
+ isc_socket_dscp(s2, 056); /* EF */
+
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ recv_dscp = false;
+ recv_dscp_value = 0;
+
+ completion_init(&completion);
+ result = isc_socket_sendto(s2, &r, task, event_done, &completion,
+ NULL, NULL);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+
+ if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) {
+ if (recv_dscp)
+ ATF_CHECK_EQ(recv_dscp_value, 056);
+ } else
+ ATF_CHECK(!recv_dscp);
+
+ isc_task_detach(&task);
+
+ isc_socket_detach(&s1);
+ isc_socket_detach(&s2);
+ isc_socket_detach(&s3);
+
+ isc_test_end();
+}
+
+/* Test TCP sendto/recv (IPv6) */
+ATF_TC(tcp_dscp_v6);
+ATF_TC_HEAD(tcp_dscp_v6, tc) {
+ atf_tc_set_md_var(tc, "descr", "tcp dscp ipv6");
+}
+ATF_TC_BODY(tcp_dscp_v6, tc) {
+#ifdef ISC_PLATFORM_HAVEIPV6
+ isc_result_t result;
+ isc_sockaddr_t addr1;
+ struct in6_addr in6;
+ isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
+ isc_task_t *task = NULL;
+ char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
+ completion_t completion, completion2;
+ isc_region_t r;
+ int n;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ n = inet_pton(AF_INET6, "::1", &in6.s6_addr);
+ ATF_REQUIRE(n == 1);
+ isc_sockaddr_fromin6(&addr1, &in6, 0);
+
+ result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp,
+ &s1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_socket_bind(s1, &addr1, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_socket_getsockname(s1, &addr1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr1) != 0);
+
+ result = isc_socket_listen(s1, 3);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp,
+ &s2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ completion_init(&completion2);
+ result = isc_socket_accept(s1, task, accept_done, &completion2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ completion_init(&completion);
+ result = isc_socket_connect(s2, &addr1, task, event_done, &completion);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ waitfor2(&completion, &completion2);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK(completion2.done);
+ ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS);
+ s3 = completion2.socket;
+
+ isc_socket_dscp(s2, 056); /* EF */
+
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ recv_dscp = false;
+ recv_dscp_value = 0;
+
+ completion_init(&completion);
+ result = isc_socket_sendto(s2, &r, task, event_done, &completion,
+ NULL, NULL);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+
+ if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) {
+ /*
+ * IPV6_RECVTCLASS is undefined for TCP however
+ * if we do get it it should be the value we set.
+ */
+ if (recv_dscp)
+ ATF_CHECK_EQ(recv_dscp_value, 056);
+ } else
+ ATF_CHECK(!recv_dscp);
+
+ isc_task_detach(&task);
+
+ isc_socket_detach(&s1);
+ isc_socket_detach(&s2);
+ isc_socket_detach(&s3);
+
+ isc_test_end();
+#else
+ UNUSED(tc);
+ atf_tc_skip("IPv6 not available");
+#endif
+}
+
+ATF_TC(net_probedscp);
+ATF_TC_HEAD(net_probedscp, tc) {
+ atf_tc_set_md_var(tc, "descr", "probe dscp capabilities");
+}
+ATF_TC_BODY(net_probedscp, tc) {
+ unsigned int n;
+
+ UNUSED(tc);
+
+ n = isc_net_probedscp();
+ ATF_CHECK((n & ~ISC_NET_DSCPALL) == 0);
+
+ /* ISC_NET_DSCPSETV4 MUST be set if any is set. */
+ if (n & (ISC_NET_DSCPSETV4|ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4))
+ ATF_CHECK_MSG((n & ISC_NET_DSCPSETV4) != 0,
+ "IPv4:%s%s%s\n",
+ (n & ISC_NET_DSCPSETV4) ? " set" : " none",
+ (n & ISC_NET_DSCPPKTV4) ? " packet" : "",
+ (n & ISC_NET_DSCPRECVV4) ? " receive" : "");
+
+ /* ISC_NET_DSCPSETV6 MUST be set if any is set. */
+ if (n & (ISC_NET_DSCPSETV6|ISC_NET_DSCPPKTV6|ISC_NET_DSCPRECVV6))
+ ATF_CHECK_MSG((n & ISC_NET_DSCPSETV6) != 0,
+ "IPv6:%s%s%s\n",
+ (n & ISC_NET_DSCPSETV6) ? " set" : " none",
+ (n & ISC_NET_DSCPPKTV6) ? " packet" : "",
+ (n & ISC_NET_DSCPRECVV6) ? " receive" : "");
+
+#if 0
+ fprintf(stdout, "IPv4:%s%s%s\n",
+ (n & ISC_NET_DSCPSETV4) ? " set" : "none",
+ (n & ISC_NET_DSCPPKTV4) ? " packet" : "",
+ (n & ISC_NET_DSCPRECVV4) ? " receive" : "");
+
+ fprintf(stdout, "IPv6:%s%s%s\n",
+ (n & ISC_NET_DSCPSETV6) ? " set" : "none",
+ (n & ISC_NET_DSCPPKTV6) ? " packet" : "",
+ (n & ISC_NET_DSCPRECVV6) ? " receive" : "");
+#endif
+}
+
+/* Test UDP truncation detection */
+ATF_TC(udp_trunc);
+ATF_TC_HEAD(udp_trunc, tc) {
+ atf_tc_set_md_var(tc, "descr", "UDP Truncation detection");
+}
+ATF_TC_BODY(udp_trunc, tc) {
+ isc_result_t result;
+ isc_sockaddr_t addr1, addr2;
+ struct in_addr in;
+ isc_socket_t *s1 = NULL, *s2 = NULL;
+ isc_task_t *task = NULL;
+ char sendbuf[BUFSIZ*2], recvbuf[BUFSIZ];
+ completion_t completion;
+ isc_region_t r;
+ isc_socketevent_t *socketevent;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ in.s_addr = inet_addr("127.0.0.1");
+ isc_sockaddr_fromin(&addr1, &in, 0);
+ isc_sockaddr_fromin(&addr2, &in, 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_getsockname(s1, &addr1);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr1) != 0);
+
+ result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ result = isc_socket_getsockname(s2, &addr2);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ ATF_REQUIRE(isc_sockaddr_getport(&addr2) != 0);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+
+ /*
+ * Send a message that will not be truncated.
+ */
+ memset(sendbuf, 0xff, sizeof(sendbuf));
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = strlen(sendbuf) + 1;
+
+ completion_init(&completion);
+
+ socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
+ event_done, &completion);
+ ATF_REQUIRE(socketevent != NULL);
+
+ result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
+ ATF_REQUIRE_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ recv_trunc = false;
+ result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+ ATF_CHECK_EQ(recv_trunc, false);
+
+ /*
+ * Send a message that will be truncated.
+ */
+ memset(sendbuf, 0xff, sizeof(sendbuf));
+ snprintf(sendbuf, sizeof(sendbuf), "Hello");
+ r.base = (void *) sendbuf;
+ r.length = sizeof(sendbuf);
+
+ completion_init(&completion);
+
+ socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
+ event_done, &completion);
+ ATF_REQUIRE(socketevent != NULL);
+
+ result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
+ ATF_REQUIRE_EQ_MSG(result, ISC_R_SUCCESS, "%s",
+ isc_result_totext(result));
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+
+ r.base = (void *) recvbuf;
+ r.length = BUFSIZ;
+ completion_init(&completion);
+ recv_trunc = false;
+ result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ waitfor(&completion);
+ ATF_CHECK(completion.done);
+ ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(recvbuf, "Hello");
+ ATF_CHECK_EQ(recv_trunc, true);
+
+ isc_task_detach(&task);
+
+ isc_socket_detach(&s1);
+ isc_socket_detach(&s2);
+
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, udp_sendto);
+ ATF_TP_ADD_TC(tp, udp_dup);
+ ATF_TP_ADD_TC(tp, tcp_dscp_v4);
+ ATF_TP_ADD_TC(tp, tcp_dscp_v6);
+ ATF_TP_ADD_TC(tp, udp_dscp_v4);
+ ATF_TP_ADD_TC(tp, udp_dscp_v6);
+ ATF_TP_ADD_TC(tp, net_probedscp);
+ ATF_TP_ADD_TC(tp, udp_trunc);
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/symtab_test.c b/lib/isc/tests/symtab_test.c
new file mode 100644
index 0000000..a50553b
--- /dev/null
+++ b/lib/isc/tests/symtab_test.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+
+#include <isc/symtab.h>
+#include <isc/print.h>
+
+#include "isctest.h"
+
+static void
+undefine(char *key, unsigned int type, isc_symvalue_t value, void *arg) {
+ UNUSED(arg);
+
+ ATF_REQUIRE_EQ(type, 1);
+ isc_mem_free(mctx, key);
+ isc_mem_free(mctx, value.as_pointer);
+}
+
+/*
+ * Individual unit tests
+ */
+
+ATF_TC(symtab_grow);
+ATF_TC_HEAD(symtab_grow, tc) {
+ atf_tc_set_md_var(tc, "descr", "symbol table growth");
+}
+ATF_TC_BODY(symtab_grow, tc) {
+ isc_result_t result;
+ isc_symtab_t *st = NULL;
+ isc_symvalue_t value;
+ isc_symexists_t policy = isc_symexists_reject;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_symtab_create(mctx, 3, undefine, NULL, false, &st);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(st != NULL);
+
+ /* Nothing should be in the table yet */
+
+ /*
+ * Put 1024 entries in the table (this should necessate
+ * regrowing the hash table several times
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16], *key;
+
+ snprintf(str, sizeof(str), "%04x", i);
+ key = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(key != NULL);
+ value.as_pointer = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(value.as_pointer != NULL);
+ result = isc_symtab_define(st, key, 1, value, policy);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ if (result != ISC_R_SUCCESS)
+ undefine(key, 1, value, NULL);
+ }
+
+ /*
+ * Try to put them in again; this should fail
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16], *key;
+
+ snprintf(str, sizeof(str), "%04x", i);
+ key = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(key != NULL);
+ value.as_pointer = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(value.as_pointer != NULL);
+ result = isc_symtab_define(st, key, 1, value, policy);
+ ATF_CHECK_EQ(result, ISC_R_EXISTS);
+ undefine(key, 1, value, NULL);
+ }
+
+ /*
+ * Retrieve them; this should succeed
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_lookup(st, str, 0, &value);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, (char *)value.as_pointer);
+ }
+
+ /*
+ * Undefine them
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_undefine(st, str, 1);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ }
+
+ /*
+ * Retrieve them again; this should fail
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_lookup(st, str, 0, &value);
+ ATF_CHECK_EQ(result, ISC_R_NOTFOUND);
+ }
+
+ isc_symtab_destroy(&st);
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, symtab_grow);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/task_test.c b/lib/isc/tests/task_test.c
new file mode 100644
index 0000000..c991272
--- /dev/null
+++ b/lib/isc/tests/task_test.c
@@ -0,0 +1,1474 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <isc/condition.h>
+#include <isc/mem.h>
+#include <isc/platform.h>
+#include <isc/print.h>
+#include <isc/task.h>
+#include <isc/time.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include "../task_p.h"
+#include "isctest.h"
+
+/*
+ * Helper functions
+ */
+
+static isc_mutex_t lock;
+int counter = 0;
+static int active[10];
+static bool done = false;
+
+#ifdef ISC_PLATFORM_USETHREADS
+static isc_condition_t cv;
+#endif
+
+static void
+set(isc_task_t *task, isc_event_t *event) {
+ int *value = (int *) event->ev_arg;
+
+ UNUSED(task);
+
+ isc_event_free(&event);
+ LOCK(&lock);
+ *value = counter++;
+ UNLOCK(&lock);
+}
+
+static void
+set_and_drop(isc_task_t *task, isc_event_t *event) {
+ int *value = (int *) event->ev_arg;
+
+ UNUSED(task);
+
+ isc_event_free(&event);
+ LOCK(&lock);
+ *value = (int) isc_taskmgr_mode(taskmgr);
+ counter++;
+ UNLOCK(&lock);
+ isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_normal);
+}
+
+/*
+ * Individual unit tests
+ */
+
+/* Create a task */
+ATF_TC(create_task);
+ATF_TC_HEAD(create_task, tc) {
+ atf_tc_set_md_var(tc, "descr", "create and destroy a task");
+}
+ATF_TC_BODY(create_task, tc) {
+ isc_result_t result;
+ isc_task_t *task = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_task_destroy(&task);
+ ATF_REQUIRE_EQ(task, NULL);
+
+ isc_test_end();
+}
+
+/* Process events */
+ATF_TC(all_events);
+ATF_TC_HEAD(all_events, tc) {
+ atf_tc_set_md_var(tc, "descr", "process task events");
+}
+ATF_TC_BODY(all_events, tc) {
+ isc_result_t result;
+ isc_task_t *task = NULL;
+ isc_event_t *event = NULL;
+ int a = 0, b = 0;
+ int i = 0;
+
+ UNUSED(tc);
+
+ counter = 1;
+
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /* First event */
+ event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
+ set, &a, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(a, 0);
+ isc_task_send(task, &event);
+
+ event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
+ set, &b, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(b, 0);
+ isc_task_send(task, &event);
+
+ while ((a == 0 || b == 0) && i++ < 5000) {
+#ifndef ISC_PLATFORM_USETHREADS
+ while (isc__taskmgr_ready(taskmgr))
+ isc__taskmgr_dispatch(taskmgr);
+#endif
+ isc_test_nap(1000);
+ }
+
+ ATF_CHECK(a != 0);
+ ATF_CHECK(b != 0);
+
+ isc_task_destroy(&task);
+ ATF_REQUIRE_EQ(task, NULL);
+
+ isc_test_end();
+}
+
+/* Privileged events */
+ATF_TC(privileged_events);
+ATF_TC_HEAD(privileged_events, tc) {
+ atf_tc_set_md_var(tc, "descr", "process privileged events");
+}
+ATF_TC_BODY(privileged_events, tc) {
+ isc_result_t result;
+ isc_task_t *task1 = NULL, *task2 = NULL;
+ isc_event_t *event = NULL;
+ int a = 0, b = 0, c = 0, d = 0, e = 0;
+ int i = 0;
+
+ UNUSED(tc);
+
+ counter = 1;
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+#ifdef ISC_PLATFORM_USETHREADS
+ /*
+ * Pause the task manager so we can fill up the work queue
+ * without things happening while we do it.
+ */
+ isc__taskmgr_pause(taskmgr);
+#endif
+
+ result = isc_task_create(taskmgr, 0, &task1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ isc_task_setname(task1, "privileged", NULL);
+ ATF_CHECK(!isc_task_privilege(task1));
+ isc_task_setprivilege(task1, true);
+ ATF_CHECK(isc_task_privilege(task1));
+
+ result = isc_task_create(taskmgr, 0, &task2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ isc_task_setname(task2, "normal", NULL);
+ ATF_CHECK(!isc_task_privilege(task2));
+
+ /* First event: privileged */
+ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
+ set, &a, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(a, 0);
+ isc_task_send(task1, &event);
+
+ /* Second event: not privileged */
+ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
+ set, &b, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(b, 0);
+ isc_task_send(task2, &event);
+
+ /* Third event: privileged */
+ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
+ set, &c, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(c, 0);
+ isc_task_send(task1, &event);
+
+ /* Fourth event: privileged */
+ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
+ set, &d, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(d, 0);
+ isc_task_send(task1, &event);
+
+ /* Fifth event: not privileged */
+ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
+ set, &e, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(e, 0);
+ isc_task_send(task2, &event);
+
+ ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
+ isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
+ ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
+
+#ifdef ISC_PLATFORM_USETHREADS
+ isc__taskmgr_resume(taskmgr);
+#endif
+
+ /* We're waiting for *all* variables to be set */
+ while ((a == 0 || b == 0 || c == 0 || d == 0 || e == 0) && i++ < 5000) {
+#ifndef ISC_PLATFORM_USETHREADS
+ while (isc__taskmgr_ready(taskmgr))
+ isc__taskmgr_dispatch(taskmgr);
+#endif
+ isc_test_nap(1000);
+ }
+
+ /*
+ * We can't guarantee what order the events fire, but
+ * we do know the privileged tasks that set a, c, and d
+ * would have fired first.
+ */
+ ATF_CHECK(a <= 3);
+ ATF_CHECK(c <= 3);
+ ATF_CHECK(d <= 3);
+
+ /* ...and the non-privileged tasks that set b and e, last */
+ ATF_CHECK(b >= 4);
+ ATF_CHECK(e >= 4);
+
+ ATF_CHECK_EQ(counter, 6);
+
+ isc_task_setprivilege(task1, false);
+ ATF_CHECK(!isc_task_privilege(task1));
+
+ ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
+
+ isc_task_destroy(&task1);
+ ATF_REQUIRE_EQ(task1, NULL);
+ isc_task_destroy(&task2);
+ ATF_REQUIRE_EQ(task2, NULL);
+
+ isc_test_end();
+}
+
+/*
+ * Edge case: this tests that the task manager behaves as expected when
+ * we explicitly set it into normal mode *while* running privileged.
+ */
+ATF_TC(privilege_drop);
+ATF_TC_HEAD(privilege_drop, tc) {
+ atf_tc_set_md_var(tc, "descr", "process privileged events");
+}
+ATF_TC_BODY(privilege_drop, tc) {
+ isc_result_t result;
+ isc_task_t *task1 = NULL, *task2 = NULL;
+ isc_event_t *event = NULL;
+ int a = -1, b = -1, c = -1, d = -1, e = -1; /* non valid states */
+ int i = 0;
+
+ UNUSED(tc);
+
+ counter = 1;
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+#ifdef ISC_PLATFORM_USETHREADS
+ /*
+ * Pause the task manager so we can fill up the work queue
+ * without things happening while we do it.
+ */
+ isc__taskmgr_pause(taskmgr);
+#endif
+
+ result = isc_task_create(taskmgr, 0, &task1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ isc_task_setname(task1, "privileged", NULL);
+ ATF_CHECK(!isc_task_privilege(task1));
+ isc_task_setprivilege(task1, true);
+ ATF_CHECK(isc_task_privilege(task1));
+
+ result = isc_task_create(taskmgr, 0, &task2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ isc_task_setname(task2, "normal", NULL);
+ ATF_CHECK(!isc_task_privilege(task2));
+
+ /* First event: privileged */
+ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
+ set_and_drop, &a, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(a, -1);
+ isc_task_send(task1, &event);
+
+ /* Second event: not privileged */
+ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
+ set_and_drop, &b, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(b, -1);
+ isc_task_send(task2, &event);
+
+ /* Third event: privileged */
+ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
+ set_and_drop, &c, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(c, -1);
+ isc_task_send(task1, &event);
+
+ /* Fourth event: privileged */
+ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
+ set_and_drop, &d, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(d, -1);
+ isc_task_send(task1, &event);
+
+ /* Fifth event: not privileged */
+ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
+ set_and_drop, &e, sizeof (isc_event_t));
+ ATF_REQUIRE(event != NULL);
+
+ ATF_CHECK_EQ(e, -1);
+ isc_task_send(task2, &event);
+
+ ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
+ isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
+ ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
+
+#ifdef ISC_PLATFORM_USETHREADS
+ isc__taskmgr_resume(taskmgr);
+#endif
+
+ /* We're waiting for all variables to be set. */
+ while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) &&
+ i++ < 5000) {
+#ifndef ISC_PLATFORM_USETHREADS
+ while (isc__taskmgr_ready(taskmgr))
+ isc__taskmgr_dispatch(taskmgr);
+#endif
+ isc_test_nap(1000);
+ }
+
+ /*
+ * We can't guarantee what order the events fire, but
+ * we do know *exactly one* of the privileged tasks will
+ * have run in privileged mode...
+ */
+ ATF_CHECK(a == isc_taskmgrmode_privileged ||
+ c == isc_taskmgrmode_privileged ||
+ d == isc_taskmgrmode_privileged);
+ ATF_CHECK(a + c + d == isc_taskmgrmode_privileged);
+
+ /* ...and neither of the non-privileged tasks did... */
+ ATF_CHECK(b == isc_taskmgrmode_normal || e == isc_taskmgrmode_normal);
+
+ /* ...but all five of them did run. */
+ ATF_CHECK_EQ(counter, 6);
+
+ ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
+
+ isc_task_destroy(&task1);
+ ATF_REQUIRE_EQ(task1, NULL);
+ isc_task_destroy(&task2);
+ ATF_REQUIRE_EQ(task2, NULL);
+
+ isc_test_end();
+}
+
+/*
+ * Basic task functions:
+ */
+static void
+basic_cb(isc_task_t *task, isc_event_t *event) {
+ int i;
+ int j;
+
+ UNUSED(task);
+
+ j = 0;
+ for (i = 0; i < 1000000; i++) {
+ j += 100;
+ }
+
+ printf("task %s\n", (char *)event->ev_arg);
+ isc_event_free(&event);
+}
+
+static void
+basic_shutdown(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ printf("shutdown %s\n", (char *)event->ev_arg);
+ isc_event_free(&event);
+}
+
+static void
+basic_tick(isc_task_t *task, isc_event_t *event) {
+
+ UNUSED(task);
+
+ printf("%s\n", (char *)event->ev_arg);
+ isc_event_free(&event);
+}
+
+static char one[] = "1";
+static char two[] = "2";
+static char three[] = "3";
+static char four[] = "4";
+static char tick[] = "tick";
+static char tock[] = "tock";
+
+
+ATF_TC(basic);
+ATF_TC_HEAD(basic, tc) {
+ atf_tc_set_md_var(tc, "descr", "basic task system check");
+}
+ATF_TC_BODY(basic, tc) {
+ isc_result_t result;
+ isc_task_t *task1 = NULL;
+ isc_task_t *task2 = NULL;
+ isc_task_t *task3 = NULL;
+ isc_task_t *task4 = NULL;
+ isc_event_t *event = NULL;
+ isc_timer_t *ti1 = NULL;
+ isc_timer_t *ti2 = NULL;
+ isc_time_t absolute;
+ isc_interval_t interval;
+ char *testarray[] = {
+ one, one, one, one, one, one, one, one, one,
+ two, three, four, two, three, four, NULL
+ };
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_task_create(taskmgr, 0, &task2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_task_create(taskmgr, 0, &task3);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_task_create(taskmgr, 0, &task4);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_onshutdown(task1, basic_shutdown, one);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_task_onshutdown(task2, basic_shutdown, two);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_task_onshutdown(task3, basic_shutdown, three);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ result = isc_task_onshutdown(task4, basic_shutdown, four);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_time_settoepoch(&absolute);
+ isc_interval_set(&interval, 1, 0);
+ result = isc_timer_create(timermgr, isc_timertype_ticker,
+ &absolute, &interval,
+ task1, basic_tick, tick, &ti1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ti2 = NULL;
+ isc_time_settoepoch(&absolute);
+ isc_interval_set(&interval, 1, 0);
+ result = isc_timer_create(timermgr, isc_timertype_ticker,
+ &absolute, &interval,
+ task2, basic_tick, tock, &ti2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+#ifndef WIN32
+ sleep(2);
+#else
+ Sleep(2000);
+#endif
+
+ for (i = 0; testarray[i] != NULL; i++) {
+ /*
+ * Note: (void *)1 is used as a sender here, since some
+ * compilers don't like casting a function pointer to a
+ * (void *).
+ *
+ * In a real use, it is more likely the sender would be a
+ * structure (socket, timer, task, etc) but this is just a
+ * test program.
+ */
+ event = isc_event_allocate(mctx, (void *)1, 1, basic_cb,
+ testarray[i], sizeof(*event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_send(task1, &event);
+ }
+
+ (void)isc_task_purge(task3, NULL, 0, 0);
+
+ isc_task_detach(&task1);
+ isc_task_detach(&task2);
+ isc_task_detach(&task3);
+ isc_task_detach(&task4);
+
+#ifndef WIN32
+ sleep(10);
+#else
+ Sleep(10000);
+#endif
+ isc_timer_detach(&ti1);
+ isc_timer_detach(&ti2);
+
+ isc_test_end();
+}
+
+/*
+ * Exclusive mode test:
+ * When one task enters exclusive mode, all other active
+ * tasks complete first.
+ */
+static
+int spin(int n) {
+ int i;
+ int r = 0;
+ for (i = 0; i < n; i++) {
+ r += i;
+ if (r > 1000000)
+ r = 0;
+ }
+ return (r);
+}
+
+static void
+exclusive_cb(isc_task_t *task, isc_event_t *event) {
+ int taskno = *(int *)(event->ev_arg);
+
+ printf("task enter %d\n", taskno);
+
+ /* task chosen from the middle of the range */
+ if (taskno == 6) {
+ isc_result_t result;
+ int i;
+
+ result = isc_task_beginexclusive(task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ for (i = 0; i < 10; i++) {
+ ATF_CHECK(active[i] == 0);
+ }
+
+ isc_task_endexclusive(task);
+ done = true;
+ } else {
+ active[taskno]++;
+ (void) spin(10000000);
+ active[taskno]--;
+ }
+
+ printf("task exit %d\n", taskno);
+
+ if (done) {
+ isc_mem_put(event->ev_destroy_arg, event->ev_arg, sizeof (int));
+ isc_event_free(&event);
+ } else {
+ isc_task_send(task, &event);
+ }
+}
+
+ATF_TC(task_exclusive);
+ATF_TC_HEAD(task_exclusive, tc) {
+ atf_tc_set_md_var(tc, "descr", "test exclusive mode");
+}
+ATF_TC_BODY(task_exclusive, tc) {
+ isc_task_t *tasks[10];
+ isc_result_t result;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 4);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ for (i = 0; i < 10; i++) {
+ isc_event_t *event = NULL;
+ int *v;
+
+ tasks[i] = NULL;
+
+ result = isc_task_create(taskmgr, 0, &tasks[i]);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ v = isc_mem_get(mctx, sizeof *v);
+ ATF_REQUIRE(v != NULL);
+
+ *v = i;
+
+ event = isc_event_allocate(mctx, NULL, 1, exclusive_cb,
+ v, sizeof(*event));
+ ATF_REQUIRE(event != NULL);
+
+ isc_task_send(tasks[i], &event);
+ }
+
+ for (i = 0; i < 10; i++) {
+ isc_task_detach(&tasks[i]);
+ }
+ isc_test_end();
+}
+
+/*
+ * The remainder of these tests require threads
+ */
+#ifdef ISC_PLATFORM_USETHREADS
+/*
+ * Max tasks test:
+ * The task system can create and execute many tasks. Tests with 10000.
+ */
+static void
+maxtask_shutdown(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ if (event->ev_arg != NULL) {
+ isc_task_destroy((isc_task_t**) &event->ev_arg);
+ } else {
+ LOCK(&lock);
+ done = true;
+ SIGNAL(&cv);
+ UNLOCK(&lock);
+
+ isc_event_free(&event);
+ isc_taskmgr_destroy(&taskmgr);
+ isc_mem_destroy(&mctx);
+
+ isc_condition_destroy(&cv);
+ DESTROYLOCK(&lock);
+ }
+}
+
+static void
+maxtask_cb(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+
+ if (event->ev_arg != NULL) {
+ isc_task_t *newtask = NULL;
+
+ event->ev_arg = (void *)(((uintptr_t) event->ev_arg) - 1);
+
+ /*
+ * Create a new task and forward the message.
+ */
+ result = isc_task_create(taskmgr, 0, &newtask);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_onshutdown(newtask, maxtask_shutdown,
+ (void *)task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_task_send(newtask, &event);
+ } else if (task != NULL) {
+ isc_task_destroy(&task);
+ }
+}
+
+ATF_TC(manytasks);
+ATF_TC_HEAD(manytasks, tc) {
+ atf_tc_set_md_var(tc, "descr", "many tasks");
+}
+ATF_TC_BODY(manytasks, tc) {
+ isc_result_t result;
+ isc_event_t *event = NULL;
+ uintptr_t ntasks = 10000;
+
+ UNUSED(tc);
+
+ printf("Testing with %lu tasks\n", (unsigned long)ntasks);
+
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_init(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mem_create(0, 0, &mctx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_taskmgr_create(mctx, 4, 0, &taskmgr);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ event = isc_event_allocate(mctx, (void *)1, 1, maxtask_cb,
+ (void *)ntasks, sizeof(*event));
+ ATF_REQUIRE(event != NULL);
+
+ LOCK(&lock);
+ maxtask_cb(NULL, event);
+ while (!done) {
+ WAIT(&cv, &lock);
+ }
+}
+
+
+/*
+ * Shutdown test:
+ * When isc_task_shutdown() is called, shutdown events are posted
+ * in LIFO order.
+ */
+
+static int senders[4];
+static int nevents = 0;
+static int nsdevents = 0;
+
+static void
+sd_sde1(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ ATF_CHECK_EQ(nevents, 256);
+ ATF_REQUIRE_EQ(nsdevents, 1);
+ ++nsdevents;
+ printf("shutdown 1\n");
+
+ isc_event_free(&event);
+}
+
+static void
+sd_sde2(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ ATF_CHECK_EQ(nevents, 256);
+ ATF_REQUIRE_EQ(nsdevents, 0);
+ ++nsdevents;
+ printf("shutdown 2\n");
+
+ isc_event_free(&event);
+}
+
+static void
+sd_event1(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ LOCK(&lock);
+ while (!done) {
+ WAIT(&cv, &lock);
+ }
+
+ printf("event 1\n");
+
+ isc_event_free(&event);
+}
+
+static void
+sd_event2(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ ++nevents;
+
+ printf("event 2\n");
+
+ isc_event_free(&event);
+}
+
+ATF_TC(shutdown);
+ATF_TC_HEAD(shutdown, tc) {
+ atf_tc_set_md_var(tc, "descr", "task shutdown");
+}
+ATF_TC_BODY(shutdown, tc) {
+ isc_result_t result;
+ isc_eventtype_t event_type;
+ isc_event_t *event = NULL;
+ isc_task_t *task = NULL;
+ int i;
+
+ nevents = nsdevents = 0;
+ done = false;
+
+ event_type = 3;
+
+ result = isc_test_begin(NULL, true, 4);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_init(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ LOCK(&lock);
+
+ task = NULL;
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /*
+ * This event causes the task to wait on cv.
+ */
+ event = isc_event_allocate(mctx, &senders[1], event_type, sd_event1,
+ NULL, sizeof(*event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_send(task, &event);
+
+ /*
+ * Now we fill up the task's event queue with some events.
+ */
+ for (i = 0; i < 256; ++i) {
+ event = isc_event_allocate(mctx, &senders[1], event_type,
+ sd_event2, NULL, sizeof(*event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_send(task, &event);
+ }
+
+ /*
+ * Now we register two shutdown events.
+ */
+ result = isc_task_onshutdown(task, sd_sde1, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_onshutdown(task, sd_sde2, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_task_shutdown(task);
+
+ /*
+ * Now we free the task by signaling cv.
+ */
+ done = true;
+ SIGNAL(&cv);
+ UNLOCK(&lock);
+
+ isc_task_detach(&task);
+
+ isc_test_end();
+
+ ATF_REQUIRE_EQ(nsdevents, 2);
+}
+
+/*
+ * Post-shutdown test:
+ * After isc_task_shutdown() has been called, any call to
+ * isc_task_onshutdown() will return ISC_R_SHUTTINGDOWN.
+ */
+static void
+psd_event1(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ LOCK(&lock);
+
+ while (!done) {
+ WAIT(&cv, &lock);
+ }
+
+ UNLOCK(&lock);
+
+ isc_event_free(&event);
+}
+
+static void
+psd_sde(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ isc_event_free(&event);
+}
+
+ATF_TC(post_shutdown);
+ATF_TC_HEAD(post_shutdown, tc) {
+ atf_tc_set_md_var(tc, "descr", "post-shutdown");
+}
+ATF_TC_BODY(post_shutdown, tc) {
+ isc_result_t result;
+ isc_eventtype_t event_type;
+ isc_event_t *event;
+ isc_task_t *task;
+
+ done = false;
+ event_type = 4;
+
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_init(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ LOCK(&lock);
+
+ task = NULL;
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /*
+ * This event causes the task to wait on cv.
+ */
+ event = isc_event_allocate(mctx, &senders[1], event_type, psd_event1,
+ NULL, sizeof(*event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_send(task, &event);
+
+ isc_task_shutdown(task);
+
+ result = isc_task_onshutdown(task, psd_sde, NULL);
+ ATF_CHECK_EQ(result, ISC_R_SHUTTINGDOWN);
+
+ /*
+ * Release the task.
+ */
+ done = true;
+
+ SIGNAL(&cv);
+ UNLOCK(&lock);
+
+ isc_task_detach(&task);
+ isc_test_end();
+
+ (void) isc_condition_destroy(&cv);
+ DESTROYLOCK(&lock);
+}
+
+/*
+ * Helper for the purge tests below:
+ */
+
+#define SENDERCNT 3
+#define TYPECNT 4
+#define TAGCNT 5
+#define NEVENTS (SENDERCNT * TYPECNT * TAGCNT)
+
+static bool testrange;
+static void *purge_sender;
+static isc_eventtype_t purge_type_first;
+static isc_eventtype_t purge_type_last;
+static void *purge_tag;
+static int eventcnt;
+
+bool started = false;
+
+static void
+pg_event1(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ LOCK(&lock);
+ while (!started) {
+ WAIT(&cv, &lock);
+ }
+ UNLOCK(&lock);
+
+ isc_event_free(&event);
+}
+
+static void
+pg_event2(isc_task_t *task, isc_event_t *event) {
+ bool sender_match = false;
+ bool type_match = false;
+ bool tag_match = false;
+
+ UNUSED(task);
+
+ if ((purge_sender == NULL) || (purge_sender == event->ev_sender)) {
+ sender_match = true;
+ }
+
+ if (testrange) {
+ if ((purge_type_first <= event->ev_type) &&
+ (event->ev_type <= purge_type_last))
+ {
+ type_match = true;
+ }
+ } else {
+ if (purge_type_first == event->ev_type) {
+ type_match = true;
+ }
+ }
+
+ if ((purge_tag == NULL) || (purge_tag == event->ev_tag)) {
+ tag_match = true;
+ }
+
+ if (sender_match && type_match && tag_match) {
+ if (event->ev_attributes & ISC_EVENTATTR_NOPURGE) {
+ printf("event %p,%d,%p matched but was not purgeable\n",
+ event->ev_sender, (int)event->ev_type,
+ event->ev_tag);
+ ++eventcnt;
+ } else {
+ printf("*** event %p,%d,%p not purged\n",
+ event->ev_sender, (int)event->ev_type,
+ event->ev_tag);
+ }
+ } else {
+ ++eventcnt;
+ }
+
+ isc_event_free(&event);
+}
+
+static void
+pg_sde(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ LOCK(&lock);
+ done = true;
+ SIGNAL(&cv);
+ UNLOCK(&lock);
+
+ isc_event_free(&event);
+}
+
+static void
+test_purge(int sender, int type, int tag, int exp_purged) {
+ isc_result_t result;
+ isc_task_t *task = NULL;
+ isc_event_t *eventtab[NEVENTS];
+ isc_event_t *event = NULL;
+ isc_interval_t interval;
+ isc_time_t now;
+ int sender_cnt, type_cnt, tag_cnt, event_cnt, i;
+ int purged = 0;
+
+ started = false;
+ done = false;
+ eventcnt = 0;
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_init(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_onshutdown(task, pg_sde, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /*
+ * Block the task on cv.
+ */
+ event = isc_event_allocate(mctx, (void *)1, 9999,
+ pg_event1, NULL, sizeof(*event));
+
+ ATF_REQUIRE(event != NULL);
+ isc_task_send(task, &event);
+
+ /*
+ * Fill the task's queue with some messages with varying
+ * sender, type, tag, and purgeable attribute values.
+ */
+ event_cnt = 0;
+ for (sender_cnt = 0; sender_cnt < SENDERCNT; ++sender_cnt) {
+ for (type_cnt = 0; type_cnt < TYPECNT; ++type_cnt) {
+ for (tag_cnt = 0; tag_cnt < TAGCNT; ++tag_cnt) {
+ eventtab[event_cnt] =
+ isc_event_allocate(mctx,
+ &senders[sender + sender_cnt],
+ (isc_eventtype_t)(type + type_cnt),
+ pg_event2, NULL, sizeof(*event));
+
+ ATF_REQUIRE(eventtab[event_cnt] != NULL);
+
+ eventtab[event_cnt]->ev_tag =
+ (void *)((uintptr_t)tag + tag_cnt);
+
+ /*
+ * Mark events as non-purgeable if
+ * sender, type and tag are all
+ * odd-numbered. (There should be 4
+ * of these out of 60 events total.)
+ */
+ if (((sender_cnt % 2) != 0) &&
+ ((type_cnt % 2) != 0) &&
+ ((tag_cnt % 2) != 0))
+ {
+ eventtab[event_cnt]->ev_attributes |=
+ ISC_EVENTATTR_NOPURGE;
+ }
+ ++event_cnt;
+ }
+ }
+ }
+
+ for (i = 0; i < event_cnt; ++i) {
+ isc_task_send(task, &eventtab[i]);
+ }
+
+ if (testrange) {
+ /*
+ * We're testing isc_task_purgerange.
+ */
+ purged = isc_task_purgerange(task, purge_sender,
+ (isc_eventtype_t)purge_type_first,
+ (isc_eventtype_t)purge_type_last,
+ purge_tag);
+ ATF_CHECK_EQ(purged, exp_purged);
+ } else {
+ /*
+ * We're testing isc_task_purge.
+ */
+ printf("purge events %p,%u,%p\n",
+ purge_sender, purge_type_first, purge_tag);
+ purged = isc_task_purge(task, purge_sender,
+ (isc_eventtype_t)purge_type_first,
+ purge_tag);
+ printf("purged %d expected %d\n", purged, exp_purged);
+ ATF_CHECK_EQ(purged, exp_purged);
+ }
+
+ /*
+ * Unblock the task, allowing event processing.
+ */
+ LOCK(&lock);
+ started = true;
+ SIGNAL(&cv);
+
+ isc_task_shutdown(task);
+
+ isc_interval_set(&interval, 5, 0);
+
+ /*
+ * Wait for shutdown processing to complete.
+ */
+ while (!done) {
+ result = isc_time_nowplusinterval(&now, &interval);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ WAITUNTIL(&cv, &lock, &now);
+ }
+
+ UNLOCK(&lock);
+
+ isc_task_detach(&task);
+
+ isc_test_end();
+ DESTROYLOCK(&lock);
+ (void) isc_condition_destroy(&cv);
+
+ ATF_CHECK_EQ(eventcnt, event_cnt - exp_purged);
+}
+
+/*
+ * Purge test:
+ * A call to isc_task_purge(task, sender, type, tag) purges all events of
+ * type 'type' and with tag 'tag' not marked as unpurgeable from sender
+ * from the task's " queue and returns the number of events purged.
+ */
+ATF_TC(purge);
+ATF_TC_HEAD(purge, tc) {
+ atf_tc_set_md_var(tc, "descr", "purge");
+}
+ATF_TC_BODY(purge, tc) {
+ /* Try purging on a specific sender. */
+ printf("testing purge on 2,4,8 expecting 1\n");
+ purge_sender = &senders[2];
+ purge_type_first = 4;
+ purge_type_last = 4;
+ purge_tag = (void *)8;
+ testrange = false;
+ test_purge(1, 4, 7, 1);
+
+ /* Try purging on all senders. */
+ printf("testing purge on 0,4,8 expecting 3\n");
+ purge_sender = NULL;
+ purge_type_first = 4;
+ purge_type_last = 4;
+ purge_tag = (void *)8;
+ testrange = false;
+ test_purge(1, 4, 7, 3);
+
+ /* Try purging on all senders, specified type, all tags. */
+ printf("testing purge on 0,4,0 expecting 15\n");
+ purge_sender = NULL;
+ purge_type_first = 4;
+ purge_type_last = 4;
+ purge_tag = NULL;
+ testrange = false;
+ test_purge(1, 4, 7, 15);
+
+ /* Try purging on a specified tag, no such type. */
+ printf("testing purge on 0,99,8 expecting 0\n");
+ purge_sender = NULL;
+ purge_type_first = 99;
+ purge_type_last = 99;
+ purge_tag = (void *)8;
+ testrange = false;
+ test_purge(1, 4, 7, 0);
+
+ /*
+ * Try purging on specified sender, type, all tags.
+ */
+ printf("testing purge on 3,5,0 expecting 5\n");
+ purge_sender = &senders[3];
+ purge_type_first = 5;
+ purge_type_last = 5;
+ purge_tag = NULL;
+ testrange = false;
+ test_purge(1, 4, 7, 5);
+}
+
+/*
+ * Purge range test:
+ * A call to isc_event_purgerange(task, sender, first, last, tag) purges
+ * all events not marked unpurgeable from sender 'sender' and of type within
+ * the range 'first' to 'last' inclusive from the task's event queue and
+ * returns the number of tasks purged.
+ */
+
+ATF_TC(purgerange);
+ATF_TC_HEAD(purgerange, tc) {
+ atf_tc_set_md_var(tc, "descr", "purge-range");
+}
+ATF_TC_BODY(purgerange, tc) {
+ /* Now let's try some ranges. */
+ printf("testing purgerange on 2,4-5,8 expecting 1\n");
+ purge_sender = &senders[2];
+ purge_type_first = 4;
+ purge_type_last = 5;
+ purge_tag = (void *)8;
+ testrange = true;
+ test_purge(1, 4, 7, 1);
+
+ /* Try purging on all senders. */
+ printf("testing purge on 0,4-5,8 expecting 5\n");
+ purge_sender = NULL;
+ purge_type_first = 4;
+ purge_type_last = 5;
+ purge_tag = (void *)8;
+ testrange = true;
+ test_purge(1, 4, 7, 5);
+
+ /* Try purging on all senders, specified type, all tags. */
+ printf("testing purge on 0,5-6,0 expecting 28\n");
+ purge_sender = NULL;
+ purge_type_first = 5;
+ purge_type_last = 6;
+ purge_tag = NULL;
+ testrange = true;
+ test_purge(1, 4, 7, 28);
+
+ /* Try purging on a specified tag, no such type. */
+ printf("testing purge on 0,99-101,8 expecting 0\n");
+ purge_sender = NULL;
+ purge_type_first = 99;
+ purge_type_last = 101;
+ purge_tag = (void *)8;
+ testrange = true;
+ test_purge(1, 4, 7, 0);
+
+ /* Try purging on specified sender, type, all tags. */
+ printf("testing purge on 3,5-6,0 expecting 10\n");
+ purge_sender = &senders[3];
+ purge_type_first = 5;
+ purge_type_last = 6;
+ purge_tag = NULL;
+ testrange = true;
+ test_purge(1, 4, 7, 10);
+}
+
+/*
+ * Helpers for purge event tests
+ */
+static void
+pge_event1(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ LOCK(&lock);
+ while (!started) {
+ WAIT(&cv, &lock);
+ }
+ UNLOCK(&lock);
+
+ isc_event_free(&event);
+}
+
+static void
+pge_event2(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ ++eventcnt;
+ isc_event_free(&event);
+}
+
+
+static void
+pge_sde(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ LOCK(&lock);
+ done = true;
+ SIGNAL(&cv);
+ UNLOCK(&lock);
+
+ isc_event_free(&event);
+}
+
+static void
+try_purgeevent(bool purgeable) {
+ isc_result_t result;
+ isc_task_t *task = NULL;
+ bool purged;
+ isc_event_t *event1 = NULL;
+ isc_event_t *event2 = NULL;
+ isc_event_t *event2_clone = NULL;;
+ isc_time_t now;
+ isc_interval_t interval;
+
+ started = false;
+ done = false;
+ eventcnt = 0;
+
+ result = isc_mutex_init(&lock);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_init(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_onshutdown(task, pge_sde, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /*
+ * Block the task on cv.
+ */
+ event1 = isc_event_allocate(mctx, (void *)1, (isc_eventtype_t)1,
+ pge_event1, NULL, sizeof(*event1));
+ ATF_REQUIRE(event1 != NULL);
+ isc_task_send(task, &event1);
+
+ event2 = isc_event_allocate(mctx, (void *)1, (isc_eventtype_t)1,
+ pge_event2, NULL, sizeof(*event2));
+ ATF_REQUIRE(event2 != NULL);
+
+ event2_clone = event2;
+
+ if (purgeable) {
+ event2->ev_attributes &= ~ISC_EVENTATTR_NOPURGE;
+ } else {
+ event2->ev_attributes |= ISC_EVENTATTR_NOPURGE;
+ }
+
+ isc_task_send(task, &event2);
+
+ purged = isc_task_purgeevent(task, event2_clone);
+ ATF_CHECK_EQ(purgeable, purged);
+
+ /*
+ * Unblock the task, allowing event processing.
+ */
+ LOCK(&lock);
+ started = true;
+ SIGNAL(&cv);
+
+ isc_task_shutdown(task);
+
+ isc_interval_set(&interval, 5, 0);
+
+ /*
+ * Wait for shutdown processing to complete.
+ */
+ while (!done) {
+ result = isc_time_nowplusinterval(&now, &interval);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ WAITUNTIL(&cv, &lock, &now);
+ }
+
+ UNLOCK(&lock);
+
+ isc_task_detach(&task);
+
+ isc_test_end();
+ DESTROYLOCK(&lock);
+ (void) isc_condition_destroy(&cv);
+
+ ATF_REQUIRE_EQ(eventcnt, (purgeable ? 0 : 1));
+}
+
+/*
+ * Purge event test:
+ * When the event is marked as purgeable, a call to
+ * isc_task_purgeevent(task, event) purges the event 'event' from the
+ * task's queue and returns true.
+ */
+
+ATF_TC(purgeevent);
+ATF_TC_HEAD(purgeevent, tc) {
+ atf_tc_set_md_var(tc, "descr", "purge-event");
+}
+ATF_TC_BODY(purgeevent, tc) {
+ try_purgeevent(true);
+}
+
+/*
+ * Purge event not purgeable test:
+ * When the event is not marked as purgable, a call to
+ * isc_task_purgeevent(task, event) does not purge the event
+ * 'event' from the task's queue and returns false.
+ */
+
+ATF_TC(purgeevent_notpurge);
+ATF_TC_HEAD(purgeevent_notpurge, tc) {
+ atf_tc_set_md_var(tc, "descr", "purge-event");
+}
+ATF_TC_BODY(purgeevent_notpurge, tc) {
+ try_purgeevent(false);
+}
+#endif
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, create_task);
+ ATF_TP_ADD_TC(tp, all_events);
+ ATF_TP_ADD_TC(tp, privileged_events);
+ ATF_TP_ADD_TC(tp, privilege_drop);
+ ATF_TP_ADD_TC(tp, basic);
+ ATF_TP_ADD_TC(tp, task_exclusive);
+
+#ifdef ISC_PLATFORM_USETHREADS
+ ATF_TP_ADD_TC(tp, manytasks);
+ ATF_TP_ADD_TC(tp, shutdown);
+ ATF_TP_ADD_TC(tp, post_shutdown);
+ ATF_TP_ADD_TC(tp, purge);
+ ATF_TP_ADD_TC(tp, purgerange);
+ ATF_TP_ADD_TC(tp, purgeevent);
+ ATF_TP_ADD_TC(tp, purgeevent_notpurge);
+#endif
+
+ return (atf_no_error());
+}
diff --git a/lib/isc/tests/taskpool_test.c b/lib/isc/tests/taskpool_test.c
new file mode 100644
index 0000000..ff2de9e
--- /dev/null
+++ b/lib/isc/tests/taskpool_test.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+
+#include <isc/task.h>
+#include <isc/taskpool.h>
+
+#include "isctest.h"
+
+/*
+ * Individual unit tests
+ */
+
+/* Create a taskpool */
+ATF_TC(create_pool);
+ATF_TC_HEAD(create_pool, tc) {
+ atf_tc_set_md_var(tc, "descr", "create a taskpool");
+}
+ATF_TC_BODY(create_pool, tc) {
+ isc_result_t result;
+ isc_taskpool_t *pool = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_taskpool_create(taskmgr, mctx, 8, 2, &pool);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_taskpool_size(pool), 8);
+
+ isc_taskpool_destroy(&pool);
+ ATF_REQUIRE_EQ(pool, NULL);
+
+ isc_test_end();
+}
+
+/* Resize a taskpool */
+ATF_TC(expand_pool);
+ATF_TC_HEAD(expand_pool, tc) {
+ atf_tc_set_md_var(tc, "descr", "expand a taskpool");
+}
+ATF_TC_BODY(expand_pool, tc) {
+ isc_result_t result;
+ isc_taskpool_t *pool1 = NULL, *pool2 = NULL, *hold = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_taskpool_create(taskmgr, mctx, 10, 2, &pool1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_taskpool_size(pool1), 10);
+
+ /* resizing to a smaller size should have no effect */
+ hold = pool1;
+ result = isc_taskpool_expand(&pool1, 5, &pool2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_taskpool_size(pool2), 10);
+ ATF_REQUIRE_EQ(pool2, hold);
+ ATF_REQUIRE_EQ(pool1, NULL);
+ pool1 = pool2;
+ pool2 = NULL;
+
+ /* resizing to the same size should have no effect */
+ hold = pool1;
+ result = isc_taskpool_expand(&pool1, 10, &pool2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_taskpool_size(pool2), 10);
+ ATF_REQUIRE_EQ(pool2, hold);
+ ATF_REQUIRE_EQ(pool1, NULL);
+ pool1 = pool2;
+ pool2 = NULL;
+
+ /* resizing to larger size should make a new pool */
+ hold = pool1;
+ result = isc_taskpool_expand(&pool1, 20, &pool2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_taskpool_size(pool2), 20);
+ ATF_REQUIRE(pool2 != hold);
+ ATF_REQUIRE_EQ(pool1, NULL);
+
+ isc_taskpool_destroy(&pool2);
+ ATF_REQUIRE_EQ(pool2, NULL);
+
+ isc_test_end();
+}
+
+/* Get tasks */
+ATF_TC(get_tasks);
+ATF_TC_HEAD(get_tasks, tc) {
+ atf_tc_set_md_var(tc, "descr", "create a taskpool");
+}
+ATF_TC_BODY(get_tasks, tc) {
+ isc_result_t result;
+ isc_taskpool_t *pool = NULL;
+ isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_taskpool_size(pool), 2);
+
+ /* two tasks in pool; make sure we can access them more than twice */
+ isc_taskpool_gettask(pool, &task1);
+ ATF_REQUIRE(ISCAPI_TASK_VALID(task1));
+
+ isc_taskpool_gettask(pool, &task2);
+ ATF_REQUIRE(ISCAPI_TASK_VALID(task2));
+
+ isc_taskpool_gettask(pool, &task3);
+ ATF_REQUIRE(ISCAPI_TASK_VALID(task3));
+
+ isc_task_destroy(&task1);
+ isc_task_destroy(&task2);
+ isc_task_destroy(&task3);
+
+ isc_taskpool_destroy(&pool);
+ ATF_REQUIRE_EQ(pool, NULL);
+
+ isc_test_end();
+}
+
+/* Get tasks */
+ATF_TC(set_privilege);
+ATF_TC_HEAD(set_privilege, tc) {
+ atf_tc_set_md_var(tc, "descr", "create a taskpool");
+}
+ATF_TC_BODY(set_privilege, tc) {
+ isc_result_t result;
+ isc_taskpool_t *pool = NULL;
+ isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 0);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_taskpool_size(pool), 2);
+
+ isc_taskpool_setprivilege(pool, true);
+
+ isc_taskpool_gettask(pool, &task1);
+ isc_taskpool_gettask(pool, &task2);
+ isc_taskpool_gettask(pool, &task3);
+
+ ATF_CHECK(ISCAPI_TASK_VALID(task1));
+ ATF_CHECK(ISCAPI_TASK_VALID(task2));
+ ATF_CHECK(ISCAPI_TASK_VALID(task3));
+
+ ATF_CHECK(isc_task_privilege(task1));
+ ATF_CHECK(isc_task_privilege(task2));
+ ATF_CHECK(isc_task_privilege(task3));
+
+ isc_taskpool_setprivilege(pool, false);
+
+ ATF_CHECK(!isc_task_privilege(task1));
+ ATF_CHECK(!isc_task_privilege(task2));
+ ATF_CHECK(!isc_task_privilege(task3));
+
+ isc_task_destroy(&task1);
+ isc_task_destroy(&task2);
+ isc_task_destroy(&task3);
+
+ isc_taskpool_destroy(&pool);
+ ATF_REQUIRE_EQ(pool, NULL);
+
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, create_pool);
+ ATF_TP_ADD_TC(tp, expand_pool);
+ ATF_TP_ADD_TC(tp, get_tasks);
+ ATF_TP_ADD_TC(tp, set_privilege);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/testdata/file/keep b/lib/isc/tests/testdata/file/keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/isc/tests/testdata/file/keep
diff --git a/lib/isc/tests/time_test.c b/lib/isc/tests/time_test.c
new file mode 100644
index 0000000..c548869
--- /dev/null
+++ b/lib/isc/tests/time_test.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#include <isc/time.h>
+#include <isc/result.h>
+
+ATF_TC(isc_time_parsehttptimestamp);
+ATF_TC_HEAD(isc_time_parsehttptimestamp, tc) {
+ atf_tc_set_md_var(tc, "descr", "parse http time stamp");
+}
+ATF_TC_BODY(isc_time_parsehttptimestamp, tc) {
+ isc_result_t result;
+ isc_time_t t, x;
+ char buf[ISC_FORMATHTTPTIMESTAMP_SIZE];
+
+ setenv("TZ", "PST8PDT", 1);
+ result = isc_time_now(&t);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_time_formathttptimestamp(&t, buf, sizeof(buf));
+ result = isc_time_parsehttptimestamp(buf, &x);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE_EQ(isc_time_seconds(&t), isc_time_seconds(&x));
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_time_parsehttptimestamp);
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/timer_test.c b/lib/isc/tests/timer_test.c
new file mode 100644
index 0000000..7a32f1d
--- /dev/null
+++ b/lib/isc/tests/timer_test.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+
+#include <isc/condition.h>
+#include <isc/mem.h>
+#include <isc/platform.h>
+#include <isc/print.h>
+#include <isc/task.h>
+#include <isc/time.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+#include <isc/util.h>
+
+#include "isctest.h"
+
+/*
+ * This entire test requires threads.
+ */
+#ifdef ISC_PLATFORM_USETHREADS
+
+/*
+ * Helper functions
+ */
+#define FUDGE_SECONDS 0 /* in absence of clock_getres() */
+#define FUDGE_NANOSECONDS 500000000 /* in absence of clock_getres() */
+
+static isc_timer_t *timer = NULL;
+static isc_condition_t cv;
+static isc_mutex_t mx;
+static isc_time_t endtime;
+static isc_time_t lasttime;
+static int seconds;
+static int nanoseconds;
+static int eventcnt;
+static int nevents;
+
+static void
+shutdown(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+
+ UNUSED(task);
+
+ /*
+ * Signal shutdown processing complete.
+ */
+ result = isc_mutex_lock(&mx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_signal(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_mutex_unlock(&mx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_event_free(&event);
+}
+
+static void
+setup_test(isc_timertype_t timertype, isc_time_t *expires,
+ isc_interval_t *interval,
+ void (*action)(isc_task_t *, isc_event_t *))
+{
+ isc_result_t result;
+ isc_task_t *task = NULL;
+ isc_time_settoepoch(&endtime);
+ eventcnt = 0;
+
+ result = isc_mutex_init(&mx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_init(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ LOCK(&mx);
+
+ result = isc_task_create(taskmgr, 0, &task);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_onshutdown(task, shutdown, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_time_now(&lasttime);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_timer_create(timermgr, timertype, expires, interval,
+ task, action, (void *)timertype,
+ &timer);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /*
+ * Wait for shutdown processing to complete.
+ */
+ while (eventcnt != nevents) {
+ result = isc_condition_wait(&cv, &mx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ }
+
+ UNLOCK(&mx);
+
+ isc_task_detach(&task);
+ DESTROYLOCK(&mx);
+ (void) isc_condition_destroy(&cv);
+}
+
+static void
+ticktock(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ isc_time_t now;
+ isc_time_t base;
+ isc_time_t ulim;
+ isc_time_t llim;
+ isc_interval_t interval;
+ isc_eventtype_t expected_event_type;
+
+ ++eventcnt;
+
+ printf("tick %d\n", eventcnt);
+
+ expected_event_type = ISC_TIMEREVENT_LIFE;
+ if ((isc_timertype_t) event->ev_arg == isc_timertype_ticker) {
+ expected_event_type = ISC_TIMEREVENT_TICK;
+ }
+
+ if (event->ev_type != expected_event_type) {
+ printf("expected event type %u, got %u\n",
+ expected_event_type, event->ev_type);
+ }
+
+ result = isc_time_now(&now);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, seconds, nanoseconds);
+ result = isc_time_add(&lasttime, &interval, &base);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
+ result = isc_time_add(&base, &interval, &ulim);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_time_subtract(&base, &interval, &llim);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_CHECK(isc_time_compare(&llim, &now) <= 0);
+ ATF_CHECK(isc_time_compare(&ulim, &now) >= 0);
+ lasttime = now;
+
+ if (eventcnt == nevents) {
+ result = isc_time_now(&endtime);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ isc_timer_detach(&timer);
+ isc_task_shutdown(task);
+ }
+
+ isc_event_free(&event);
+}
+
+/*
+ * Individual unit tests
+ */
+
+ATF_TC(ticker);
+ATF_TC_HEAD(ticker, tc) {
+ atf_tc_set_md_var(tc, "descr", "timer type ticker");
+}
+ATF_TC_BODY(ticker, tc) {
+ isc_result_t result;
+ isc_time_t expires;
+ isc_interval_t interval;
+
+ UNUSED(tc);
+
+ nevents = 12;
+ seconds = 0;
+ nanoseconds = 500000000;
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, seconds, nanoseconds);
+ isc_time_settoepoch(&expires);
+
+ setup_test(isc_timertype_ticker, &expires, &interval, ticktock);
+
+ isc_test_end();
+}
+
+ATF_TC(once_life);
+ATF_TC_HEAD(once_life, tc) {
+ atf_tc_set_md_var(tc, "descr", "timer type once reaches lifetime");
+}
+ATF_TC_BODY(once_life, tc) {
+ isc_result_t result;
+ isc_time_t expires;
+ isc_interval_t interval;
+
+ UNUSED(tc);
+
+ nevents = 1;
+ seconds = 1;
+ nanoseconds = 100000000;
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, seconds, nanoseconds);
+ result = isc_time_nowplusinterval(&expires, &interval);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, 0, 0);
+
+ setup_test(isc_timertype_once, &expires, &interval, ticktock);
+
+ isc_test_end();
+}
+
+
+static void
+test_idle(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ isc_time_t now;
+ isc_time_t base;
+ isc_time_t ulim;
+ isc_time_t llim;
+ isc_interval_t interval;
+
+ ++eventcnt;
+
+ printf("tick %d\n", eventcnt);
+
+ result = isc_time_now(&now);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, seconds, nanoseconds);
+ result = isc_time_add(&lasttime, &interval, &base);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
+ result = isc_time_add(&base, &interval, &ulim);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_time_subtract(&base, &interval, &llim);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_CHECK(isc_time_compare(&llim, &now) <= 0);
+ ATF_CHECK(isc_time_compare(&ulim, &now) >= 0);
+ lasttime = now;
+
+ ATF_CHECK_EQ(event->ev_type, ISC_TIMEREVENT_IDLE);
+
+ isc_timer_detach(&timer);
+ isc_task_shutdown(task);
+ isc_event_free(&event);
+}
+
+ATF_TC(once_idle);
+ATF_TC_HEAD(once_idle, tc) {
+ atf_tc_set_md_var(tc, "descr", "timer type once idles out");
+}
+ATF_TC_BODY(once_idle, tc) {
+ isc_result_t result;
+ isc_time_t expires;
+ isc_interval_t interval;
+
+ UNUSED(tc);
+
+ nevents = 1;
+ seconds = 1;
+ nanoseconds = 200000000;
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, seconds + 1, nanoseconds);
+ result = isc_time_nowplusinterval(&expires, &interval);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, seconds, nanoseconds);
+
+ setup_test(isc_timertype_once, &expires, &interval, test_idle);
+
+ isc_test_end();
+}
+
+static void
+test_reset(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ isc_time_t now;
+ isc_time_t base;
+ isc_time_t ulim;
+ isc_time_t llim;
+ isc_time_t expires;
+ isc_interval_t interval;
+
+ ++eventcnt;
+
+ printf("tick %d\n", eventcnt);
+
+ /*
+ * Check expired time.
+ */
+
+ result = isc_time_now(&now);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, seconds, nanoseconds);
+ result = isc_time_add(&lasttime, &interval, &base);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
+ result = isc_time_add(&base, &interval, &ulim);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_time_subtract(&base, &interval, &llim);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_CHECK(isc_time_compare(&llim, &now) <= 0);
+ ATF_CHECK(isc_time_compare(&ulim, &now) >= 0);
+ lasttime = now;
+
+ if (eventcnt < 3) {
+ ATF_CHECK_EQ(event->ev_type, ISC_TIMEREVENT_TICK);
+
+ if (eventcnt == 2) {
+ isc_interval_set(&interval, seconds, nanoseconds);
+ result = isc_time_nowplusinterval(&expires, &interval);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, 0, 0);
+ result = isc_timer_reset(timer, isc_timertype_once,
+ &expires, &interval,
+ false);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ }
+ } else {
+ ATF_CHECK_EQ(event->ev_type, ISC_TIMEREVENT_LIFE);
+
+ isc_timer_detach(&timer);
+ isc_task_shutdown(task);
+ }
+
+ isc_event_free(&event);
+}
+
+ATF_TC(reset);
+ATF_TC_HEAD(reset, tc) {
+ atf_tc_set_md_var(tc, "descr", "timer reset");
+}
+ATF_TC_BODY(reset, tc) {
+ isc_result_t result;
+ isc_time_t expires;
+ isc_interval_t interval;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ nevents = 3;
+ seconds = 0;
+ nanoseconds = 750000000;
+
+ isc_interval_set(&interval, seconds, nanoseconds);
+ isc_time_settoepoch(&expires);
+
+ setup_test(isc_timertype_ticker, &expires, &interval, test_reset);
+
+ isc_test_end();
+}
+
+static int startflag;
+static int shutdownflag;
+static isc_timer_t *tickertimer = NULL;
+static isc_timer_t *oncetimer = NULL;
+static isc_task_t *task1 = NULL;
+static isc_task_t *task2 = NULL;
+
+/*
+ * task1 blocks on mx while events accumulate
+ * in its queue, until signaled by task2.
+ */
+
+static void
+start_event(isc_task_t *task, isc_event_t *event) {
+ UNUSED(task);
+
+ printf("start_event\n");
+
+ LOCK(&mx);
+ while (! startflag) {
+ (void) isc_condition_wait(&cv, &mx);
+ }
+ UNLOCK(&mx);
+
+ isc_event_free(&event);
+}
+
+static void
+tick_event(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ isc_time_t expires;
+ isc_interval_t interval;
+
+ UNUSED(task);
+
+ ++eventcnt;
+ printf("tick_event %d\n", eventcnt);
+
+ /*
+ * On the first tick, purge all remaining tick events
+ * and then shut down the task.
+ */
+ if (eventcnt == 1) {
+ isc_time_settoepoch(&expires);
+ isc_interval_set(&interval, seconds, 0);
+ result = isc_timer_reset(tickertimer, isc_timertype_ticker,
+ &expires, &interval, true);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_task_shutdown(task);
+ }
+
+ isc_event_free(&event);
+}
+
+static void
+once_event(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+
+ printf("once_event\n");
+
+ /*
+ * Allow task1 to start processing events.
+ */
+ LOCK(&mx);
+ startflag = 1;
+
+ result = isc_condition_broadcast(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ UNLOCK(&mx);
+
+ isc_event_free(&event);
+ isc_task_shutdown(task);
+}
+
+static void
+shutdown_purge(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+
+ UNUSED(task);
+ UNUSED(event);
+
+ printf("shutdown_event\n");
+
+ /*
+ * Signal shutdown processing complete.
+ */
+ LOCK(&mx);
+ shutdownflag = 1;
+
+ result = isc_condition_signal(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ UNLOCK(&mx);
+
+ isc_event_free(&event);
+}
+
+ATF_TC(purge);
+ATF_TC_HEAD(purge, tc) {
+ atf_tc_set_md_var(tc, "descr", "timer events purged");
+}
+ATF_TC_BODY(purge, tc) {
+ isc_result_t result;
+ isc_event_t *event = NULL;
+ isc_time_t expires;
+ isc_interval_t interval;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, true, 2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ startflag = 0;
+ shutdownflag = 0;
+ eventcnt = 0;
+ seconds = 1;
+ nanoseconds = 0;
+
+ result = isc_mutex_init(&mx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_condition_init(&cv);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_onshutdown(task1, shutdown_purge, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_task_create(taskmgr, 0, &task2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ LOCK(&mx);
+
+ event = isc_event_allocate(mctx, (void *)1 , (isc_eventtype_t)1,
+ start_event, NULL, sizeof(*event));
+ ATF_REQUIRE(event != NULL);
+ isc_task_send(task1, &event);
+
+ isc_time_settoepoch(&expires);
+ isc_interval_set(&interval, seconds, 0);
+
+ tickertimer = NULL;
+ result = isc_timer_create(timermgr, isc_timertype_ticker,
+ &expires, &interval, task1,
+ tick_event, NULL, &tickertimer);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ oncetimer = NULL;
+
+ isc_interval_set(&interval, (seconds * 2) + 1, 0);
+ result = isc_time_nowplusinterval(&expires, &interval);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_interval_set(&interval, 0, 0);
+ result = isc_timer_create(timermgr, isc_timertype_once,
+ &expires, &interval, task2,
+ once_event, NULL, &oncetimer);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /*
+ * Wait for shutdown processing to complete.
+ */
+ while (! shutdownflag) {
+ result = isc_condition_wait(&cv, &mx);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ }
+
+ UNLOCK(&mx);
+
+ ATF_CHECK_EQ(eventcnt, 1);
+
+ isc_timer_detach(&tickertimer);
+ isc_timer_detach(&oncetimer);
+ isc_task_destroy(&task1);
+ isc_task_destroy(&task2);
+ DESTROYLOCK(&mx);
+
+ isc_test_end();
+}
+#else
+ATF_TC(untested);
+ATF_TC_HEAD(untested, tc) {
+ atf_tc_set_md_var(tc, "descr", "skipping nsec3 test");
+}
+ATF_TC_BODY(untested, tc) {
+ UNUSED(tc);
+ atf_tc_skip("DNSSEC not available");
+}
+#endif
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+#ifdef ISC_PLATFORM_USETHREADS
+ ATF_TP_ADD_TC(tp, ticker);
+ ATF_TP_ADD_TC(tp, once_life);
+ ATF_TP_ADD_TC(tp, once_idle);
+ ATF_TP_ADD_TC(tp, reset);
+ ATF_TP_ADD_TC(tp, purge);
+#else
+ ATF_TP_ADD_TC(tp, untested);
+#endif
+
+ return (atf_no_error());
+}