LCOV - code coverage report
Current view: top level - lib - idna.c (source / functions) Hit Total Coverage
Test: GNU Libidn Lines: 181 243 74.5 %
Date: 2014-08-10 Functions: 8 11 72.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 118 170 69.4 %

           Branch data     Line data    Source code
       1                 :            : /* idna.c --- Prototypes for Internationalized Domain Name library.
       2                 :            :    Copyright (C) 2002-2014 Simon Josefsson
       3                 :            : 
       4                 :            :    This file is part of GNU Libidn.
       5                 :            : 
       6                 :            :    GNU Libidn is free software: you can redistribute it and/or
       7                 :            :    modify it under the terms of either:
       8                 :            : 
       9                 :            :      * the GNU Lesser General Public License as published by the Free
      10                 :            :        Software Foundation; either version 3 of the License, or (at
      11                 :            :        your option) any later version.
      12                 :            : 
      13                 :            :    or
      14                 :            : 
      15                 :            :      * the GNU General Public License as published by the Free
      16                 :            :        Software Foundation; either version 2 of the License, or (at
      17                 :            :        your option) any later version.
      18                 :            : 
      19                 :            :    or both in parallel, as here.
      20                 :            : 
      21                 :            :    GNU Libidn is distributed in the hope that it will be useful,
      22                 :            :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      23                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      24                 :            :    General Public License for more details.
      25                 :            : 
      26                 :            :    You should have received copies of the GNU General Public License and
      27                 :            :    the GNU Lesser General Public License along with this program.  If
      28                 :            :    not, see <http://www.gnu.org/licenses/>. */
      29                 :            : 
      30                 :            : #ifdef HAVE_CONFIG_H
      31                 :            : # include "config.h"
      32                 :            : #endif
      33                 :            : 
      34                 :            : #include <stdlib.h>
      35                 :            : #include <string.h>
      36                 :            : #include <stringprep.h>
      37                 :            : #include <punycode.h>
      38                 :            : 
      39                 :            : #include "idna.h"
      40                 :            : 
      41                 :            : /* Get c_strcasecmp. */
      42                 :            : #include <c-strcase.h>
      43                 :            : 
      44                 :            : #define DOTP(c) ((c) == 0x002E || (c) == 0x3002 ||      \
      45                 :            :                  (c) == 0xFF0E || (c) == 0xFF61)
      46                 :            : 
      47                 :            : /* Core functions */
      48                 :            : 
      49                 :            : /**
      50                 :            :  * idna_to_ascii_4i:
      51                 :            :  * @in: input array with unicode code points.
      52                 :            :  * @inlen: length of input array with unicode code points.
      53                 :            :  * @out: output zero terminated string that must have room for at
      54                 :            :  *       least 63 characters plus the terminating zero.
      55                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
      56                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
      57                 :            :  *
      58                 :            :  * The ToASCII operation takes a sequence of Unicode code points that
      59                 :            :  * make up one domain label and transforms it into a sequence of code
      60                 :            :  * points in the ASCII range (0..7F). If ToASCII succeeds, the
      61                 :            :  * original sequence and the resulting sequence are equivalent labels.
      62                 :            :  *
      63                 :            :  * It is important to note that the ToASCII operation can fail. ToASCII
      64                 :            :  * fails if any step of it fails. If any step of the ToASCII operation
      65                 :            :  * fails on any label in a domain name, that domain name MUST NOT be used
      66                 :            :  * as an internationalized domain name. The method for deadling with this
      67                 :            :  * failure is application-specific.
      68                 :            :  *
      69                 :            :  * The inputs to ToASCII are a sequence of code points, the AllowUnassigned
      70                 :            :  * flag, and the UseSTD3ASCIIRules flag. The output of ToASCII is either a
      71                 :            :  * sequence of ASCII code points or a failure condition.
      72                 :            :  *
      73                 :            :  * ToASCII never alters a sequence of code points that are all in the ASCII
      74                 :            :  * range to begin with (although it could fail). Applying the ToASCII
      75                 :            :  * operation multiple times has exactly the same effect as applying it just
      76                 :            :  * once.
      77                 :            :  *
      78                 :            :  * Return value: Returns 0 on success, or an #Idna_rc error code.
      79                 :            :  */
      80                 :            : int
      81                 :        221 : idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags)
      82                 :            : {
      83                 :            :   size_t len, outlen;
      84                 :            :   uint32_t *src;                /* XXX don't need to copy data? */
      85                 :            :   int rc;
      86                 :            : 
      87                 :            :   /*
      88                 :            :    * ToASCII consists of the following steps:
      89                 :            :    *
      90                 :            :    * 1. If all code points in the sequence are in the ASCII range (0..7F)
      91                 :            :    * then skip to step 3.
      92                 :            :    */
      93                 :            : 
      94                 :            :   {
      95                 :            :     size_t i;
      96                 :            :     int inasciirange;
      97                 :            : 
      98                 :        221 :     inasciirange = 1;
      99         [ +  + ]:       2089 :     for (i = 0; i < inlen; i++)
     100         [ +  + ]:       1868 :       if (in[i] > 0x7F)
     101                 :        786 :         inasciirange = 0;
     102         [ +  + ]:        221 :     if (inasciirange)
     103                 :            :       {
     104                 :         74 :         src = malloc (sizeof (in[0]) * (inlen + 1));
     105         [ -  + ]:         74 :         if (src == NULL)
     106                 :          0 :           return IDNA_MALLOC_ERROR;
     107                 :            : 
     108                 :         74 :         memcpy (src, in, sizeof (in[0]) * inlen);
     109                 :         74 :         src[inlen] = 0;
     110                 :            : 
     111                 :         74 :         goto step3;
     112                 :            :       }
     113                 :            :   }
     114                 :            : 
     115                 :            :   /*
     116                 :            :    * 2. Perform the steps specified in [NAMEPREP] and fail if there is
     117                 :            :    * an error. The AllowUnassigned flag is used in [NAMEPREP].
     118                 :            :    */
     119                 :            : 
     120                 :            :   {
     121                 :            :     char *p;
     122                 :            : 
     123                 :        147 :     p = stringprep_ucs4_to_utf8 (in, (ssize_t) inlen, NULL, NULL);
     124         [ -  + ]:        147 :     if (p == NULL)
     125                 :          0 :       return IDNA_MALLOC_ERROR;
     126                 :            : 
     127                 :        147 :     len = strlen (p);
     128                 :            :     do
     129                 :            :       {
     130                 :            :         char *newp;
     131                 :            : 
     132                 :        147 :         len = 2 * len + 10;     /* XXX better guess? */
     133                 :        147 :         newp = realloc (p, len);
     134         [ -  + ]:        147 :         if (newp == NULL)
     135                 :            :           {
     136                 :          0 :             free (p);
     137                 :          0 :             return IDNA_MALLOC_ERROR;
     138                 :            :           }
     139                 :        147 :         p = newp;
     140                 :            : 
     141         [ +  + ]:        147 :         if (flags & IDNA_ALLOW_UNASSIGNED)
     142                 :         98 :           rc = stringprep_nameprep (p, len);
     143                 :            :         else
     144                 :         49 :           rc = stringprep_nameprep_no_unassigned (p, len);
     145                 :            :       }
     146         [ -  + ]:        147 :     while (rc == STRINGPREP_TOO_SMALL_BUFFER);
     147                 :            : 
     148         [ +  + ]:        147 :     if (rc != STRINGPREP_OK)
     149                 :            :       {
     150                 :         17 :         free (p);
     151                 :         17 :         return IDNA_STRINGPREP_ERROR;
     152                 :            :       }
     153                 :            : 
     154                 :        130 :     src = stringprep_utf8_to_ucs4 (p, -1, NULL);
     155                 :            : 
     156                 :        130 :     free (p);
     157                 :            : 
     158         [ -  + ]:        130 :     if (!src)
     159                 :          0 :       return IDNA_MALLOC_ERROR;
     160                 :            :   }
     161                 :            : 
     162                 :            : step3:
     163                 :            :   /*
     164                 :            :    * 3. If the UseSTD3ASCIIRules flag is set, then perform these checks:
     165                 :            :    *
     166                 :            :    * (a) Verify the absence of non-LDH ASCII code points; that is,
     167                 :            :    * the absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F.
     168                 :            :    *
     169                 :            :    * (b) Verify the absence of leading and trailing hyphen-minus;
     170                 :            :    * that is, the absence of U+002D at the beginning and end of
     171                 :            :    * the sequence.
     172                 :            :    */
     173                 :            : 
     174         [ +  + ]:        204 :   if (flags & IDNA_USE_STD3_ASCII_RULES)
     175                 :            :     {
     176                 :            :       size_t i;
     177                 :            : 
     178         [ +  + ]:       1057 :       for (i = 0; src[i]; i++)
     179 [ +  + ][ +  - ]:        915 :         if (src[i] <= 0x2C || src[i] == 0x2E || src[i] == 0x2F ||
         [ +  - ][ +  + ]
     180 [ +  + ][ +  + ]:        910 :             (src[i] >= 0x3A && src[i] <= 0x40) ||
     181 [ +  - ][ +  + ]:        909 :             (src[i] >= 0x5B && src[i] <= 0x60) ||
     182         [ -  + ]:        170 :             (src[i] >= 0x7B && src[i] <= 0x7F))
     183                 :            :           {
     184                 :          6 :             free (src);
     185                 :          6 :             return IDNA_CONTAINS_NON_LDH;
     186                 :            :           }
     187                 :            : 
     188 [ +  + ][ +  - ]:        142 :       if (src[0] == 0x002D || (i > 0 && src[i - 1] == 0x002D))
                 [ +  + ]
     189                 :            :         {
     190                 :          4 :           free (src);
     191                 :          4 :           return IDNA_CONTAINS_MINUS;
     192                 :            :         }
     193                 :            :     }
     194                 :            : 
     195                 :            :   /*
     196                 :            :    * 4. If all code points in the sequence are in the ASCII range
     197                 :            :    * (0..7F), then skip to step 8.
     198                 :            :    */
     199                 :            : 
     200                 :            :   {
     201                 :            :     size_t i;
     202                 :            :     int inasciirange;
     203                 :            : 
     204                 :        194 :     inasciirange = 1;
     205         [ +  + ]:       1944 :     for (i = 0; src[i]; i++)
     206                 :            :       {
     207         [ +  + ]:       1750 :         if (src[i] > 0x7F)
     208                 :        724 :           inasciirange = 0;
     209                 :            :         /* copy string to output buffer if we are about to skip to step8 */
     210         [ +  - ]:       1750 :         if (i < 64)
     211                 :       1750 :           out[i] = src[i];
     212                 :            :       }
     213         [ +  - ]:        194 :     if (i < 64)
     214                 :        194 :       out[i] = '\0';
     215         [ +  + ]:        194 :     if (inasciirange)
     216                 :         77 :       goto step8;
     217                 :            :   }
     218                 :            : 
     219                 :            :   /*
     220                 :            :    * 5. Verify that the sequence does NOT begin with the ACE prefix.
     221                 :            :    *
     222                 :            :    */
     223                 :            : 
     224                 :            :   {
     225                 :            :     size_t i;
     226                 :            :     int match;
     227                 :            : 
     228                 :        117 :     match = 1;
     229 [ +  + ][ +  + ]:        243 :     for (i = 0; match && i < strlen (IDNA_ACE_PREFIX); i++)
     230         [ +  + ]:        126 :       if (((uint32_t) IDNA_ACE_PREFIX[i] & 0xFF) != src[i])
     231                 :        114 :         match = 0;
     232         [ +  + ]:        117 :     if (match)
     233                 :            :       {
     234                 :          3 :         free (src);
     235                 :          3 :         return IDNA_CONTAINS_ACE_PREFIX;
     236                 :            :       }
     237                 :            :   }
     238                 :            : 
     239                 :            :   /*
     240                 :            :    * 6. Encode the sequence using the encoding algorithm in [PUNYCODE]
     241                 :            :    * and fail if there is an error.
     242                 :            :    */
     243         [ +  + ]:       1336 :   for (len = 0; src[len]; len++)
     244                 :            :     ;
     245                 :        114 :   src[len] = '\0';
     246                 :        114 :   outlen = 63 - strlen (IDNA_ACE_PREFIX);
     247                 :        114 :   rc = punycode_encode (len, src, NULL,
     248                 :            :                         &outlen, &out[strlen (IDNA_ACE_PREFIX)]);
     249         [ +  + ]:        114 :   if (rc != PUNYCODE_SUCCESS)
     250                 :            :     {
     251                 :          2 :       free (src);
     252                 :          2 :       return IDNA_PUNYCODE_ERROR;
     253                 :            :     }
     254                 :        112 :   out[strlen (IDNA_ACE_PREFIX) + outlen] = '\0';
     255                 :            : 
     256                 :            :   /*
     257                 :            :    * 7. Prepend the ACE prefix.
     258                 :            :    */
     259                 :            : 
     260                 :        112 :   memcpy (out, IDNA_ACE_PREFIX, strlen (IDNA_ACE_PREFIX));
     261                 :            : 
     262                 :            :   /*
     263                 :            :    * 8. Verify that the number of code points is in the range 1 to 63
     264                 :            :    * inclusive (0 is excluded).
     265                 :            :    */
     266                 :            : 
     267                 :            : step8:
     268                 :        189 :   free (src);
     269 [ +  + ][ -  + ]:        189 :   if (strlen (out) < 1 || strlen (out) > 63)
     270                 :          3 :     return IDNA_INVALID_LENGTH;
     271                 :            : 
     272                 :        221 :   return IDNA_SUCCESS;
     273                 :            : }
     274                 :            : 
     275                 :            : /* ToUnicode().  May realloc() utf8in.  Will free utf8in unconditionally. */
     276                 :            : static int
     277                 :         28 : idna_to_unicode_internal (char *utf8in,
     278                 :            :                           uint32_t * out, size_t * outlen, int flags)
     279                 :            : {
     280                 :            :   int rc;
     281                 :            :   char tmpout[64];
     282                 :         28 :   size_t utf8len = strlen (utf8in) + 1;
     283                 :         28 :   size_t addlen = 0;
     284                 :            : 
     285                 :            :   /*
     286                 :            :    * ToUnicode consists of the following steps:
     287                 :            :    *
     288                 :            :    * 1. If the sequence contains any code points outside the ASCII range
     289                 :            :    * (0..7F) then proceed to step 2, otherwise skip to step 3.
     290                 :            :    */
     291                 :            : 
     292                 :            :   {
     293                 :            :     size_t i;
     294                 :            :     int inasciirange;
     295                 :            : 
     296                 :         28 :     inasciirange = 1;
     297         [ +  + ]:        951 :     for (i = 0; utf8in[i]; i++)
     298         [ -  + ]:        923 :       if (utf8in[i] & ~0x7F)
     299                 :          0 :         inasciirange = 0;
     300         [ +  - ]:         28 :     if (inasciirange)
     301                 :         28 :       goto step3;
     302                 :            :   }
     303                 :            : 
     304                 :            :   /*
     305                 :            :    * 2. Perform the steps specified in [NAMEPREP] and fail if there is an
     306                 :            :    * error. (If step 3 of ToASCII is also performed here, it will not
     307                 :            :    * affect the overall behavior of ToUnicode, but it is not
     308                 :            :    * necessary.) The AllowUnassigned flag is used in [NAMEPREP].
     309                 :            :    */
     310                 :            :   do
     311                 :            :     {
     312                 :          0 :       char *newp = realloc (utf8in, utf8len + addlen);
     313         [ #  # ]:          0 :       if (newp == NULL)
     314                 :            :         {
     315                 :          0 :           free (utf8in);
     316                 :          0 :           return IDNA_MALLOC_ERROR;
     317                 :            :         }
     318                 :          0 :       utf8in = newp;
     319         [ #  # ]:          0 :       if (flags & IDNA_ALLOW_UNASSIGNED)
     320                 :          0 :         rc = stringprep_nameprep (utf8in, utf8len + addlen);
     321                 :            :       else
     322                 :          0 :         rc = stringprep_nameprep_no_unassigned (utf8in, utf8len + addlen);
     323                 :          0 :       addlen += 1;
     324                 :            :     }
     325         [ #  # ]:          0 :   while (rc == STRINGPREP_TOO_SMALL_BUFFER);
     326                 :            : 
     327         [ #  # ]:          0 :   if (rc != STRINGPREP_OK)
     328                 :            :     {
     329                 :          0 :       free (utf8in);
     330                 :          0 :       return IDNA_STRINGPREP_ERROR;
     331                 :            :     }
     332                 :            : 
     333                 :            :   /* 3. Verify that the sequence begins with the ACE prefix, and save a
     334                 :            :    * copy of the sequence.
     335                 :            :    * ... The ToASCII and ToUnicode operations MUST recognize the ACE
     336                 :            :    prefix in a case-insensitive manner.
     337                 :            :    */
     338                 :            : 
     339                 :            : step3:
     340         [ -  + ]:         28 :   if (c_strncasecmp (utf8in, IDNA_ACE_PREFIX, strlen (IDNA_ACE_PREFIX)) != 0)
     341                 :            :     {
     342                 :          0 :       free (utf8in);
     343                 :          0 :       return IDNA_NO_ACE_PREFIX;
     344                 :            :     }
     345                 :            : 
     346                 :            :   /* 4. Remove the ACE prefix.
     347                 :            :    */
     348                 :            : 
     349                 :         28 :   memmove (utf8in, &utf8in[strlen (IDNA_ACE_PREFIX)],
     350                 :         28 :            strlen (utf8in) - strlen (IDNA_ACE_PREFIX) + 1);
     351                 :            : 
     352                 :            :   /* 5. Decode the sequence using the decoding algorithm in [PUNYCODE]
     353                 :            :    * and fail if there is an error. Save a copy of the result of
     354                 :            :    * this step.
     355                 :            :    */
     356                 :            : 
     357                 :         28 :   (*outlen)--;                  /* reserve one for the zero */
     358                 :            : 
     359                 :         28 :   rc = punycode_decode (strlen (utf8in), utf8in, outlen, out, NULL);
     360         [ +  + ]:         28 :   if (rc != PUNYCODE_SUCCESS)
     361                 :            :     {
     362                 :          1 :       free (utf8in);
     363                 :          1 :       return IDNA_PUNYCODE_ERROR;
     364                 :            :     }
     365                 :            : 
     366                 :         27 :   out[*outlen] = 0;             /* add zero */
     367                 :            : 
     368                 :            :   /* 6. Apply ToASCII.
     369                 :            :    */
     370                 :            : 
     371                 :         27 :   rc = idna_to_ascii_4i (out, *outlen, tmpout, flags);
     372         [ +  + ]:         27 :   if (rc != IDNA_SUCCESS)
     373                 :            :     {
     374                 :          1 :       free (utf8in);
     375                 :          1 :       return rc;
     376                 :            :     }
     377                 :            : 
     378                 :            :   /* 7. Verify that the result of step 6 matches the saved copy from
     379                 :            :    * step 3, using a case-insensitive ASCII comparison.
     380                 :            :    */
     381                 :            : 
     382         [ -  + ]:         26 :   if (c_strcasecmp (utf8in, tmpout + strlen (IDNA_ACE_PREFIX)) != 0)
     383                 :            :     {
     384                 :          0 :       free (utf8in);
     385                 :          0 :       return IDNA_ROUNDTRIP_VERIFY_ERROR;
     386                 :            :     }
     387                 :            : 
     388                 :            :   /* 8. Return the saved copy from step 5.
     389                 :            :    */
     390                 :            : 
     391                 :         26 :   free (utf8in);
     392                 :         28 :   return IDNA_SUCCESS;
     393                 :            : }
     394                 :            : 
     395                 :            : /**
     396                 :            :  * idna_to_unicode_44i:
     397                 :            :  * @in: input array with unicode code points.
     398                 :            :  * @inlen: length of input array with unicode code points.
     399                 :            :  * @out: output array with unicode code points.
     400                 :            :  * @outlen: on input, maximum size of output array with unicode code points,
     401                 :            :  *          on exit, actual size of output array with unicode code points.
     402                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     403                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     404                 :            :  *
     405                 :            :  * The ToUnicode operation takes a sequence of Unicode code points
     406                 :            :  * that make up one domain label and returns a sequence of Unicode
     407                 :            :  * code points. If the input sequence is a label in ACE form, then the
     408                 :            :  * result is an equivalent internationalized label that is not in ACE
     409                 :            :  * form, otherwise the original sequence is returned unaltered.
     410                 :            :  *
     411                 :            :  * ToUnicode never fails. If any step fails, then the original input
     412                 :            :  * sequence is returned immediately in that step.
     413                 :            :  *
     414                 :            :  * The Punycode decoder can never output more code points than it
     415                 :            :  * inputs, but Nameprep can, and therefore ToUnicode can.  Note that
     416                 :            :  * the number of octets needed to represent a sequence of code points
     417                 :            :  * depends on the particular character encoding used.
     418                 :            :  *
     419                 :            :  * The inputs to ToUnicode are a sequence of code points, the
     420                 :            :  * AllowUnassigned flag, and the UseSTD3ASCIIRules flag. The output of
     421                 :            :  * ToUnicode is always a sequence of Unicode code points.
     422                 :            :  *
     423                 :            :  * Return value: Returns #Idna_rc error condition, but it must only be
     424                 :            :  *   used for debugging purposes.  The output buffer is always
     425                 :            :  *   guaranteed to contain the correct data according to the
     426                 :            :  *   specification (sans malloc induced errors).  NB!  This means that
     427                 :            :  *   you normally ignore the return code from this function, as
     428                 :            :  *   checking it means breaking the standard.
     429                 :            :  */
     430                 :            : int
     431                 :         28 : idna_to_unicode_44i (const uint32_t * in, size_t inlen,
     432                 :            :                      uint32_t * out, size_t * outlen, int flags)
     433                 :            : {
     434                 :            :   int rc;
     435                 :         28 :   size_t outlensave = *outlen;
     436                 :            :   char *p;
     437                 :            : 
     438                 :         28 :   p = stringprep_ucs4_to_utf8 (in, (ssize_t) inlen, NULL, NULL);
     439         [ -  + ]:         28 :   if (p == NULL)
     440                 :          0 :     return IDNA_MALLOC_ERROR;
     441                 :            : 
     442                 :         28 :   rc = idna_to_unicode_internal (p, out, outlen, flags);
     443         [ +  + ]:         28 :   if (rc != IDNA_SUCCESS)
     444                 :            :     {
     445                 :          2 :       memcpy (out, in, sizeof (in[0]) * (inlen < outlensave ?
     446                 :          2 :                                          inlen : outlensave));
     447                 :          2 :       *outlen = inlen;
     448                 :            :     }
     449                 :            : 
     450                 :            :   /* p is freed in idna_to_unicode_internal.  */
     451                 :            : 
     452                 :         28 :   return rc;
     453                 :            : }
     454                 :            : 
     455                 :            : /* Wrappers that handle several labels */
     456                 :            : 
     457                 :            : /**
     458                 :            :  * idna_to_ascii_4z:
     459                 :            :  * @input: zero terminated input Unicode string.
     460                 :            :  * @output: pointer to newly allocated output string.
     461                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     462                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     463                 :            :  *
     464                 :            :  * Convert UCS-4 domain name to ASCII string.  The domain name may
     465                 :            :  * contain several labels, separated by dots.  The output buffer must
     466                 :            :  * be deallocated by the caller.
     467                 :            :  *
     468                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     469                 :            :  **/
     470                 :            : int
     471                 :        101 : idna_to_ascii_4z (const uint32_t * input, char **output, int flags)
     472                 :            : {
     473                 :        101 :   const uint32_t *start = input;
     474                 :            :   const uint32_t *end;
     475                 :            :   char buf[64];
     476                 :        101 :   char *out = NULL;
     477                 :            :   int rc;
     478                 :            : 
     479                 :            :   /* 1) Whenever dots are used as label separators, the following
     480                 :            :      characters MUST be recognized as dots: U+002E (full stop),
     481                 :            :      U+3002 (ideographic full stop), U+FF0E (fullwidth full stop),
     482                 :            :      U+FF61 (halfwidth ideographic full stop). */
     483                 :            : 
     484         [ +  + ]:        101 :   if (input[0] == 0)
     485                 :            :     {
     486                 :            :       /* Handle implicit zero-length root label. */
     487                 :          1 :       *output = malloc (1);
     488         [ -  + ]:          1 :       if (!*output)
     489                 :          0 :         return IDNA_MALLOC_ERROR;
     490                 :          1 :       strcpy (*output, "");
     491                 :          1 :       return IDNA_SUCCESS;
     492                 :            :     }
     493                 :            : 
     494 [ +  - ][ +  - ]:        100 :   if (DOTP (input[0]) && input[1] == 0)
         [ +  - ][ -  + ]
                 [ #  # ]
     495                 :            :     {
     496                 :            :       /* Handle explicit zero-length root label. */
     497                 :          0 :       *output = malloc (2);
     498         [ #  # ]:          0 :       if (!*output)
     499                 :          0 :         return IDNA_MALLOC_ERROR;
     500                 :          0 :       strcpy (*output, ".");
     501                 :          0 :       return IDNA_SUCCESS;
     502                 :            :     }
     503                 :            : 
     504                 :        100 :   *output = NULL;
     505                 :            :   do
     506                 :            :     {
     507                 :        172 :       end = start;
     508                 :            : 
     509 [ +  + ][ +  + ]:       1196 :       for (; *end && !DOTP (*end); end++)
         [ +  + ][ +  + ]
                 [ +  + ]
     510                 :            :         ;
     511                 :            : 
     512 [ +  + ][ -  + ]:        172 :       if (*end == '\0' && start == end)
     513                 :            :         {
     514                 :            :           /* Handle explicit zero-length root label. */
     515                 :          0 :           buf[0] = '\0';
     516                 :            :         }
     517                 :            :       else
     518                 :            :         {
     519                 :        172 :           rc = idna_to_ascii_4i (start, (size_t) (end - start), buf, flags);
     520         [ +  + ]:        172 :           if (rc != IDNA_SUCCESS)
     521                 :            :             {
     522                 :         32 :               free (out);
     523                 :         32 :               return rc;
     524                 :            :             }
     525                 :            :         }
     526                 :            : 
     527         [ +  + ]:        140 :       if (out)
     528                 :            :         {
     529                 :         69 :           size_t l = strlen (out) + 1 + strlen (buf) + 1;
     530                 :         69 :           char *newp = realloc (out, l);
     531         [ -  + ]:         69 :           if (!newp)
     532                 :            :             {
     533                 :          0 :               free (out);
     534                 :          0 :               return IDNA_MALLOC_ERROR;
     535                 :            :             }
     536                 :         69 :           out = newp;
     537                 :         69 :           strcat (out, ".");
     538                 :         69 :           strcat (out, buf);
     539                 :            :         }
     540                 :            :       else
     541                 :            :         {
     542                 :         71 :           size_t l = strlen (buf) + 1;
     543                 :         71 :           out = (char *) malloc (l);
     544         [ -  + ]:         71 :           if (!out)
     545                 :          0 :             return IDNA_MALLOC_ERROR;
     546                 :         71 :           strcpy (out, buf);
     547                 :            :         }
     548                 :            : 
     549                 :        140 :       start = end + 1;
     550                 :            :     }
     551         [ +  + ]:        140 :   while (*end);
     552                 :            : 
     553                 :         68 :   *output = out;
     554                 :            : 
     555                 :        101 :   return IDNA_SUCCESS;
     556                 :            : }
     557                 :            : 
     558                 :            : /**
     559                 :            :  * idna_to_ascii_8z:
     560                 :            :  * @input: zero terminated input UTF-8 string.
     561                 :            :  * @output: pointer to newly allocated output string.
     562                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     563                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     564                 :            :  *
     565                 :            :  * Convert UTF-8 domain name to ASCII string.  The domain name may
     566                 :            :  * contain several labels, separated by dots.  The output buffer must
     567                 :            :  * be deallocated by the caller.
     568                 :            :  *
     569                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     570                 :            :  **/
     571                 :            : int
     572                 :        101 : idna_to_ascii_8z (const char *input, char **output, int flags)
     573                 :            : {
     574                 :            :   uint32_t *ucs4;
     575                 :            :   size_t ucs4len;
     576                 :            :   int rc;
     577                 :            : 
     578                 :        101 :   ucs4 = stringprep_utf8_to_ucs4 (input, -1, &ucs4len);
     579         [ -  + ]:        101 :   if (!ucs4)
     580                 :          0 :     return IDNA_ICONV_ERROR;
     581                 :            : 
     582                 :        101 :   rc = idna_to_ascii_4z (ucs4, output, flags);
     583                 :            : 
     584                 :        101 :   free (ucs4);
     585                 :            : 
     586                 :        101 :   return rc;
     587                 :            : 
     588                 :            : }
     589                 :            : 
     590                 :            : /**
     591                 :            :  * idna_to_ascii_lz:
     592                 :            :  * @input: zero terminated input string encoded in the current locale's
     593                 :            :  *   character set.
     594                 :            :  * @output: pointer to newly allocated output string.
     595                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     596                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     597                 :            :  *
     598                 :            :  * Convert domain name in the locale's encoding to ASCII string.  The
     599                 :            :  * domain name may contain several labels, separated by dots.  The
     600                 :            :  * output buffer must be deallocated by the caller.
     601                 :            :  *
     602                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     603                 :            :  **/
     604                 :            : int
     605                 :          0 : idna_to_ascii_lz (const char *input, char **output, int flags)
     606                 :            : {
     607                 :            :   char *utf8;
     608                 :            :   int rc;
     609                 :            : 
     610                 :          0 :   utf8 = stringprep_locale_to_utf8 (input);
     611         [ #  # ]:          0 :   if (!utf8)
     612                 :          0 :     return IDNA_ICONV_ERROR;
     613                 :            : 
     614                 :          0 :   rc = idna_to_ascii_8z (utf8, output, flags);
     615                 :            : 
     616                 :          0 :   free (utf8);
     617                 :            : 
     618                 :          0 :   return rc;
     619                 :            : }
     620                 :            : 
     621                 :            : /**
     622                 :            :  * idna_to_unicode_4z4z:
     623                 :            :  * @input: zero-terminated Unicode string.
     624                 :            :  * @output: pointer to newly allocated output Unicode string.
     625                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     626                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     627                 :            :  *
     628                 :            :  * Convert possibly ACE encoded domain name in UCS-4 format into a
     629                 :            :  * UCS-4 string.  The domain name may contain several labels,
     630                 :            :  * separated by dots.  The output buffer must be deallocated by the
     631                 :            :  * caller.
     632                 :            :  *
     633                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     634                 :            :  **/
     635                 :            : int
     636                 :          3 : idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags)
     637                 :            : {
     638                 :          3 :   const uint32_t *start = input;
     639                 :            :   const uint32_t *end;
     640                 :            :   uint32_t *buf;
     641                 :            :   size_t buflen;
     642                 :          3 :   uint32_t *out = NULL;
     643                 :          3 :   size_t outlen = 0;
     644                 :            : 
     645                 :          3 :   *output = NULL;
     646                 :            : 
     647                 :            :   do
     648                 :            :     {
     649                 :          6 :       end = start;
     650                 :            : 
     651 [ +  + ][ +  + ]:        111 :       for (; *end && !DOTP (*end); end++)
         [ +  - ][ +  - ]
                 [ +  - ]
     652                 :            :         ;
     653                 :            : 
     654                 :          6 :       buflen = (size_t) (end - start);
     655                 :          6 :       buf = malloc (sizeof (buf[0]) * (buflen + 1));
     656         [ -  + ]:          6 :       if (!buf)
     657                 :          0 :         return IDNA_MALLOC_ERROR;
     658                 :            : 
     659                 :            :       /* don't check return code as per specification! */
     660                 :          6 :       idna_to_unicode_44i (start, (size_t) (end - start),
     661                 :            :                            buf, &buflen, flags);
     662                 :            : 
     663         [ +  + ]:          6 :       if (out)
     664                 :            :         {
     665                 :          3 :           uint32_t *newp = realloc (out,
     666                 :            :                                     sizeof (out[0])
     667                 :          3 :                                     * (outlen + 1 + buflen + 1));
     668         [ -  + ]:          3 :           if (!newp)
     669                 :            :             {
     670                 :          0 :               free (buf);
     671                 :          0 :               free (out);
     672                 :          0 :               return IDNA_MALLOC_ERROR;
     673                 :            :             }
     674                 :          3 :           out = newp;
     675                 :          3 :           out[outlen++] = 0x002E;       /* '.' (full stop) */
     676                 :          3 :           memcpy (out + outlen, buf, sizeof (buf[0]) * buflen);
     677                 :          3 :           outlen += buflen;
     678                 :          3 :           out[outlen] = 0x0;
     679                 :          3 :           free (buf);
     680                 :            :         }
     681                 :            :       else
     682                 :            :         {
     683                 :          3 :           out = buf;
     684                 :          3 :           outlen = buflen;
     685                 :          3 :           out[outlen] = 0x0;
     686                 :            :         }
     687                 :            : 
     688                 :          6 :       start = end + 1;
     689                 :            :     }
     690         [ +  + ]:          6 :   while (*end);
     691                 :            : 
     692                 :          3 :   *output = out;
     693                 :            : 
     694                 :          3 :   return IDNA_SUCCESS;
     695                 :            : }
     696                 :            : 
     697                 :            : /**
     698                 :            :  * idna_to_unicode_8z4z:
     699                 :            :  * @input: zero-terminated UTF-8 string.
     700                 :            :  * @output: pointer to newly allocated output Unicode string.
     701                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     702                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     703                 :            :  *
     704                 :            :  * Convert possibly ACE encoded domain name in UTF-8 format into a
     705                 :            :  * UCS-4 string.  The domain name may contain several labels,
     706                 :            :  * separated by dots.  The output buffer must be deallocated by the
     707                 :            :  * caller.
     708                 :            :  *
     709                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     710                 :            :  **/
     711                 :            : int
     712                 :          3 : idna_to_unicode_8z4z (const char *input, uint32_t ** output, int flags)
     713                 :            : {
     714                 :            :   uint32_t *ucs4;
     715                 :            :   size_t ucs4len;
     716                 :            :   int rc;
     717                 :            : 
     718                 :          3 :   ucs4 = stringprep_utf8_to_ucs4 (input, -1, &ucs4len);
     719         [ -  + ]:          3 :   if (!ucs4)
     720                 :          0 :     return IDNA_ICONV_ERROR;
     721                 :            : 
     722                 :          3 :   rc = idna_to_unicode_4z4z (ucs4, output, flags);
     723                 :          3 :   free (ucs4);
     724                 :            : 
     725                 :          3 :   return rc;
     726                 :            : }
     727                 :            : 
     728                 :            : /**
     729                 :            :  * idna_to_unicode_8z8z:
     730                 :            :  * @input: zero-terminated UTF-8 string.
     731                 :            :  * @output: pointer to newly allocated output UTF-8 string.
     732                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     733                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     734                 :            :  *
     735                 :            :  * Convert possibly ACE encoded domain name in UTF-8 format into a
     736                 :            :  * UTF-8 string.  The domain name may contain several labels,
     737                 :            :  * separated by dots.  The output buffer must be deallocated by the
     738                 :            :  * caller.
     739                 :            :  *
     740                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     741                 :            :  **/
     742                 :            : int
     743                 :          3 : idna_to_unicode_8z8z (const char *input, char **output, int flags)
     744                 :            : {
     745                 :            :   uint32_t *ucs4;
     746                 :            :   int rc;
     747                 :            : 
     748                 :          3 :   rc = idna_to_unicode_8z4z (input, &ucs4, flags);
     749                 :          3 :   *output = stringprep_ucs4_to_utf8 (ucs4, -1, NULL, NULL);
     750                 :          3 :   free (ucs4);
     751                 :            : 
     752         [ -  + ]:          3 :   if (!*output)
     753                 :          0 :     return IDNA_ICONV_ERROR;
     754                 :            : 
     755                 :          3 :   return rc;
     756                 :            : }
     757                 :            : 
     758                 :            : /**
     759                 :            :  * idna_to_unicode_8zlz:
     760                 :            :  * @input: zero-terminated UTF-8 string.
     761                 :            :  * @output: pointer to newly allocated output string encoded in the
     762                 :            :  *   current locale's character set.
     763                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     764                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     765                 :            :  *
     766                 :            :  * Convert possibly ACE encoded domain name in UTF-8 format into a
     767                 :            :  * string encoded in the current locale's character set.  The domain
     768                 :            :  * name may contain several labels, separated by dots.  The output
     769                 :            :  * buffer must be deallocated by the caller.
     770                 :            :  *
     771                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     772                 :            :  **/
     773                 :            : int
     774                 :          0 : idna_to_unicode_8zlz (const char *input, char **output, int flags)
     775                 :            : {
     776                 :            :   char *utf8;
     777                 :            :   int rc;
     778                 :            : 
     779                 :          0 :   rc = idna_to_unicode_8z8z (input, &utf8, flags);
     780                 :          0 :   *output = stringprep_utf8_to_locale (utf8);
     781                 :          0 :   free (utf8);
     782                 :            : 
     783         [ #  # ]:          0 :   if (!*output)
     784                 :          0 :     return IDNA_ICONV_ERROR;
     785                 :            : 
     786                 :          0 :   return rc;
     787                 :            : }
     788                 :            : 
     789                 :            : /**
     790                 :            :  * idna_to_unicode_lzlz:
     791                 :            :  * @input: zero-terminated string encoded in the current locale's
     792                 :            :  *   character set.
     793                 :            :  * @output: pointer to newly allocated output string encoded in the
     794                 :            :  *   current locale's character set.
     795                 :            :  * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
     796                 :            :  *   %IDNA_USE_STD3_ASCII_RULES.
     797                 :            :  *
     798                 :            :  * Convert possibly ACE encoded domain name in the locale's character
     799                 :            :  * set into a string encoded in the current locale's character set.
     800                 :            :  * The domain name may contain several labels, separated by dots.  The
     801                 :            :  * output buffer must be deallocated by the caller.
     802                 :            :  *
     803                 :            :  * Return value: Returns %IDNA_SUCCESS on success, or error code.
     804                 :            :  **/
     805                 :            : int
     806                 :          0 : idna_to_unicode_lzlz (const char *input, char **output, int flags)
     807                 :            : {
     808                 :            :   char *utf8;
     809                 :            :   int rc;
     810                 :            : 
     811                 :          0 :   utf8 = stringprep_locale_to_utf8 (input);
     812         [ #  # ]:          0 :   if (!utf8)
     813                 :          0 :     return IDNA_ICONV_ERROR;
     814                 :            : 
     815                 :          0 :   rc = idna_to_unicode_8zlz (utf8, output, flags);
     816                 :          0 :   free (utf8);
     817                 :            : 
     818                 :          0 :   return rc;
     819                 :            : }
     820                 :            : 
     821                 :            : /**
     822                 :            :  * IDNA_ACE_PREFIX
     823                 :            :  *
     824                 :            :  * The IANA allocated prefix to use for IDNA. "xn--"
     825                 :            :  */
     826                 :            : 
     827                 :            : /**
     828                 :            :  * Idna_rc:
     829                 :            :  * @IDNA_SUCCESS: Successful operation.  This value is guaranteed to
     830                 :            :  *   always be zero, the remaining ones are only guaranteed to hold
     831                 :            :  *   non-zero values, for logical comparison purposes.
     832                 :            :  * @IDNA_STRINGPREP_ERROR:  Error during string preparation.
     833                 :            :  * @IDNA_PUNYCODE_ERROR: Error during punycode operation.
     834                 :            :  * @IDNA_CONTAINS_NON_LDH: For IDNA_USE_STD3_ASCII_RULES, indicate that
     835                 :            :  *   the string contains non-LDH ASCII characters.
     836                 :            :  * @IDNA_CONTAINS_LDH: Same as @IDNA_CONTAINS_NON_LDH, for compatibility
     837                 :            :  *   with typo in earlier versions.
     838                 :            :  * @IDNA_CONTAINS_MINUS: For IDNA_USE_STD3_ASCII_RULES, indicate that
     839                 :            :  *   the string contains a leading or trailing hyphen-minus (U+002D).
     840                 :            :  * @IDNA_INVALID_LENGTH: The final output string is not within the
     841                 :            :  *   (inclusive) range 1 to 63 characters.
     842                 :            :  * @IDNA_NO_ACE_PREFIX: The string does not contain the ACE prefix
     843                 :            :  *   (for ToUnicode).
     844                 :            :  * @IDNA_ROUNDTRIP_VERIFY_ERROR: The ToASCII operation on output
     845                 :            :  *   string does not equal the input.
     846                 :            :  * @IDNA_CONTAINS_ACE_PREFIX: The input contains the ACE prefix (for
     847                 :            :  *   ToASCII).
     848                 :            :  * @IDNA_ICONV_ERROR: Could not convert string in locale encoding.
     849                 :            :  * @IDNA_MALLOC_ERROR: Could not allocate buffer (this is typically a
     850                 :            :  *   fatal error).
     851                 :            :  * @IDNA_DLOPEN_ERROR: Could not dlopen the libcidn DSO (only used
     852                 :            :  *   internally in libc).
     853                 :            :  *
     854                 :            :  * Enumerated return codes of idna_to_ascii_4i(),
     855                 :            :  * idna_to_unicode_44i() functions (and functions derived from those
     856                 :            :  * functions).  The value 0 is guaranteed to always correspond to
     857                 :            :  * success.
     858                 :            :  */
     859                 :            : 
     860                 :            : 
     861                 :            : /**
     862                 :            :  * Idna_flags:
     863                 :            :  * @IDNA_ALLOW_UNASSIGNED: Don't reject strings containing unassigned
     864                 :            :  *   Unicode code points.
     865                 :            :  * @IDNA_USE_STD3_ASCII_RULES: Validate strings according to STD3
     866                 :            :  *   rules (i.e., normal host name rules).
     867                 :            :  *
     868                 :            :  * Flags to pass to idna_to_ascii_4i(), idna_to_unicode_44i() etc.
     869                 :            :  */

Generated by: LCOV version 1.9