/* Test ns_name-related functions.
   Copyright (C) 2017-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

/* This test program processes the tst-ns_name.data file.  */

#include <ctype.h>
#include <resolv.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/support.h>
#include <support/xstdio.h>

/* A byte buffer and its length.  */
struct buffer
{
  unsigned char *data;
  size_t length;
};

/* Convert a base64-encoded string to its binary representation.  */
static bool
base64_to_buffer (const char *base64, struct buffer *result)
{
  /* "-" denotes an empty input.  */
  if (strcmp (base64, "-") == 0)
    {
      result->data = xmalloc (1);
      result->length = 0;
      return true;
    }

  size_t size = strlen (base64);
  unsigned char *data = xmalloc (size);
  int ret = b64_pton (base64, data, size);
  if (ret < 0 || ret > size)
    return false;
  result->data = xrealloc (data, ret);
  result->length = ret;
  return true;
}

/* A test case for ns_name_unpack and ns_name_ntop.  */
struct test_case
{
  char *path;
  size_t lineno;
  struct buffer input;
  size_t input_offset;
  int unpack_result;
  struct buffer unpack_output;
  int ntop_result;
  char *ntop_text;
};

/* Deallocate the buffers associated with the test case.  */
static void
free_test_case (struct test_case *t)
{
  free (t->path);
  free (t->input.data);
  free (t->unpack_output.data);
  free (t->ntop_text);
}

/* Extract the test case information from a test file line.  */
static bool
parse_test_case (const char *path, size_t lineno, const char *line,
                 struct test_case *result)
{
  memset (result, 0, sizeof (*result));
  result->path = xstrdup (path);
  result->lineno = lineno;
  result->ntop_result = -1;
  char *input = NULL;
  char *unpack_output = NULL;
  int ret = sscanf (line, "%ms %zu %d %ms %d %ms",
                    &input, &result->input_offset,
                    &result->unpack_result, &unpack_output,
                    &result->ntop_result, &result->ntop_text);
  if (ret < 3)
    {
      printf ("%s:%zu: error: missing input fields\n", path, lineno);
      free (input);
      return false;
    }
  if (!base64_to_buffer (input, &result->input))
    {
      printf ("%s:%zu: error: malformed base64 input data\n", path, lineno);
      free (input);
      free (unpack_output);
      free (result->ntop_text);
      return false;
    }
  free (input);

  if (unpack_output == NULL)
    result->unpack_output = (struct buffer) { NULL, 0 };
  else if (!base64_to_buffer (unpack_output, &result->unpack_output))
    {
      printf ("%s:%zu: error: malformed base64 unpack data\n", path, lineno);
      free (result->input.data);
      free (unpack_output);
      free (result->ntop_text);
      return false;
    }
  free (unpack_output);

  /* At this point, all allocated buffers have been transferred to
     *result.  */

  if (result->input_offset > result->input.length)
    {
      printf ("%s:%zu: error: input offset %zu exceeds buffer size %zu\n",
              path, lineno, result->input_offset, result->input.length);
      free_test_case (result);
      return false;
    }
  if (result->unpack_result < -1)
    {
      printf ("%s:%zu: error: invalid unpack result %d\n",
              path, lineno, result->unpack_result);
      free_test_case (result);
      return false;
    }
  if (result->ntop_result < -1)
    {
      printf ("%s:%zu: error: invalid ntop result %d\n",
              path, lineno, result->ntop_result);
      free_test_case (result);
      return false;
    }

  bool fields_consistent;
  switch (ret)
    {
    case 3:
      fields_consistent = result->unpack_result == -1;
      break;
    case 5:
      fields_consistent = result->unpack_result != -1
        && result->ntop_result == -1;
      break;
    case 6:
      fields_consistent = result->unpack_result != -1
        && result->ntop_result != -1;
      break;
    default:
      fields_consistent = false;
    }
  if (!fields_consistent)
    {
      printf ("%s:%zu: error: wrong number of fields: %d\n",
              path, lineno, ret);
      free_test_case (result);
      return false;
    }
  return true;
}

/* Format the buffer as a hexadecimal string and write it to standard
   output.  */
