Blame inet/idna_name_classify.c

Packit Service 82fcde
/* Classify a domain name for IDNA purposes.
Packit Service 82fcde
   Copyright (C) 2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <inet/net-internal.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <wchar.h>
Packit Service 82fcde
Packit Service 82fcde
enum idna_name_classification
Packit Service 82fcde
__idna_name_classify (const char *name)
Packit Service 82fcde
{
Packit Service 82fcde
  mbstate_t mbs;
Packit Service 82fcde
  memset (&mbs, 0, sizeof (mbs));
Packit Service 82fcde
  const char *p = name;
Packit Service 82fcde
  const char *end = p + strlen (p) + 1;
Packit Service 82fcde
  bool nonascii = false;
Packit Service 82fcde
  bool backslash = false;
Packit Service 82fcde
  while (true)
Packit Service 82fcde
    {
Packit Service 82fcde
      wchar_t wc;
Packit Service 82fcde
      size_t result = mbrtowc (&wc, p, end - p, &mbs);
Packit Service 82fcde
      if (result == 0)
Packit Service 82fcde
        /* NUL terminator was reached.  */
Packit Service 82fcde
        break;
Packit Service 82fcde
      else if (result == (size_t) -2)
Packit Service 82fcde
        /* Incomplete trailing multi-byte character.  This is an
Packit Service 82fcde
           encoding error becaue we received the full name.  */
Packit Service 82fcde
        return idna_name_encoding_error;
Packit Service 82fcde
      else if (result == (size_t) -1)
Packit Service 82fcde
        {
Packit Service 82fcde
          /* Other error, including EILSEQ.  */
Packit Service 82fcde
          if (errno == EILSEQ)
Packit Service 82fcde
            return idna_name_encoding_error;
Packit Service 82fcde
          else if (errno == ENOMEM)
Packit Service 82fcde
            return idna_name_memory_error;
Packit Service 82fcde
          else
Packit Service 82fcde
            return idna_name_error;
Packit Service 82fcde
        }
Packit Service 82fcde
      else
Packit Service 82fcde
        {
Packit Service 82fcde
          /* A wide character was decoded.  */
Packit Service 82fcde
          p += result;
Packit Service 82fcde
          if (wc == L'\\')
Packit Service 82fcde
            backslash = true;
Packit Service 82fcde
          else if (wc > 127)
Packit Service 82fcde
            nonascii = true;
Packit Service 82fcde
        }
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (nonascii)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (backslash)
Packit Service 82fcde
        return idna_name_nonascii_backslash;
Packit Service 82fcde
      else
Packit Service 82fcde
        return idna_name_nonascii;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    return idna_name_ascii;
Packit Service 82fcde
}