LCOV - code coverage report
Current view: top level - lib - xvasprintf.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 13 37 35.1 %
Date: 2017-08-04 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /* vasprintf and asprintf with out-of-memory checking.
       2             :    Copyright (C) 1999, 2002-2004, 2006-2016 Free Software Foundation, Inc.
       3             : 
       4             :    This program is free software: you can redistribute it and/or modify
       5             :    it under the terms of the GNU General Public License as published by
       6             :    the Free Software Foundation; either version 3 of the License, or
       7             :    (at your option) any later version.
       8             : 
       9             :    This program is distributed in the hope that it will be useful,
      10             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :    GNU General Public License for more details.
      13             : 
      14             :    You should have received a copy of the GNU General Public License
      15             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      16             : 
      17             : #include <config.h>
      18             : 
      19             : /* Specification.  */
      20             : #include "xvasprintf.h"
      21             : 
      22             : #include <errno.h>
      23             : #include <limits.h>
      24             : #include <string.h>
      25             : #include <stdio.h>
      26             : 
      27             : #include "xalloc.h"
      28             : 
      29             : /* Checked size_t computations.  */
      30             : #include "xsize.h"
      31             : 
      32             : static char *
      33           0 : xstrcat (size_t argcount, va_list args)
      34             : {
      35             :   char *result;
      36             :   va_list ap;
      37             :   size_t totalsize;
      38             :   size_t i;
      39             :   char *p;
      40             : 
      41             :   /* Determine the total size.  */
      42           0 :   totalsize = 0;
      43           0 :   va_copy (ap, args);
      44           0 :   for (i = argcount; i > 0; i--)
      45             :     {
      46           0 :       const char *next = va_arg (ap, const char *);
      47           0 :       totalsize = xsum (totalsize, strlen (next));
      48             :     }
      49           0 :   va_end (ap);
      50             : 
      51             :   /* Test for overflow in the summing pass above or in (totalsize + 1) below.
      52             :      Also, don't return a string longer than INT_MAX, for consistency with
      53             :      vasprintf().  */
      54           0 :   if (totalsize == SIZE_MAX || totalsize > INT_MAX)
      55             :     {
      56           0 :       errno = EOVERFLOW;
      57           0 :       return NULL;
      58             :     }
      59             : 
      60             :   /* Allocate and fill the result string.  */
      61           0 :   result = XNMALLOC (totalsize + 1, char);
      62           0 :   p = result;
      63           0 :   for (i = argcount; i > 0; i--)
      64             :     {
      65           0 :       const char *next = va_arg (args, const char *);
      66           0 :       size_t len = strlen (next);
      67           0 :       memcpy (p, next, len);
      68           0 :       p += len;
      69             :     }
      70           0 :   *p = '\0';
      71             : 
      72           0 :   return result;
      73             : }
      74             : 
      75             : char *
      76           1 : xvasprintf (const char *format, va_list args)
      77             : {
      78             :   char *result;
      79             : 
      80             :   /* Recognize the special case format = "%s...%s".  It is a frequently used
      81             :      idiom for string concatenation and needs to be fast.  We don't want to
      82             :      have a separate function xstrcat() for this purpose.  */
      83             :   {
      84           1 :     size_t argcount = 0;
      85             :     const char *f;
      86             : 
      87           1 :     for (f = format;;)
      88             :       {
      89           2 :         if (*f == '\0')
      90             :           /* Recognized the special case of string concatenation.  */
      91           0 :           return xstrcat (argcount, args);
      92           2 :         if (*f != '%')
      93           1 :           break;
      94           1 :         f++;
      95           1 :         if (*f != 's')
      96           0 :           break;
      97           1 :         f++;
      98           1 :         argcount++;
      99           1 :       }
     100             :   }
     101             : 
     102           1 :   if (vasprintf (&result, format, args) < 0)
     103             :     {
     104           0 :       if (errno == ENOMEM)
     105           0 :         xalloc_die ();
     106           0 :       return NULL;
     107             :     }
     108             : 
     109           1 :   return result;
     110             : }

Generated by: LCOV version 1.10