978e96
commit 5c1a69238fcb87ff7f916a5ce7960b2864afb3a1
978e96
Author: Florian Weimer <fweimer@redhat.com>
978e96
Date:   Sat Nov 11 11:23:40 2017 +0100
978e96
978e96
    resolv: Add tst-res_hnok
978e96
978e96
diff --git a/resolv/Makefile b/resolv/Makefile
978e96
index 988871086a70b291..b1fd2e2db8736f9b 100644
978e96
--- a/resolv/Makefile
978e96
+++ b/resolv/Makefile
978e96
@@ -50,6 +50,7 @@ tests += \
978e96
   tst-ns_name \
978e96
   tst-ns_name_compress \
978e96
   tst-res_hconf_reorder \
978e96
+  tst-res_hnok \
978e96
   tst-res_use_inet6 \
978e96
   tst-resolv-basic \
978e96
   tst-resolv-edns \
978e96
@@ -182,6 +183,7 @@ $(objpfx)tst-resolv-canonname: \
978e96
 $(objpfx)tst-ns_name: $(objpfx)libresolv.so
978e96
 $(objpfx)tst-ns_name.out: tst-ns_name.data
978e96
 $(objpfx)tst-ns_name_compress: $(objpfx)libresolv.so
978e96
+$(objpfx)tst-res_hnok: $(objpfx)libresolv.so
978e96
 
978e96
 
978e96
 # This test case uses the deprecated RES_USE_INET6 resolver option.
