Coverage Report

Created: 2026-03-31 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pistache/src/common/ps_strl.cc
Line
Count
Source
1
/*
2
 * SPDX-FileCopyrightText: 2024 Duncan Greatwood
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
5
 */
6
7
// Defines a ps_strlcpy and ps_strlcat for OS that do not have strlcpy/strlcat
8
// natively, including Windows and (some) Linux
9
10
#include <pistache/ps_strl.h>
11
12
/* ------------------------------------------------------------------------- */
13
14
#include <errno.h>
15
#include <string.h> // for memcpy
16
#include <cstring>
17
#include <algorithm> // for std::min
18
19
#if defined(_IS_WINDOWS) || defined(__linux__)
20
21
/* ------------------------------------------------------------------------- */
22
23
extern "C" size_t ps_strlcpy(char *dst, const char *src, size_t n)
24
0
{
25
0
    if ((!dst) || (!src) || (!n))
26
0
        return(0);
27
28
0
    if (n == 1)
29
0
    {
30
0
        dst[0] = 0;
31
0
        return(0);
32
0
    }
33
34
0
    size_t bytes_to_copy = (strlen(src)+1);
35
0
    if (bytes_to_copy > n)
36
0
    {
37
0
        bytes_to_copy = n-1;
38
39
0
        std::memcpy(dst, src, bytes_to_copy);
40
0
        dst[bytes_to_copy] = 0;
41
0
    }
42
0
    else
43
0
    {
44
0
        std::memcpy(dst, src, bytes_to_copy);
45
0
    }
46
47
0
    return(bytes_to_copy);
48
0
}
49
50
extern "C" size_t ps_strlcat(char *dst, const char *src, size_t n)
51
0
{
52
0
    if ((!dst) || (!src) || (n <= 1))
53
0
        return(0);
54
55
0
    const size_t dst_len= strlen(dst);
56
0
    if ((n+1) <= dst_len)
57
0
        return(dst_len); // no space to add onto dst
58
59
0
    const size_t len_added = ps_strlcpy(dst+dst_len, src, (n - dst_len));
60
0
    return(dst_len+len_added);
61
0
}
62
63
64
/* ------------------------------------------------------------------------- */
65
66
#endif // of #if defined(_IS_WINDOWS) || defined(__linux__)
67
68
/* ------------------------------------------------------------------------- */
69
70
71
/* ------------------------------------------------------------------------- */
72
73
// ps_strncpy_s returns 0 for success, -1 on failure with errno set. NB: This
74
// is different from C++ standard (Annex K) strncpy_s which returns an errno_t
75
// on failure; we diverge because errno_t is often not defined on non-Windows
76
// systems. If the copy would result in a truncation, errno is set to
77
// PS_ESTRUNCATE.
78
extern "C" int ps_strncpy_s(char *strDest, size_t numberOfElements,
79
                            const char *strSource, size_t count)
80
0
{
81
#ifdef _IS_WINDOWS
82
    errno_t win_strncpy_s_res = strncpy_s(strDest, numberOfElements,
83
                                          strSource, count);
84
    if (win_strncpy_s_res == 0)
85
        return(0); // success
86
87
    if (win_strncpy_s_res == STRUNCATE)
88
    {
89
        errno = PS_ESTRUNCATE;
90
        return(-1);
91
    }
92
93
    errno = win_strncpy_s_res;
94
    return(-1);
95
#else // i.e. NOT Windows
96
0
    if ((!strDest) || (!strSource))
97
0
    {
98
0
        errno = EINVAL;
99
0
        return(-1);
100
0
    }
101
102
0
    size_t non_null_bytes_to_copy = std::min(strlen(strSource), count);
103
0
    if (non_null_bytes_to_copy >= numberOfElements)
104
0
    {
105
0
        errno = PS_ESTRUNCATE;
106
0
        return(-1);
107
0
    }
108
109
0
    std::memcpy(strDest, strSource, non_null_bytes_to_copy);
110
0
    strDest[non_null_bytes_to_copy] = 0;
111
0
    return(0);
112
113
0
#endif // of #ifdef _IS_WINDOWS
114
0
}
115
116
117
118
119
120
/* ------------------------------------------------------------------------- */
121
122
123
124
/* ------------------------------------------------------------------------- */