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 block Executed 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 block Executed 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 block Executed 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 |