978e96
diff --git a/resolv/tst-res_hnok.c b/resolv/tst-res_hnok.c
978e96
new file mode 100644
978e96
index 0000000000000000..9c923038218e965c
978e96
--- /dev/null
978e96
+++ b/resolv/tst-res_hnok.c
978e96
@@ -0,0 +1,153 @@
978e96
+/* Tests for res_hnok and related functions.
978e96
+   Copyright (C) 2017 Free Software Foundation, Inc.
978e96
+   This file is part of the GNU C Library.
978e96
+
978e96
+   The GNU C Library is free software; you can redistribute it and/or
978e96
+   modify it under the terms of the GNU Lesser General Public
978e96
+   License as published by the Free Software Foundation; either
978e96
+   version 2.1 of the License, or (at your option) any later version.
978e96
+
978e96
+   The GNU C Library is distributed in the hope that it will be useful,
978e96
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
978e96
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
978e96
+   Lesser General Public License for more details.
978e96
+
978e96
+   You should have received a copy of the GNU Lesser General Public
978e96
+   License along with the GNU C Library; if not, see
978e96
+   <http://www.gnu.org/licenses/>.  */
978e96
+
978e96
+#include <array_length.h>
978e96
+#include <resolv.h>
978e96
+#include <string.h>
978e96
+#include <support/check.h>
978e96
+#include <support/test-driver.h>
978e96
+
978e96
+/* Bits which indicate which functions are supposed to report
978e96
+   success.  */
978e96
+enum
978e96
+  {
978e96
+    hnok = 1,
978e96
+    dnok = 2,
978e96
+    mailok = 4,
978e96
+    ownok = 8,
978e96
+    allnomailok = hnok | dnok | ownok,
978e96
+    allok = hnok | dnok | mailok | ownok
978e96
+  };
978e96
+
978e96
+/* A string of 60 characters.  */
978e96
+#define STRING60 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
978e96
+
978e96
+/* A string of 63 characters (maximum label length).  */
978e96
+#define STRING63 STRING60 "zzz"
978e96
+
978e96
+/* Combines a test name with the expected results.  */
978e96
+struct test_case
978e96
+{
978e96
+  const char *dn;
978e96
+  unsigned int result;          /* Combination of the *ok flags.  */
978e96
+};
978e96
+
978e96
+static const struct test_case tests[] =
978e96
+  {
978e96
+    { "", allok },
978e96
+    { ".", allok },
978e96
+    { "www", allnomailok },
978e96
+    { "example", allnomailok },
978e96
+    { "example.com", allok },
978e96
+    { "www.example.com", allok },
978e96
+    { "www.example.com.", allok },
978e96
+    { "*.example.com", dnok | mailok | ownok },
978e96
+    { "-v", dnok },
978e96
+    { "-v.example.com", mailok | dnok },
978e96
+    { "**.example.com", dnok | mailok },
978e96
+    { STRING63, allnomailok },
978e96
+    { STRING63 ".example.com", allok },
978e96
+    { STRING63 "." STRING63 "." STRING63 "." STRING60 "z", allok },
978e96
+    { "hostmaster@mail.example.com", dnok | mailok },
978e96
+    { "with whitespace", 0 },
978e96
+    { "with\twhitespace", 0 },
978e96
+    { "with\nwhitespace", 0 },
978e96
+    { "with.whitespace ", 0 },
978e96
+    { "with.whitespace\t", 0 },
978e96
+    { "with.whitespace\n", 0 },
978e96
+    { "with\\ whitespace", 0 },
978e96
+    { "with\\\twhitespace", 0 },
978e96
+    { "with\\\nwhitespace", 0 },
978e96
+    { "with.whitespace\\ ", 0 },
978e96
+    { "with.whitespace\\\t", 0 },
978e96
+    { "with.whitespace\\\n", 0 },
978e96
+  };
978e96
+
978e96
+/* Run test case *TEST with FUNC (named FUNCNAME) and report an error
978e96
+   if the result does not match the result flag at BIT.  */
978e96
+static void
978e96
+one_test (const struct test_case *test, const char *funcname,
978e96
+          int (*func) (const char *), unsigned int bit)
978e96
+{
978e96
+  int expected = (test->result & bit) != 0;
978e96
+  int actual = func (test->dn);
978e96
+  if (actual != expected)
978e96
+    {
978e96
+      support_record_failure ();
978e96
+      printf ("error: %s (\"%s\"): expected=%d, actual=%d\n",
978e96
+              funcname, test->dn, expected, actual);
978e96
+    }
978e96
+}
978e96
+
978e96
+/* Run 255 tests using all the bytes from 1 to 255, surround the byte
978e96
+   with the strings PREFIX and SUFFIX, and check that FUNC (named
978e96
+   FUNCNAME) accepts only those bytes listed in ACCEPTED.  */
978e96
+static void
978e96
+one_char (const char *prefix, const char *accepted, const char *suffix,
978e96
+          const char *funcname, int (*func) (const char *))
978e96
+{
978e96
+  for (int ch = 1; ch <= 255; ++ch)
978e96
+    {
978e96
+      char dn[1024];
978e96
+      snprintf (dn, sizeof (dn), "%s%c%s", prefix, ch, suffix);
978e96
+      int expected = strchr (accepted, ch) != NULL;
978e96
+      int actual = func (dn);
978e96
+      if (actual != expected)
978e96
+        {
978e96
+          support_record_failure ();
978e96
+          printf ("error: %s (\"%s\"): expected=%d, actual=%d\n",
978e96
+                  funcname, dn, expected, actual);
978e96
+        }
978e96
+    }
978e96
+}
978e96
+
978e96
+static int
978e96
+do_test (void)
978e96
+{
978e96
+  for (const struct test_case *test = tests; test < array_end (tests); ++test)
978e96
+    {
978e96
+      if (test_verbose)
978e96
+        printf ("info: testing domain name [[[%s]]] (0x%x)\n",
978e96
+                test->dn, test->result);
978e96
+      one_test (test, "res_hnok", res_hnok, hnok);
978e96
+      one_test (test, "res_dnok", res_dnok, dnok);
978e96
+      one_test (test, "res_mailok", res_mailok, mailok);
978e96
+      one_test (test, "res_ownok", res_ownok, ownok);
978e96
+    }
978e96
+
978e96
+  one_char
978e96
+    ("", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.",
978e96
+     "", "res_hnok", res_hnok);
978e96
+  one_char
978e96
+    ("middle",
978e96
+     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
978e96
+     "suffix", "res_hnok", res_hnok);
978e96
+  one_char
978e96
+    ("middle",
978e96
+     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_"
978e96
+     "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~",
978e96
+     "suffix.example", "res_mailok", res_mailok);
978e96
+  one_char
978e96
+    ("mailbox.middle",
978e96
+     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
978e96
+     "suffix.example", "res_mailok", res_mailok);
978e96
+
978e96
+  return 0;
978e96
+}
978e96
+
978e96
+#include <support/test-driver.c>