Coverage Report

Created: 2025-12-11 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/systemd/src/basic/strxcpyx.c
Line
Count
Source
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
/*
4
 * Concatenates/copies strings. In any case, terminates in all cases
5
 * with '\0' and moves the @dest pointer forward to the added '\0'.
6
 * Returns the remaining size, and 0 if the string was truncated.
7
 *
8
 * Due to the intended usage, these helpers silently noop invocations
9
 * having zero size.  This is technically an exception to the above
10
 * statement "terminates in all cases".  It's unexpected for such calls to
11
 * occur outside of a loop where this is the preferred behavior.
12
 */
13
14
#include <stdio.h>
15
#include <string.h>
16
17
#include "strxcpyx.h"
18
19
1.83k
size_t strnpcpy_full(char **dest, size_t size, const char *src, size_t len, bool *ret_truncated) {
20
1.83k
        bool truncated = false;
21
22
1.83k
        assert(dest);
23
1.83k
        assert(src);
24
25
1.83k
        if (size == 0) {
26
0
                if (ret_truncated)
27
0
                        *ret_truncated = len > 0;
28
0
                return 0;
29
0
        }
30
31
1.83k
        if (len >= size) {
32
0
                if (size > 1)
33
0
                        *dest = mempcpy(*dest, src, size-1);
34
0
                size = 0;
35
0
                truncated = true;
36
1.83k
        } else if (len > 0) {
37
1.83k
                *dest = mempcpy(*dest, src, len);
38
1.83k
                size -= len;
39
1.83k
        }
40
41
1.83k
        if (ret_truncated)
42
0
                *ret_truncated = truncated;
43
44
1.83k
        (*dest)[0] = '\0';
45
1.83k
        return size;
46
1.83k
}
47
48
0
size_t strpcpy_full(char **dest, size_t size, const char *src, bool *ret_truncated) {
49
0
        assert(dest);
50
0
        assert(src);
51
52
0
        return strnpcpy_full(dest, size, src, strlen(src), ret_truncated);
53
0
}
54
55
0
size_t strpcpyf_full(char **dest, size_t size, bool *ret_truncated, const char *src, ...) {
56
0
        bool truncated = false;
57
0
        va_list va;
58
0
        int i;
59
60
0
        assert(dest);
61
0
        assert(src);
62
63
0
        va_start(va, src);
64
0
        i = vsnprintf(*dest, size, src, va);
65
0
        va_end(va);
66
67
0
        if (i < (int) size) {
68
0
                *dest += i;
69
0
                size -= i;
70
0
        } else {
71
0
                size = 0;
72
0
                truncated = i > 0;
73
0
        }
74
75
0
        if (ret_truncated)
76
0
                *ret_truncated = truncated;
77
78
0
        return size;
79
0
}
80
81
0
size_t strpcpyl_full(char **dest, size_t size, bool *ret_truncated, const char *src, ...) {
82
0
        bool truncated = false;
83
0
        va_list va;
84
85
0
        assert(dest);
86
0
        assert(src);
87
88
0
        va_start(va, src);
89
0
        do {
90
0
                bool t;
91
92
0
                size = strpcpy_full(dest, size, src, &t);
93
0
                truncated = truncated || t;
94
0
                src = va_arg(va, char *);
95
0
        } while (src);
96
0
        va_end(va);
97
98
0
        if (ret_truncated)
99
0
                *ret_truncated = truncated;
100
0
        return size;
101
0
}
102
103
1.83k
size_t strnscpy_full(char *dest, size_t size, const char *src, size_t len, bool *ret_truncated) {
104
1.83k
        char *s;
105
106
1.83k
        assert(dest);
107
1.83k
        assert(src);
108
109
1.83k
        s = dest;
110
1.83k
        return strnpcpy_full(&s, size, src, len, ret_truncated);
111
1.83k
}
112
113
0
size_t strscpy_full(char *dest, size_t size, const char *src, bool *ret_truncated) {
114
0
        assert(dest);
115
0
        assert(src);
116
117
0
        return strnscpy_full(dest, size, src, strlen(src), ret_truncated);
118
0
}
119
120
0
size_t strscpyl_full(char *dest, size_t size, bool *ret_truncated, const char *src, ...) {
121
0
        bool truncated = false;
122
0
        va_list va;
123
0
        char *s;
124
125
0
        assert(dest);
126
0
        assert(src);
127
128
0
        va_start(va, src);
129
0
        s = dest;
130
0
        do {
131
0
                bool t;
132
133
0
                size = strpcpy_full(&s, size, src, &t);
134
0
                truncated = truncated || t;
135
0
                src = va_arg(va, char *);
136
0
        } while (src);
137
0
        va_end(va);
138
139
0
        if (ret_truncated)
140
0
                *ret_truncated = truncated;
141
142
0
        return size;
143
0
}