• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Broadcom Secure Standard Library.
3  *
4  * Copyright (C) 1999-2019, Broadcom.
5  *
6  *      Unless you and Broadcom execute a separate written software license
7  * agreement governing use of this software, this software is licensed to you
8  * under the terms of the GNU General Public License version 2 (the "GPL"),
9  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10  * following added to such license:
11  *
12  *      As a special exception, the copyright holders of this software give you
13  * permission to link this software with independent modules, and to copy and
14  * distribute the resulting executable under terms of your choice, provided that
15  * you also meet, for each linked independent module, the terms and conditions
16  * of the license of that module.  An independent module is a module which is
17  * not derived from this software.  The special exception does not apply to any
18  * modifications of the software.
19  *
20  *      Notwithstanding the above, under no circumstances may you combine this
21  * software in any way with any other Broadcom software provided under a license
22  * other than the GPL, without Broadcom's express prior written consent.
23  *
24  *
25  * <<Broadcom-WL-IPTag/Open:>>
26  *
27  * $Id $
28  */
29 
30 #include <bcm_cfg.h>
31 #include <typedefs.h>
32 #include <bcmdefs.h>
33 #ifdef BCMDRIVER
34 #include <osl.h>
35 #else /* BCMDRIVER */
36 #include <stddef.h>
37 #include <string.h>
38 #endif /* else BCMDRIVER */
39 
40 #include <bcmstdlib_s.h>
41 #include <bcmutils.h>
42 
43 /*
44  * __SIZE_MAX__ value is depending on platform:
45  * Firmware Dongle: RAMSIZE (Dongle Specific Limit).
46  * LINUX NIC/Windows/MACOSX/Application: OS Native or
47  * 0xFFFFFFFFu if not defined.
48  */
49 #ifndef SIZE_MAX
50 #ifndef __SIZE_MAX__
51 #define __SIZE_MAX__ 0xFFFFFFFFu
52 #endif /* __SIZE_MAX__ */
53 #define SIZE_MAX __SIZE_MAX__
54 #endif /* SIZE_MAX */
55 #define RSIZE_MAX (SIZE_MAX >> 1u)
56 
57 /**
58  * strlcat_s - Concatenate a %NUL terminated string with a sized buffer
59  * @dest: Where to concatenate the string to
60  * @src: Where to copy the string from
61  * @size: size of destination buffer
62  * return: string length of created string (i.e. the initial length of dest plus
63  * the length of src) not including the NUL char, up until size
64  *
65  * Unlike strncat(), strlcat() take the full size of the buffer (not just the
66  * number of bytes to copy) and guarantee to NUL-terminate the result (even when
67  * there's nothing to concat). If the length of dest string concatinated with
68  * the src string >= size, truncation occurs.
69  *
70  * Compatible with *BSD: the result is always a valid NUL-terminated string that
71  * fits in the buffer (unless, of course, the buffer size is zero).
72  *
73  * If either src or dest is not NUL-terminated, dest[size-1] will be set to NUL.
74  * If size < strlen(dest) + strlen(src), dest[size-1] will be set to NUL.
75  * If size == 0, dest[0] will be set to NUL.
76  */
strlcat_s(char * dest,const char * src,size_t size)77 size_t strlcat_s(char *dest, const char *src, size_t size)
78 {
79     char *d = dest;
80     const char *s = src; /* point to the start of the src string */
81     size_t n = size;
82     size_t dlen;
83     size_t bytes_to_copy = 0;
84 
85     if (dest == NULL) {
86         return 0;
87     }
88 
89     /* set d to point to the end of dest string (up to size) */
90     while (n != 0 && *d != '\0') {
91         d++;
92         n--;
93     }
94     dlen = (size_t)(d - dest);
95 
96     if (s != NULL) {
97         size_t slen = 0;
98 
99         /* calculate src len in case it's not null-terminated */
100         n = size;
101         while (n-- != 0 && *(s + slen) != '\0') {
102             ++slen;
103         }
104 
105         n = size - dlen; /* maximum num of chars to copy */
106         if (n != 0) {
107             /* copy relevant chars (until end of src buf or given size is
108              * reached) */
109             bytes_to_copy = MIN(slen - (size_t)(s - src), n - 1);
110             (void)memcpy(d, s, bytes_to_copy);
111             d += bytes_to_copy;
112         }
113     }
114     if (n == 0 && dlen != 0) {
115         --d; /* nothing to copy, but NUL-terminate dest anyway */
116     }
117     *d = '\0'; /* NUL-terminate dest */
118 
119     return (dlen + bytes_to_copy);
120 }
121