LCOV - code coverage report
Current view: top level - common - stringhelp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 294 464 63.4 %
Date: 2015-11-05 17:10:59 Functions: 32 43 74.4 %

          Line data    Source code
       1             : /* stringhelp.c -  standard string helper functions
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
       3             :  *               2008, 2009, 2010  Free Software Foundation, Inc.
       4             :  * Copyright (C) 2014 Werner Koch
       5             :  * Copyright (C) 2015  g10 Code GmbH
       6             :  *
       7             :  * This file is part of GnuPG.
       8             :  *
       9             :  * GnuPG is free software; you can redistribute it and/or modify it
      10             :  * under the terms of either
      11             :  *
      12             :  *   - the GNU Lesser General Public License as published by the Free
      13             :  *     Software Foundation; either version 3 of the License, or (at
      14             :  *     your option) any later version.
      15             :  *
      16             :  * or
      17             :  *
      18             :  *   - the GNU General Public License as published by the Free
      19             :  *     Software Foundation; either version 2 of the License, or (at
      20             :  *     your option) any later version.
      21             :  *
      22             :  * or both in parallel, as here.
      23             :  *
      24             :  * GnuPG is distributed in the hope that it will be useful, but
      25             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      26             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      27             :  * General Public License for more details.
      28             :  *
      29             :  * You should have received a copies of the GNU General Public License
      30             :  * and the GNU Lesser General Public License along with this program;
      31             :  * if not, see <http://www.gnu.org/licenses/>.
      32             :  */
      33             : 
      34             : #include <config.h>
      35             : #include <stdlib.h>
      36             : #include <string.h>
      37             : #include <stdarg.h>
      38             : #include <ctype.h>
      39             : #include <errno.h>
      40             : #ifdef HAVE_PWD_H
      41             : # include <pwd.h>
      42             : #endif
      43             : #include <unistd.h>
      44             : #include <sys/types.h>
      45             : #ifdef HAVE_W32_SYSTEM
      46             : # ifdef HAVE_WINSOCK2_H
      47             : #  include <winsock2.h>
      48             : # endif
      49             : # include <windows.h>
      50             : #endif
      51             : #include <assert.h>
      52             : 
      53             : #include "util.h"
      54             : #include "common-defs.h"
      55             : #include "utf8conv.h"
      56             : #include "sysutils.h"
      57             : #include "stringhelp.h"
      58             : 
      59             : #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
      60             : 
      61             : /* Sometimes we want to avoid mixing slashes and backslashes on W32
      62             :    and prefer backslashes.  There is usual no problem with mixing
      63             :    them, however a very few W32 API calls can't grok plain slashes.
      64             :    Printing filenames with mixed slashes also looks a bit strange.
      65             :    This function has no effext on POSIX. */
      66             : static inline char *
      67       11803 : change_slashes (char *name)
      68             : {
      69             : #ifdef HAVE_DOSISH_SYSTEM
      70             :   char *p;
      71             : 
      72             :   if (strchr (name, '\\'))
      73             :     {
      74             :       for (p=name; *p; p++)
      75             :         if (*p == '/')
      76             :           *p = '\\';
      77             :     }
      78             : #endif /*HAVE_DOSISH_SYSTEM*/
      79       11803 :   return name;
      80             : }
      81             : 
      82             : 
      83             : /*
      84             :  * Check whether STRING starts with KEYWORD.  The keyword is
      85             :  * delimited by end of string, a space or a tab.  Returns NULL if not
      86             :  * found or a pointer into STRING to the next non-space character
      87             :  * after the KEYWORD (which may be end of string).
      88             :  */
      89             : char *
      90         521 : has_leading_keyword (const char *string, const char *keyword)
      91             : {
      92         521 :   size_t n = strlen (keyword);
      93             : 
      94         521 :   if (!strncmp (string, keyword, n)
      95         269 :       && (!string[n] || string[n] == ' ' || string[n] == '\t'))
      96             :     {
      97         269 :       string += n;
      98         538 :       while (*string == ' ' || *string == '\t')
      99           0 :         string++;
     100         269 :       return (char*)string;
     101             :     }
     102         252 :   return NULL;
     103             : }
     104             : 
     105             : 
     106             : /*
     107             :  * Look for the substring SUB in buffer and return a pointer to that
     108             :  * substring in BUFFER or NULL if not found.
     109             :  * Comparison is case-insensitive.
     110             :  */
     111             : const char *
     112           0 : memistr (const void *buffer, size_t buflen, const char *sub)
     113             : {
     114           0 :   const unsigned char *buf = buffer;
     115           0 :   const unsigned char *t = (const unsigned char *)buffer;
     116           0 :   const unsigned char *s = (const unsigned char *)sub;
     117           0 :   size_t n = buflen;
     118             : 
     119           0 :   for ( ; n ; t++, n-- )
     120             :     {
     121           0 :       if ( toupper (*t) == toupper (*s) )
     122             :         {
     123           0 :           for ( buf=t++, buflen = n--, s++;
     124           0 :                 n && toupper (*t) == toupper (*s); t++, s++, n-- )
     125             :             ;
     126           0 :           if (!*s)
     127           0 :             return (const char*)buf;
     128           0 :           t = buf;
     129           0 :           s = (const unsigned char *)sub ;
     130           0 :           n = buflen;
     131             :         }
     132             :     }
     133           0 :   return NULL;
     134             : }
     135             : 
     136             : const char *
     137           0 : ascii_memistr ( const void *buffer, size_t buflen, const char *sub )
     138             : {
     139           0 :   const unsigned char *buf = buffer;
     140           0 :   const unsigned char *t = (const unsigned char *)buf;
     141           0 :   const unsigned char *s = (const unsigned char *)sub;
     142           0 :   size_t n = buflen;
     143             : 
     144           0 :   for ( ; n ; t++, n-- )
     145             :     {
     146           0 :       if (ascii_toupper (*t) == ascii_toupper (*s) )
     147             :         {
     148           0 :           for ( buf=t++, buflen = n--, s++;
     149           0 :                 n && ascii_toupper (*t) == ascii_toupper (*s); t++, s++, n-- )
     150             :             ;
     151           0 :           if (!*s)
     152           0 :             return (const char*)buf;
     153           0 :           t = (const unsigned char *)buf;
     154           0 :           s = (const unsigned char *)sub ;
     155           0 :           n = buflen;
     156             :         }
     157             :     }
     158           0 :   return NULL;
     159             : }
     160             : 
     161             : /* This function is similar to strncpy().  However it won't copy more
     162             :    than N - 1 characters and makes sure that a '\0' is appended. With
     163             :    N given as 0, nothing will happen.  With DEST given as NULL, memory
     164             :    will be allocated using xmalloc (i.e. if it runs out of core
     165             :    the function terminates).  Returns DES or a pointer to the
     166             :    allocated memory.
     167             :  */
     168             : char *
     169         179 : mem2str( char *dest , const void *src , size_t n )
     170             : {
     171             :     char *d;
     172             :     const char *s;
     173             : 
     174         179 :     if( n ) {
     175         179 :         if( !dest )
     176           0 :             dest = xmalloc( n ) ;
     177         179 :         d = dest;
     178         179 :         s = src ;
     179        3375 :         for(n--; n && *s; n-- )
     180        3196 :             *d++ = *s++;
     181         179 :         *d = '\0' ;
     182             :     }
     183             : 
     184         179 :     return dest ;
     185             : }
     186             : 
     187             : 
     188             : /****************
     189             :  * remove leading and trailing white spaces
     190             :  */
     191             : char *
     192        1308 : trim_spaces( char *str )
     193             : {
     194             :     char *string, *p, *mark;
     195             : 
     196        1308 :     string = str;
     197             :     /* find first non space character */
     198        1308 :     for( p=string; *p && isspace( *(byte*)p ) ; p++ )
     199             :         ;
     200             :     /* move characters */
     201       89877 :     for( (mark = NULL); (*string = *p); string++, p++ )
     202       88569 :         if( isspace( *(byte*)p ) ) {
     203           0 :             if( !mark )
     204           0 :                 mark = string ;
     205             :         }
     206             :         else
     207       88569 :             mark = NULL ;
     208        1308 :     if( mark )
     209           0 :         *mark = '\0' ;  /* remove trailing spaces */
     210             : 
     211        1308 :     return str ;
     212             : }
     213             : 
     214             : /****************
     215             :  * remove trailing white spaces
     216             :  */
     217             : char *
     218           0 : trim_trailing_spaces( char *string )
     219             : {
     220             :     char *p, *mark;
     221             : 
     222           0 :     for( mark = NULL, p = string; *p; p++ ) {
     223           0 :         if( isspace( *(byte*)p ) ) {
     224           0 :             if( !mark )
     225           0 :                 mark = p;
     226             :         }
     227             :         else
     228           0 :             mark = NULL;
     229             :     }
     230           0 :     if( mark )
     231           0 :         *mark = '\0' ;
     232             : 
     233           0 :     return string ;
     234             : }
     235             : 
     236             : 
     237             : unsigned
     238        5362 : trim_trailing_chars( byte *line, unsigned len, const char *trimchars )
     239             : {
     240             :     byte *p, *mark;
     241             :     unsigned n;
     242             : 
     243      212848 :     for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
     244      207486 :         if( strchr(trimchars, *p ) ) {
     245       39017 :             if( !mark )
     246       33102 :                 mark = p;
     247             :         }
     248             :         else
     249      168469 :             mark = NULL;
     250             :     }
     251             : 
     252        5362 :     if( mark ) {
     253        5355 :         *mark = 0;
     254        5355 :         return mark - line;
     255             :     }
     256           7 :     return len;
     257             : }
     258             : 
     259             : /****************
     260             :  * remove trailing white spaces and return the length of the buffer
     261             :  */
     262             : unsigned
     263          21 : trim_trailing_ws( byte *line, unsigned len )
     264             : {
     265          21 :     return trim_trailing_chars( line, len, " \t\r\n" );
     266             : }
     267             : 
     268             : size_t
     269         287 : length_sans_trailing_chars (const unsigned char *line, size_t len,
     270             :                             const char *trimchars )
     271             : {
     272             :   const unsigned char *p, *mark;
     273             :   size_t n;
     274             : 
     275        4151 :   for( mark=NULL, p=line, n=0; n < len; n++, p++ )
     276             :     {
     277        3864 :       if (strchr (trimchars, *p ))
     278             :         {
     279         674 :           if( !mark )
     280         674 :             mark = p;
     281             :         }
     282             :       else
     283        3190 :         mark = NULL;
     284             :     }
     285             : 
     286         287 :   if (mark)
     287         287 :     return mark - line;
     288           0 :   return len;
     289             : }
     290             : 
     291             : /*
     292             :  *  Return the length of line ignoring trailing white-space.
     293             :  */
     294             : size_t
     295         287 : length_sans_trailing_ws (const unsigned char *line, size_t len)
     296             : {
     297         287 :   return length_sans_trailing_chars (line, len, " \t\r\n");
     298             : }
     299             : 
     300             : 
     301             : 
     302             : /*
     303             :  * Extract from a given path the filename component.  This function
     304             :  * terminates the process on memory shortage.
     305             :  */
     306             : char *
     307         496 : make_basename(const char *filepath, const char *inputpath)
     308             : {
     309             : #ifdef __riscos__
     310             :     return riscos_make_basename(filepath, inputpath);
     311             : #else
     312             :     char *p;
     313             : 
     314             :     (void)inputpath; /* Only required for riscos.  */
     315             : 
     316         496 :     if ( !(p=strrchr(filepath, '/')) )
     317             : #ifdef HAVE_DOSISH_SYSTEM
     318             :         if ( !(p=strrchr(filepath, '\\')) )
     319             : #endif
     320             : #ifdef HAVE_DRIVE_LETTERS
     321             :             if ( !(p=strrchr(filepath, ':')) )
     322             : #endif
     323             :               {
     324         496 :                 return xstrdup(filepath);
     325             :               }
     326             : 
     327           0 :     return xstrdup(p+1);
     328             : #endif
     329             : }
     330             : 
     331             : 
     332             : 
     333             : /*
     334             :  * Extract from a given filename the path prepended to it.  If there
     335             :  * isn't a path prepended to the filename, a dot is returned ('.').
     336             :  * This function terminates the process on memory shortage.
     337             :  */
     338             : char *
     339           0 : make_dirname(const char *filepath)
     340             : {
     341             :     char *dirname;
     342             :     int  dirname_length;
     343             :     char *p;
     344             : 
     345           0 :     if ( !(p=strrchr(filepath, '/')) )
     346             : #ifdef HAVE_DOSISH_SYSTEM
     347             :         if ( !(p=strrchr(filepath, '\\')) )
     348             : #endif
     349             : #ifdef HAVE_DRIVE_LETTERS
     350             :             if ( !(p=strrchr(filepath, ':')) )
     351             : #endif
     352             :               {
     353           0 :                 return xstrdup(".");
     354             :               }
     355             : 
     356           0 :     dirname_length = p-filepath;
     357           0 :     dirname = xmalloc(dirname_length+1);
     358           0 :     strncpy(dirname, filepath, dirname_length);
     359           0 :     dirname[dirname_length] = 0;
     360             : 
     361           0 :     return dirname;
     362             : }
     363             : 
     364             : 
     365             : 
     366             : static char *
     367           0 : get_pwdir (int xmode, const char *name)
     368             : {
     369           0 :   char *result = NULL;
     370             : #ifdef HAVE_PWD_H
     371           0 :   struct passwd *pwd = NULL;
     372             : 
     373           0 :   if (name)
     374             :     {
     375             : #ifdef HAVE_GETPWNAM
     376             :       /* Fixme: We should use getpwnam_r if available.  */
     377           0 :       pwd = getpwnam (name);
     378             : #endif
     379             :     }
     380             :   else
     381             :     {
     382             : #ifdef HAVE_GETPWUID
     383             :       /* Fixme: We should use getpwuid_r if available.  */
     384           0 :       pwd = getpwuid (getuid());
     385             : #endif
     386             :     }
     387           0 :   if (pwd)
     388             :     {
     389           0 :       if (xmode)
     390           0 :         result = xstrdup (pwd->pw_dir);
     391             :       else
     392           0 :         result = xtrystrdup (pwd->pw_dir);
     393             :     }
     394             : #else /*!HAVE_PWD_H*/
     395             :   /* No support at all.  */
     396             :   (void)xmode;
     397             :   (void)name;
     398             : #endif /*HAVE_PWD_H*/
     399           0 :   return result;
     400             : }
     401             : 
     402             : 
     403             : /* xmode 0 := Return NULL on error
     404             :          1 := Terminate on error
     405             :          2 := Make sure that name is absolute; return NULL on error
     406             :          3 := Make sure that name is absolute; terminate on error
     407             :  */
     408             : static char *
     409       11805 : do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
     410             : {
     411             :   const char *argv[32];
     412             :   int argc;
     413             :   size_t n;
     414       11805 :   int skip = 1;
     415       11805 :   char *home_buffer = NULL;
     416             :   char *name, *home, *p;
     417             :   int want_abs;
     418             : 
     419       11805 :   want_abs = !!(xmode & 2);
     420       11805 :   xmode &= 1;
     421             : 
     422       11805 :   n = strlen (first_part) + 1;
     423       11805 :   argc = 0;
     424       36949 :   while ( (argv[argc] = va_arg (arg_ptr, const char *)) )
     425             :     {
     426       13341 :       n += strlen (argv[argc]) + 1;
     427       13341 :       if (argc >= DIM (argv)-1)
     428             :         {
     429           2 :           if (xmode)
     430           0 :             BUG ();
     431           2 :           gpg_err_set_errno (EINVAL);
     432           2 :           return NULL;
     433             :         }
     434       13339 :       argc++;
     435             :     }
     436       11803 :   n++;
     437             : 
     438       11803 :   home = NULL;
     439       11803 :   if (*first_part == '~')
     440             :     {
     441           2 :       if (first_part[1] == '/' || !first_part[1])
     442             :         {
     443             :           /* This is the "~/" or "~" case.  */
     444           2 :           home = getenv("HOME");
     445           2 :           if (!home)
     446           0 :             home = home_buffer = get_pwdir (xmode, NULL);
     447           4 :           if (home && *home)
     448           2 :             n += strlen (home);
     449             :         }
     450             :       else
     451             :         {
     452             :           /* This is the "~username/" or "~username" case.  */
     453             :           char *user;
     454             : 
     455           0 :           if (xmode)
     456           0 :             user = xstrdup (first_part+1);
     457             :           else
     458             :             {
     459           0 :               user = xtrystrdup (first_part+1);
     460           0 :               if (!user)
     461           0 :                 return NULL;
     462             :             }
     463           0 :           p = strchr (user, '/');
     464           0 :           if (p)
     465           0 :             *p = 0;
     466           0 :           skip = 1 + strlen (user);
     467             : 
     468           0 :           home = home_buffer = get_pwdir (xmode, user);
     469           0 :           xfree (user);
     470           0 :           if (home)
     471           0 :             n += strlen (home);
     472             :           else
     473           0 :             skip = 1;
     474             :         }
     475             :     }
     476             : 
     477       11803 :   if (xmode)
     478       11570 :     name = xmalloc (n);
     479             :   else
     480             :     {
     481         233 :       name = xtrymalloc (n);
     482         233 :       if (!name)
     483             :         {
     484           0 :           xfree (home_buffer);
     485           0 :           return NULL;
     486             :         }
     487             :     }
     488             : 
     489       11803 :   if (home)
     490           2 :     p = stpcpy (stpcpy (name, home), first_part + skip);
     491             :   else
     492       11801 :     p = stpcpy (name, first_part);
     493             : 
     494       11803 :   xfree (home_buffer);
     495       25080 :   for (argc=0; argv[argc]; argc++)
     496             :     {
     497             :       /* Avoid a leading double slash if the first part was "/".  */
     498       13277 :       if (!argc && name[0] == '/' && !name[1])
     499           0 :         p = stpcpy (p, argv[argc]);
     500             :       else
     501       13277 :         p = stpcpy (stpcpy (p, "/"), argv[argc]);
     502             :     }
     503             : 
     504       11803 :   if (want_abs)
     505             :     {
     506             : #ifdef HAVE_DRIVE_LETTERS
     507             :       p = strchr (name, ':');
     508             :       if (p)
     509             :         p++;
     510             :       else
     511             :         p = name;
     512             : #else
     513         401 :       p = name;
     514             : #endif
     515         401 :       if (*p != '/'
     516             : #ifdef HAVE_DRIVE_LETTERS
     517             :           && *p != '\\'
     518             : #endif
     519             :           )
     520             :         {
     521           3 :           home = gnupg_getcwd ();
     522           3 :           if (!home)
     523             :             {
     524           0 :               if (xmode)
     525             :                 {
     526           0 :                   fprintf (stderr, "\nfatal: getcwd failed: %s\n",
     527           0 :                            strerror (errno));
     528           0 :                   exit(2);
     529             :                 }
     530           0 :               xfree (name);
     531           0 :               return NULL;
     532             :             }
     533           3 :           n = strlen (home) + 1 + strlen (name) + 1;
     534           3 :           if (xmode)
     535           0 :             home_buffer = xmalloc (n);
     536             :           else
     537             :             {
     538           3 :               home_buffer = xtrymalloc (n);
     539           3 :               if (!home_buffer)
     540             :                 {
     541           0 :                   xfree (name);
     542           0 :                   return NULL;
     543             :                 }
     544             :             }
     545           3 :           if (p == name)
     546           3 :             p = home_buffer;
     547             :           else /* Windows case.  */
     548             :             {
     549           0 :               memcpy (home_buffer, p, p - name + 1);
     550           0 :               p = home_buffer + (p - name + 1);
     551             :             }
     552             : 
     553             :           /* Avoid a leading double slash if the cwd is "/".  */
     554           3 :           if (home[0] == '/' && !home[1])
     555           0 :             strcpy (stpcpy (p, "/"), name);
     556             :           else
     557           3 :             strcpy (stpcpy (stpcpy (p, home), "/"), name);
     558             : 
     559           3 :           xfree (name);
     560           3 :           name = home_buffer;
     561             :           /* Let's do a simple compression to catch the most common
     562             :              case of using "." for gpg's --homedir option.  */
     563           3 :           n = strlen (name);
     564           3 :           if (n > 2 && name[n-2] == '/' && name[n-1] == '.')
     565           1 :             name[n-2] = 0;
     566             :         }
     567             :     }
     568       11803 :   return change_slashes (name);
     569             : }
     570             : 
     571             : /* Construct a filename from the NULL terminated list of parts.  Tilde
     572             :    expansion is done for the first argument.  This function terminates
     573             :    the process on memory shortage. */
     574             : char *
     575       11174 : make_filename (const char *first_part, ... )
     576             : {
     577             :   va_list arg_ptr;
     578             :   char *result;
     579             : 
     580       11174 :   va_start (arg_ptr, first_part);
     581       11174 :   result = do_make_filename (1, first_part, arg_ptr);
     582       11174 :   va_end (arg_ptr);
     583       11174 :   return result;
     584             : }
     585             : 
     586             : /* Construct a filename from the NULL terminated list of parts.  Tilde
     587             :    expansion is done for the first argument.  This function may return
     588             :    NULL on error. */
     589             : char *
     590         230 : make_filename_try (const char *first_part, ... )
     591             : {
     592             :   va_list arg_ptr;
     593             :   char *result;
     594             : 
     595         230 :   va_start (arg_ptr, first_part);
     596         230 :   result = do_make_filename (0, first_part, arg_ptr);
     597         230 :   va_end (arg_ptr);
     598         230 :   return result;
     599             : }
     600             : 
     601             : /* Construct an absolute filename from the NULL terminated list of
     602             :    parts.  Tilde expansion is done for the first argument.  This
     603             :    function terminates the process on memory shortage. */
     604             : char *
     605         396 : make_absfilename (const char *first_part, ... )
     606             : {
     607             :   va_list arg_ptr;
     608             :   char *result;
     609             : 
     610         396 :   va_start (arg_ptr, first_part);
     611         396 :   result = do_make_filename (3, first_part, arg_ptr);
     612         396 :   va_end (arg_ptr);
     613         396 :   return result;
     614             : }
     615             : 
     616             : /* Construct an absolute filename from the NULL terminated list of
     617             :    parts.  Tilde expansion is done for the first argument.  This
     618             :    function may return NULL on error. */
     619             : char *
     620           5 : make_absfilename_try (const char *first_part, ... )
     621             : {
     622             :   va_list arg_ptr;
     623             :   char *result;
     624             : 
     625           5 :   va_start (arg_ptr, first_part);
     626           5 :   result = do_make_filename (2, first_part, arg_ptr);
     627           5 :   va_end (arg_ptr);
     628           5 :   return result;
     629             : }
     630             : 
     631             : 
     632             : 
     633             : /* Compare whether the filenames are identical.  This is a
     634             :    special version of strcmp() taking the semantics of filenames in
     635             :    account.  Note that this function works only on the supplied names
     636             :    without considering any context like the current directory.  See
     637             :    also same_file_p(). */
     638             : int
     639        1042 : compare_filenames (const char *a, const char *b)
     640             : {
     641             : #ifdef HAVE_DOSISH_SYSTEM
     642             :   for ( ; *a && *b; a++, b++ )
     643             :     {
     644             :       if (*a != *b
     645             :           && (toupper (*(const unsigned char*)a)
     646             :               != toupper (*(const unsigned char*)b) )
     647             :           && !((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/')))
     648             :         break;
     649             :     }
     650             :   if ((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/'))
     651             :     return 0;
     652             :   else
     653             :     return (toupper (*(const unsigned char*)a)
     654             :             - toupper (*(const unsigned char*)b));
     655             : #else
     656        1042 :     return strcmp(a,b);
     657             : #endif
     658             : }
     659             : 
     660             : 
     661             : /* Convert 2 hex characters at S to a byte value.  Return this value
     662             :    or -1 if there is an error. */
     663             : int
     664         100 : hextobyte (const char *s)
     665             : {
     666             :   int c;
     667             : 
     668         100 :   if ( *s >= '0' && *s <= '9' )
     669          54 :     c = 16 * (*s - '0');
     670          46 :   else if ( *s >= 'A' && *s <= 'F' )
     671          46 :     c = 16 * (10 + *s - 'A');
     672           0 :   else if ( *s >= 'a' && *s <= 'f' )
     673           0 :     c = 16 * (10 + *s - 'a');
     674             :   else
     675           0 :     return -1;
     676         100 :   s++;
     677         100 :   if ( *s >= '0' && *s <= '9' )
     678          59 :     c += *s - '0';
     679          41 :   else if ( *s >= 'A' && *s <= 'F' )
     680          41 :     c += 10 + *s - 'A';
     681           0 :   else if ( *s >= 'a' && *s <= 'f' )
     682           0 :     c += 10 + *s - 'a';
     683             :   else
     684           0 :     return -1;
     685         100 :   return c;
     686             : }
     687             : 
     688             : 
     689             : /* Create a string from the buffer P_ARG of length N which is suitable
     690             :    for printing.  Caller must release the created string using xfree.
     691             :    This function terminates the process on memory shortage.  */
     692             : char *
     693           0 : sanitize_buffer (const void *p_arg, size_t n, int delim)
     694             : {
     695           0 :   const unsigned char *p = p_arg;
     696             :   size_t save_n, buflen;
     697             :   const unsigned char *save_p;
     698             :   char *buffer, *d;
     699             : 
     700             :   /* First count length. */
     701           0 :   for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ )
     702             :     {
     703           0 :       if ( *p < 0x20 || *p == 0x7f || *p == delim  || (delim && *p=='\\'))
     704             :         {
     705           0 :           if ( *p=='\n' || *p=='\r' || *p=='\f'
     706           0 :                || *p=='\v' || *p=='\b' || !*p )
     707           0 :             buflen += 2;
     708             :           else
     709           0 :             buflen += 5;
     710             :         }
     711             :       else
     712           0 :         buflen++;
     713             :     }
     714           0 :   p = save_p;
     715           0 :   n = save_n;
     716             :   /* And now make the string */
     717           0 :   d = buffer = xmalloc( buflen );
     718           0 :   for ( ; n; n--, p++ )
     719             :     {
     720           0 :       if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) {
     721           0 :         *d++ = '\\';
     722           0 :         if( *p == '\n' )
     723           0 :           *d++ = 'n';
     724           0 :         else if( *p == '\r' )
     725           0 :           *d++ = 'r';
     726           0 :         else if( *p == '\f' )
     727           0 :           *d++ = 'f';
     728           0 :         else if( *p == '\v' )
     729           0 :           *d++ = 'v';
     730           0 :         else if( *p == '\b' )
     731           0 :           *d++ = 'b';
     732           0 :         else if( !*p )
     733           0 :           *d++ = '0';
     734             :         else {
     735           0 :           sprintf(d, "x%02x", *p );
     736           0 :           d += 3;
     737             :         }
     738             :       }
     739             :       else
     740           0 :         *d++ = *p;
     741             :     }
     742           0 :   *d = 0;
     743           0 :   return buffer;
     744             : }
     745             : 
     746             : 
     747             : /* Given a string containing an UTF-8 encoded text, return the number
     748             :    of characters in this string.  It differs from strlen in that it
     749             :    only counts complete UTF-8 characters.  Note, that this function
     750             :    does not take combined characters into account.  */
     751             : size_t
     752          92 : utf8_charcount (const char *s)
     753             : {
     754             :   size_t n;
     755             : 
     756         897 :   for (n=0; *s; s++)
     757         805 :     if ( (*s&0xc0) != 0x80 ) /* Exclude continuation bytes: 10xxxxxx */
     758         805 :       n++;
     759             : 
     760          92 :   return n;
     761             : }
     762             : 
     763             : 
     764             : /****************************************************
     765             :  **********  W32 specific functions  ****************
     766             :  ****************************************************/
     767             : 
     768             : #ifdef HAVE_W32_SYSTEM
     769             : const char *
     770             : w32_strerror (int ec)
     771             : {
     772             :   static char strerr[256];
     773             : 
     774             :   if (ec == -1)
     775             :     ec = (int)GetLastError ();
     776             : #ifdef HAVE_W32CE_SYSTEM
     777             :   /* There is only a wchar_t FormatMessage.  It does not make much
     778             :      sense to play the conversion game; we print only the code.  */
     779             :   snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ());
     780             : #else
     781             :   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
     782             :                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
     783             :                  strerr, DIM (strerr)-1, NULL);
     784             : #endif
     785             :   return strerr;
     786             : }
     787             : #endif /*HAVE_W32_SYSTEM*/
     788             : 
     789             : 
     790             : /****************************************************
     791             :  ******** Locale insensitive ctype functions ********
     792             :  ****************************************************/
     793             : /* FIXME: replace them by a table lookup and macros */
     794             : int
     795           0 : ascii_isupper (int c)
     796             : {
     797           0 :     return c >= 'A' && c <= 'Z';
     798             : }
     799             : 
     800             : int
     801           0 : ascii_islower (int c)
     802             : {
     803           0 :     return c >= 'a' && c <= 'z';
     804             : }
     805             : 
     806             : int
     807      578188 : ascii_toupper (int c)
     808             : {
     809      578188 :     if (c >= 'a' && c <= 'z')
     810      448904 :         c &= ~0x20;
     811      578188 :     return c;
     812             : }
     813             : 
     814             : int
     815           4 : ascii_tolower (int c)
     816             : {
     817           4 :     if (c >= 'A' && c <= 'Z')
     818           2 :         c |= 0x20;
     819           4 :     return c;
     820             : }
     821             : 
     822             : /* Lowercase all ASCII characters in S.  */
     823             : char *
     824         286 : ascii_strlwr (char *s)
     825             : {
     826         286 :   char *p = s;
     827             : 
     828        5574 :   for (p=s; *p; p++ )
     829        5288 :     if (isascii (*p) && *p >= 'A' && *p <= 'Z')
     830         266 :       *p |= 0x20;
     831             : 
     832         286 :   return s;
     833             : }
     834             : 
     835             : int
     836        9313 : ascii_strcasecmp( const char *a, const char *b )
     837             : {
     838        9313 :     if (a == b)
     839           0 :         return 0;
     840             : 
     841       21732 :     for (; *a && *b; a++, b++) {
     842       20078 :         if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b))
     843        7659 :             break;
     844             :     }
     845        9313 :     return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
     846             : }
     847             : 
     848             : int
     849           2 : ascii_strncasecmp (const char *a, const char *b, size_t n)
     850             : {
     851           2 :   const unsigned char *p1 = (const unsigned char *)a;
     852           2 :   const unsigned char *p2 = (const unsigned char *)b;
     853             :   unsigned char c1, c2;
     854             : 
     855           2 :   if (p1 == p2 || !n )
     856           0 :     return 0;
     857             : 
     858             :   do
     859             :     {
     860           2 :       c1 = ascii_tolower (*p1);
     861           2 :       c2 = ascii_tolower (*p2);
     862             : 
     863           2 :       if ( !--n || c1 == '\0')
     864             :         break;
     865             : 
     866           2 :       ++p1;
     867           2 :       ++p2;
     868             :     }
     869           2 :   while (c1 == c2);
     870             : 
     871           2 :   return c1 - c2;
     872             : }
     873             : 
     874             : 
     875             : int
     876      131109 : ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n )
     877             : {
     878      131109 :   const char *a = a_arg;
     879      131109 :   const char *b = b_arg;
     880             : 
     881      131109 :   if (a == b)
     882           0 :     return 0;
     883      143225 :   for ( ; n; n--, a++, b++ )
     884             :     {
     885      143079 :       if( *a != *b  && ascii_toupper (*a) != ascii_toupper (*b) )
     886      130963 :         return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
     887             :     }
     888         146 :   return 0;
     889             : }
     890             : 
     891             : int
     892           0 : ascii_strcmp( const char *a, const char *b )
     893             : {
     894           0 :     if (a == b)
     895           0 :         return 0;
     896             : 
     897           0 :     for (; *a && *b; a++, b++) {
     898           0 :         if (*a != *b )
     899           0 :             break;
     900             :     }
     901           0 :     return *a == *b? 0 : (*(signed char *)a - *(signed char *)b);
     902             : }
     903             : 
     904             : 
     905             : void *
     906        5222 : ascii_memcasemem (const void *haystack, size_t nhaystack,
     907             :                   const void *needle, size_t nneedle)
     908             : {
     909             : 
     910        5222 :   if (!nneedle)
     911           0 :     return (void*)haystack; /* finding an empty needle is really easy */
     912        5222 :   if (nneedle <= nhaystack)
     913             :     {
     914        4960 :       const char *a = haystack;
     915        4960 :       const char *b = a + nhaystack - nneedle;
     916             : 
     917      134574 :       for (; a <= b; a++)
     918             :         {
     919      129760 :           if ( !ascii_memcasecmp (a, needle, nneedle) )
     920         146 :             return (void *)a;
     921             :         }
     922             :     }
     923        5076 :   return NULL;
     924             : }
     925             : 
     926             : /*********************************************
     927             :  ********** missing string functions *********
     928             :  *********************************************/
     929             : 
     930             : #ifndef HAVE_STPCPY
     931             : char *
     932             : stpcpy(char *a,const char *b)
     933             : {
     934             :     while( *b )
     935             :         *a++ = *b++;
     936             :     *a = 0;
     937             : 
     938             :     return (char*)a;
     939             : }
     940             : #endif
     941             : 
     942             : #ifndef HAVE_STRPBRK
     943             : /* Find the first occurrence in S of any character in ACCEPT.
     944             :    Code taken from glibc-2.6/string/strpbrk.c (LGPLv2.1+) and modified. */
     945             : char *
     946             : strpbrk (const char *s, const char *accept)
     947             : {
     948             :   while (*s != '\0')
     949             :     {
     950             :       const char *a = accept;
     951             :       while (*a != '\0')
     952             :         if (*a++ == *s)
     953             :           return (char *) s;
     954             :       ++s;
     955             :     }
     956             : 
     957             :   return NULL;
     958             : }
     959             : #endif /*!HAVE_STRPBRK*/
     960             : 
     961             : 
     962             : #ifndef HAVE_STRSEP
     963             : /* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
     964             : char *
     965             : strsep (char **stringp, const char *delim)
     966             : {
     967             :   char *begin, *end;
     968             : 
     969             :   begin = *stringp;
     970             :   if (begin == NULL)
     971             :     return NULL;
     972             : 
     973             :   /* A frequent case is when the delimiter string contains only one
     974             :      character.  Here we don't need to call the expensive 'strpbrk'
     975             :      function and instead work using 'strchr'.  */
     976             :   if (delim[0] == '\0' || delim[1] == '\0')
     977             :     {
     978             :       char ch = delim[0];
     979             : 
     980             :       if (ch == '\0')
     981             :         end = NULL;
     982             :       else
     983             :         {
     984             :           if (*begin == ch)
     985             :             end = begin;
     986             :           else if (*begin == '\0')
     987             :             end = NULL;
     988             :           else
     989             :             end = strchr (begin + 1, ch);
     990             :         }
     991             :     }
     992             :   else
     993             :     /* Find the end of the token.  */
     994             :     end = strpbrk (begin, delim);
     995             : 
     996             :   if (end)
     997             :     {
     998             :       /* Terminate the token and set *STRINGP past NUL character.  */
     999             :       *end++ = '\0';
    1000             :       *stringp = end;
    1001             :     }
    1002             :   else
    1003             :     /* No more delimiters; this is the last token.  */
    1004             :     *stringp = NULL;
    1005             : 
    1006             :   return begin;
    1007             : }
    1008             : #endif /*HAVE_STRSEP*/
    1009             : 
    1010             : 
    1011             : #ifndef HAVE_STRLWR
    1012             : char *
    1013           6 : strlwr(char *s)
    1014             : {
    1015             :     char *p;
    1016         288 :     for(p=s; *p; p++ )
    1017         282 :         *p = tolower(*p);
    1018           6 :     return s;
    1019             : }
    1020             : #endif
    1021             : 
    1022             : 
    1023             : #ifndef HAVE_STRCASECMP
    1024             : int
    1025             : strcasecmp( const char *a, const char *b )
    1026             : {
    1027             :     for( ; *a && *b; a++, b++ ) {
    1028             :         if( *a != *b && toupper(*a) != toupper(*b) )
    1029             :             break;
    1030             :     }
    1031             :     return *(const byte*)a - *(const byte*)b;
    1032             : }
    1033             : #endif
    1034             : 
    1035             : 
    1036             : /****************
    1037             :  * mingw32/cpd has a memicmp()
    1038             :  */
    1039             : #ifndef HAVE_MEMICMP
    1040             : int
    1041           0 : memicmp( const char *a, const char *b, size_t n )
    1042             : {
    1043           0 :     for( ; n; n--, a++, b++ )
    1044           0 :         if( *a != *b  && toupper(*(const byte*)a) != toupper(*(const byte*)b) )
    1045           0 :             return *(const byte *)a - *(const byte*)b;
    1046           0 :     return 0;
    1047             : }
    1048             : #endif
    1049             : 
    1050             : 
    1051             : #ifndef HAVE_MEMRCHR
    1052             : void *
    1053             : memrchr (const void *buffer, int c, size_t n)
    1054             : {
    1055             :   const unsigned char *p = buffer;
    1056             : 
    1057             :   for (p += n; n ; n--)
    1058             :     if (*--p == c)
    1059             :       return (void *)p;
    1060             :   return NULL;
    1061             : }
    1062             : #endif /*HAVE_MEMRCHR*/
    1063             : 
    1064             : 
    1065             : /* Percent-escape the string STR by replacing colons with '%3a'.  If
    1066             :    EXTRA is not NULL all characters in EXTRA are also escaped.  */
    1067             : static char *
    1068          22 : do_percent_escape (const char *str, const char *extra, int die)
    1069             : {
    1070             :   int i, j;
    1071             :   char *ptr;
    1072             : 
    1073          22 :   if (!str)
    1074           1 :     return NULL;
    1075             : 
    1076          69 :   for (i=j=0; str[i]; i++)
    1077          48 :     if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
    1078          38 :       j++;
    1079          21 :   if (die)
    1080          21 :     ptr = xmalloc (i + 2 * j + 1);
    1081             :   else
    1082             :     {
    1083           0 :       ptr = xtrymalloc (i + 2 * j + 1);
    1084           0 :       if (!ptr)
    1085           0 :         return NULL;
    1086             :     }
    1087          21 :   i = 0;
    1088          90 :   while (*str)
    1089             :     {
    1090          48 :       if (*str == ':')
    1091             :         {
    1092          19 :           ptr[i++] = '%';
    1093          19 :           ptr[i++] = '3';
    1094          19 :           ptr[i++] = 'a';
    1095             :         }
    1096          29 :       else if (*str == '%')
    1097             :         {
    1098          15 :           ptr[i++] = '%';
    1099          15 :           ptr[i++] = '2';
    1100          15 :           ptr[i++] = '5';
    1101             :         }
    1102          14 :       else if (extra && strchr (extra, *str))
    1103             :         {
    1104           4 :           ptr[i++] = '%';
    1105           4 :           ptr[i++] = tohex_lower ((*str>>4)&15);
    1106           4 :           ptr[i++] = tohex_lower (*str&15);
    1107             :         }
    1108             :       else
    1109          10 :         ptr[i++] = *str;
    1110          48 :       str++;
    1111             :     }
    1112          21 :   ptr[i] = '\0';
    1113             : 
    1114          21 :   return ptr;
    1115             : }
    1116             : 
    1117             : /* Percent-escape the string STR by replacing colons with '%3a'.  If
    1118             :    EXTRA is not NULL all characters in EXTRA are also escaped.  This
    1119             :    function terminates the process on memory shortage.  */
    1120             : char *
    1121          22 : percent_escape (const char *str, const char *extra)
    1122             : {
    1123          22 :   return do_percent_escape (str, extra, 1);
    1124             : }
    1125             : 
    1126             : /* Same as percent_escape but return NULL instead of exiting on memory
    1127             :    error. */
    1128             : char *
    1129           0 : try_percent_escape (const char *str, const char *extra)
    1130             : {
    1131           0 :   return do_percent_escape (str, extra, 0);
    1132             : }
    1133             : 
    1134             : 
    1135             : 
    1136             : static char *
    1137          79 : do_strconcat (const char *s1, va_list arg_ptr)
    1138             : {
    1139             :   const char *argv[48];
    1140             :   size_t argc;
    1141             :   size_t needed;
    1142             :   char *buffer, *p;
    1143             : 
    1144          79 :   argc = 0;
    1145          79 :   argv[argc++] = s1;
    1146          79 :   needed = strlen (s1);
    1147         431 :   while (((argv[argc] = va_arg (arg_ptr, const char *))))
    1148             :     {
    1149         275 :       needed += strlen (argv[argc]);
    1150         275 :       if (argc >= DIM (argv)-1)
    1151             :         {
    1152           2 :           gpg_err_set_errno (EINVAL);
    1153           2 :           return NULL;
    1154             :         }
    1155         273 :       argc++;
    1156             :     }
    1157          77 :   needed++;
    1158          77 :   buffer = xtrymalloc (needed);
    1159          77 :   if (buffer)
    1160             :     {
    1161         335 :       for (p = buffer, argc=0; argv[argc]; argc++)
    1162         258 :         p = stpcpy (p, argv[argc]);
    1163             :     }
    1164          77 :   return buffer;
    1165             : }
    1166             : 
    1167             : 
    1168             : /* Concatenate the string S1 with all the following strings up to a
    1169             :    NULL.  Returns a malloced buffer with the new string or NULL on a
    1170             :    malloc error or if too many arguments are given.  */
    1171             : char *
    1172          12 : strconcat (const char *s1, ...)
    1173             : {
    1174             :   va_list arg_ptr;
    1175             :   char *result;
    1176             : 
    1177          12 :   if (!s1)
    1178           1 :     result = xtrystrdup ("");
    1179             :   else
    1180             :     {
    1181          11 :       va_start (arg_ptr, s1);
    1182          11 :       result = do_strconcat (s1, arg_ptr);
    1183          11 :       va_end (arg_ptr);
    1184             :     }
    1185          12 :   return result;
    1186             : }
    1187             : 
    1188             : /* Same as strconcat but terminate the process with an error message
    1189             :    if something goes wrong.  */
    1190             : char *
    1191          69 : xstrconcat (const char *s1, ...)
    1192             : {
    1193             :   va_list arg_ptr;
    1194             :   char *result;
    1195             : 
    1196          69 :   if (!s1)
    1197           1 :     result = xstrdup ("");
    1198             :   else
    1199             :     {
    1200          68 :       va_start (arg_ptr, s1);
    1201          68 :       result = do_strconcat (s1, arg_ptr);
    1202          68 :       va_end (arg_ptr);
    1203             :     }
    1204          69 :   if (!result)
    1205             :     {
    1206           0 :       if (errno == EINVAL)
    1207           0 :         fputs ("\nfatal: too many args for xstrconcat\n", stderr);
    1208             :       else
    1209           0 :         fputs ("\nfatal: out of memory\n", stderr);
    1210           0 :       exit (2);
    1211             :     }
    1212          69 :   return result;
    1213             : }
    1214             : 
    1215             : /* Split a string into fields at DELIM.  REPLACEMENT is the character
    1216             :    to replace the delimiter with (normally: '\0' so that each field is
    1217             :    NUL terminated).  The caller is responsible for freeing the result.
    1218             :    Note: this function modifies STRING!  If you need the original
    1219             :    value, then you should pass a copy to this function.
    1220             : 
    1221             :    If malloc fails, this function returns NULL.  */
    1222             : char **
    1223           3 : strsplit (char *string, char delim, char replacement, int *count)
    1224             : {
    1225           3 :   int fields = 1;
    1226             :   char *t;
    1227             :   char **result;
    1228             : 
    1229             :   /* First, count the number of fields.  */
    1230          15 :   for (t = strchr (string, delim); t; t = strchr (t + 1, delim))
    1231          12 :     fields ++;
    1232             : 
    1233           3 :   result = xtrycalloc ((fields + 1), sizeof (*result));
    1234           3 :   if (! result)
    1235           0 :     return NULL;
    1236             : 
    1237           3 :   result[0] = string;
    1238           3 :   fields = 1;
    1239          15 :   for (t = strchr (string, delim); t; t = strchr (t + 1, delim))
    1240             :     {
    1241          12 :       result[fields ++] = t + 1;
    1242          12 :       *t = replacement;
    1243             :     }
    1244             : 
    1245           3 :   if (count)
    1246           3 :     *count = fields;
    1247             : 
    1248           3 :   return result;
    1249             : }
    1250             : 
    1251             : 
    1252             : /* Tokenize STRING using the set of delimiters in DELIM.  Leading
    1253             :  * spaces and tabs are removed from all tokens.  The caller must xfree
    1254             :  * the result.
    1255             :  *
    1256             :  * Returns: A malloced and NULL delimited array with the tokens.  On
    1257             :  *          memory error NULL is returned and ERRNO is set.
    1258             :  */
    1259             : char **
    1260          22 : strtokenize (const char *string, const char *delim)
    1261             : {
    1262             :   const char *s;
    1263             :   size_t fields;
    1264             :   size_t bytes, n;
    1265             :   char *buffer;
    1266             :   char *p, *px, *pend;
    1267             :   char **result;
    1268             : 
    1269             :   /* Count the number of fields.  */
    1270          63 :   for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim))
    1271          41 :     fields++;
    1272          22 :   fields++; /* Add one for the terminating NULL.  */
    1273             : 
    1274             :   /* Allocate an array for all fields, a terminating NULL, and space
    1275             :      for a copy of the string.  */
    1276          22 :   bytes = fields * sizeof *result;
    1277          22 :   if (bytes / sizeof *result != fields)
    1278             :     {
    1279           0 :       gpg_err_set_errno (ENOMEM);
    1280           0 :       return NULL;
    1281             :     }
    1282          22 :   n = strlen (string) + 1;
    1283          22 :   bytes += n;
    1284          22 :   if (bytes < n)
    1285             :     {
    1286           0 :       gpg_err_set_errno (ENOMEM);
    1287           0 :       return NULL;
    1288             :     }
    1289          22 :   result = xtrymalloc (bytes);
    1290          22 :   if (!result)
    1291           0 :     return NULL;
    1292          22 :   buffer = (char*)(result + fields);
    1293             : 
    1294             :   /* Copy and parse the string.  */
    1295          22 :   strcpy (buffer, string);
    1296          63 :   for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
    1297             :     {
    1298          41 :       *pend = 0;
    1299          96 :       while (spacep (p))
    1300          14 :         p++;
    1301          41 :       for (px = pend - 1; px >= p && spacep (px); px--)
    1302           0 :         *px = 0;
    1303          41 :       result[n++] = p;
    1304             :     }
    1305          51 :   while (spacep (p))
    1306           7 :     p++;
    1307          25 :   for (px = p + strlen (p) - 1; px >= p && spacep (px); px--)
    1308           3 :     *px = 0;
    1309          22 :   result[n++] = p;
    1310          22 :   result[n] = NULL;
    1311             : 
    1312          22 :   assert ((char*)(result + n + 1) == buffer);
    1313             : 
    1314          22 :   return result;
    1315             : }

Generated by: LCOV version 1.11