static void
print_hex (const char *label, struct buffer buffer)
{
  printf ("  %s ", label);
  unsigned char *p = buffer.data;
  unsigned char *end = p + buffer.length;
  while (p < end)
    {
      printf ("%02X", *p & 0xFF);
      ++p;
    }
  putchar ('\n');
}

/* Run the test case specified in *T.  */
static void
run_test_case (struct test_case *t)
{
  /* Test ns_name_unpack.  */
  unsigned char *unpacked = xmalloc (NS_MAXCDNAME);
  int consumed = ns_name_unpack
    (t->input.data, t->input.data + t->input.length,
     t->input.data + t->input_offset,
     unpacked, NS_MAXCDNAME);
  if (consumed != t->unpack_result)
    {
      support_record_failure ();
      printf ("%s:%zu: error: wrong result from ns_name_unpack\n"
              "  expected: %d\n"
              "  actual:   %d\n",
              t->path, t->lineno, t->unpack_result, consumed);
      return;
    }
  if (consumed != -1)
    {
      if (memcmp (unpacked, t->unpack_output.data,
                  t->unpack_output.length) != 0)
        {
          support_record_failure ();
          printf ("%s:%zu: error: wrong data from ns_name_unpack\n",
                  t->path, t->lineno);
          print_hex ("expected:", t->unpack_output);
          print_hex ("actual:  ",
                     (struct buffer) { unpacked, t->unpack_output.length });
          return;
        }

      /* Test ns_name_ntop.  */
      char *text = xmalloc (NS_MAXDNAME);
      int ret = ns_name_ntop (unpacked, text, NS_MAXDNAME);
      if (ret != t->ntop_result)
        {
          support_record_failure ();
          printf ("%s:%zu: error: wrong result from ns_name_top\n"
                  "  expected: %d\n"
                  "  actual:   %d\n",
                  t->path, t->lineno, t->ntop_result, ret);
          return;
        }
      if (ret != -1)
        {
          if (strcmp (text, t->ntop_text) != 0)
            {
              support_record_failure ();
              printf ("%s:%zu: error: wrong data from ns_name_ntop\n",
                      t->path, t->lineno);
              printf ("  expected: \"%s\"\n", t->ntop_text);
              printf ("  actual:   \"%s\"\n", text);
              return;
            }

          /* Test ns_name_pton.  Unpacking does not check the
             NS_MAXCDNAME limit, but packing does, so we need to
             adjust the expected result.  */
          int expected;
          if (t->unpack_output.length > NS_MAXCDNAME)
            expected = -1;
          else if (strcmp (text, ".") == 0)
            /* The root domain is fully qualified.  */
            expected = 1;
          else
            /* The domain name is never fully qualified.  */
            expected = 0;
          unsigned char *repacked = xmalloc (NS_MAXCDNAME);
          ret = ns_name_pton (text, repacked, NS_MAXCDNAME);
          if (ret != expected)
            {
              support_record_failure ();
              printf ("%s:%zu: error: wrong result from ns_name_pton\n"
                      "  expected: %d\n"
                      "  actual:   %d\n",
                      t->path, t->lineno, expected, ret);
              return;
            }
          if (ret >= 0
              && memcmp (repacked, unpacked, t->unpack_output.length) != 0)
            {
              support_record_failure ();
              printf ("%s:%zu: error: wrong data from ns_name_pton\n",
                      t->path, t->lineno);
              print_hex ("expected:", t->unpack_output);
              print_hex ("actual:  ",
                         (struct buffer) { repacked, t->unpack_output.length });
              return;
            }

          /* Test ns_name_compress, no compression case.  */
          if (t->unpack_output.length > NS_MAXCDNAME)
            expected = -1;
          else
            expected = t->unpack_output.length;
          memset (repacked, '$', NS_MAXCDNAME);
          {
            enum { ptr_count = 5 };
            const unsigned char *dnptrs[ptr_count] = { repacked, };
            ret = ns_name_compress (text, repacked, NS_MAXCDNAME,
                                    dnptrs, dnptrs + ptr_count);
            if (ret != expected)
              {
                support_record_failure ();
                printf ("%s:%zu: error: wrong result from ns_name_compress\n"
                        "  expected: %d\n"
                        "  actual:   %d\n",
                        t->path, t->lineno, expected, ret);
                return;
              }
            if (ret < 0)
              {
                TEST_VERIFY (dnptrs[0] == repacked);
                TEST_VERIFY (dnptrs[1] == NULL);
              }
            else
              {
                if (memcmp (repacked, unpacked, t->unpack_output.length) != 0)
                  {
                    support_record_failure ();
                    printf ("%s:%zu: error: wrong data from ns_name_compress\n",
                            t->path, t->lineno);
                    print_hex ("expected:", t->unpack_output);
                    print_hex ("actual:  ", (struct buffer) { repacked, ret });
                    return;
                  }
                TEST_VERIFY (dnptrs[0] == repacked);
                if (unpacked[0] == '\0')
                  /* The root domain is not a compression target.  */
                  TEST_VERIFY (dnptrs[1] == NULL);
                else
                  {
                    TEST_VERIFY (dnptrs[1] == repacked);
                    TEST_VERIFY (dnptrs[2] == NULL);
                  }
              }
          }

          /* Test ns_name_compress, full compression case.  Skip this
             test for invalid names and the root domain.  */
          if (expected >= 0 && unpacked[0] != '\0')
            {
              /* The destination buffer needs additional room for the
                 offset, the initial name, and the compression
                 reference.  */
              enum { name_offset = 259 };
              size_t target_offset = name_offset + t->unpack_output.length;
              size_t repacked_size = target_offset + 2;
              repacked = xrealloc (repacked, repacked_size);
              memset (repacked, '@', repacked_size);
              memcpy (repacked + name_offset,
                      t->unpack_output.data, t->unpack_output.length);
              enum { ptr_count = 5 };
              const unsigned char *dnptrs[ptr_count]
                = { repacked, repacked + name_offset, };
              ret = ns_name_compress
                (text, repacked + target_offset, NS_MAXCDNAME,
                 dnptrs, dnptrs + ptr_count);
              if (ret != 2)
                {
                  support_record_failure ();
                  printf ("%s:%zu: error: wrong result from ns_name_compress"
                          " (2)\n"
                          "  expected: 2\n"
                          "  actual:   %d\n",
                          t->path, t->lineno, ret);
                  return;
                }
              if (memcmp (repacked + target_offset, "\xc1\x03", 2) != 0)
                {
                  support_record_failure ();
                  printf ("%s:%zu: error: wrong data from ns_name_compress"
                          " (2)\n"
                          "  expected: C103\n",
                          t->path, t->lineno);
                  print_hex ("actual:  ",
                             (struct buffer) { repacked + target_offset, ret });
                  return;
                }
              TEST_VERIFY (dnptrs[0] == repacked);
              TEST_VERIFY (dnptrs[1] == repacked + name_offset);
              TEST_VERIFY (dnptrs[2] == NULL);
            }

          free (repacked);
        }
      free (text);
    }
  free (unpacked);
}

/* Open the file at PATH, parse the test cases contained in it, and
   run them.  */
static void
run_test_file (const char *path)
{
  FILE *fp = xfopen (path, "re");
  char *line = NULL;
  size_t line_allocated = 0;
  size_t lineno = 0;

  while (true)
    {
      ssize_t ret = getline (&line, &line_allocated, fp);
      if (ret < 0)
        {
          if (ferror (fp))
            {
              printf ("%s: error reading file: %m\n", path);
              exit (1);
            }
          TEST_VERIFY (feof (fp));
          break;
        }

      ++lineno;
      char *p = line;
      while (isspace (*p))
        ++p;
      if (*p == '\0' || *p == '#')
        continue;

      struct test_case test_case;
      if (!parse_test_case (path, lineno, line, &test_case))
        {
          support_record_failure ();
          continue;
        }
      run_test_case (&test_case);
      free_test_case (&test_case);
    }
  free (line);
  xfclose (fp);
}

static int
do_test (void)
{
  run_test_file ("tst-ns_name.data");
  return 0;
}

#include <support/test-driver.c>
