| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/xvasprintf.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /* vasprintf and asprintf with out-of-memory checking. | - | ||||||||||||
| 2 | Copyright (C) 1999, 2002-2004, 2006-2018 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 <https://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 | 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 | totalsize = 0; | - | ||||||||||||
| 43 | va_copy (ap, args); | - | ||||||||||||
| 44 | for (i = argcount; i > 0; i--)
| 216-432 | ||||||||||||
| 45 | { | - | ||||||||||||
| 46 | const char *next = va_arg (ap, const char *); | - | ||||||||||||
| 47 | totalsize = xsum (totalsize, strlen (next)); | - | ||||||||||||
| 48 | } executed 432 times by 1 test: end of blockExecuted by:
| 432 | ||||||||||||
| 49 | 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 | if (totalsize == SIZE_MAX || totalsize > INT_MAX)
| 0-216 | ||||||||||||
| 55 | { | - | ||||||||||||
| 56 | errno = EOVERFLOW; | - | ||||||||||||
| 57 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
| 58 | } | - | ||||||||||||
| 59 | - | |||||||||||||
| 60 | /* Allocate and fill the result string. */ | - | ||||||||||||
| 61 | result = XNMALLOC (totalsize + 1, char); | - | ||||||||||||
| 62 | p = result; | - | ||||||||||||
| 63 | for (i = argcount; i > 0; i--)
| 216-432 | ||||||||||||
| 64 | { | - | ||||||||||||
| 65 | const char *next = va_arg (args, const char *); | - | ||||||||||||
| 66 | size_t len = strlen (next); | - | ||||||||||||
| 67 | memcpy (p, next, len); | - | ||||||||||||
| 68 | p += len; | - | ||||||||||||
| 69 | } executed 432 times by 1 test: end of blockExecuted by:
| 432 | ||||||||||||
| 70 | *p = '\0'; | - | ||||||||||||
| 71 | - | |||||||||||||
| 72 | return result; executed 216 times by 1 test: return result;Executed by:
| 216 | ||||||||||||
| 73 | } | - | ||||||||||||
| 74 | - | |||||||||||||
| 75 | char * | - | ||||||||||||
| 76 | 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 | size_t argcount = 0; | - | ||||||||||||
| 85 | const char *f; | - | ||||||||||||
| 86 | - | |||||||||||||
| 87 | for (f = format;;) | - | ||||||||||||
| 88 | { | - | ||||||||||||
| 89 | if (*f == '\0')
| 216-463 | ||||||||||||
| 90 | /* Recognized the special case of string concatenation. */ | - | ||||||||||||
| 91 | return xstrcat (argcount, args); executed 216 times by 1 test: return xstrcat (argcount, args);Executed by:
| 216 | ||||||||||||
| 92 | if (*f != '%')
| 22-441 | ||||||||||||
| 93 | break; executed 22 times by 2 tests: break;Executed by:
| 22 | ||||||||||||
| 94 | f++; | - | ||||||||||||
| 95 | if (*f != 's')
| 0-441 | ||||||||||||
| 96 | break; never executed: break; | 0 | ||||||||||||
| 97 | f++; | - | ||||||||||||
| 98 | argcount++; | - | ||||||||||||
| 99 | } executed 441 times by 2 tests: end of blockExecuted by:
| 441 | ||||||||||||
| 100 | } | - | ||||||||||||
| 101 | - | |||||||||||||
| 102 | if (vasprintf (&result, format, args) < 0)
| 0-22 | ||||||||||||
| 103 | { | - | ||||||||||||
| 104 | if (errno == ENOMEM)
| 0 | ||||||||||||
| 105 | xalloc_die (); never executed: xalloc_die (); | 0 | ||||||||||||
| 106 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
| 107 | } | - | ||||||||||||
| 108 | - | |||||||||||||
| 109 | return result; executed 22 times by 2 tests: return result;Executed by:
| 22 | ||||||||||||
| 110 | } | - | ||||||||||||
| Source code | Switch to Preprocessed file |