1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci
16570af302Sopenharmony_ci#ifndef _STRING_H
17570af302Sopenharmony_ci#error "Never include this file directly; instead, include <string.h>"
18570af302Sopenharmony_ci#endif
19570af302Sopenharmony_ci
20570af302Sopenharmony_ci#include "fortify.h"
21570af302Sopenharmony_ci
22570af302Sopenharmony_ci#ifdef __cplusplus
23570af302Sopenharmony_ciextern "C" {
24570af302Sopenharmony_ci#endif
25570af302Sopenharmony_ci
26570af302Sopenharmony_civoid *__memchr_chk(const void* s, int c, size_t n, size_t actual_size);
27570af302Sopenharmony_civoid *__memrchr_chk(const void*, int, size_t, size_t);
28570af302Sopenharmony_cisize_t __strlcpy_chk(char*, const char*, size_t, size_t);
29570af302Sopenharmony_cisize_t __strlcat_chk(char*, const char*, size_t, size_t);
30570af302Sopenharmony_cichar *__strchr_chk(const char* p, int ch, size_t s_len);
31570af302Sopenharmony_cichar *__strrchr_chk(const char *p, int ch, size_t s_len);
32570af302Sopenharmony_cisize_t __strlen_chk(const char* s, size_t s_len);
33570af302Sopenharmony_ci
34570af302Sopenharmony_ci#ifdef __FORTIFY_COMPILATION
35570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
36570af302Sopenharmony_cichar *strcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src)
37570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
38570af302Sopenharmony_ci__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)),
39570af302Sopenharmony_ci    "'strcpy' " CALLED_WITH_STRING_BIGGER_BUFFER)
40570af302Sopenharmony_ci{
41570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
42570af302Sopenharmony_ci    return __builtin___strcpy_chk(dest, src, __DIAGNOSE_BOS(dest));
43570af302Sopenharmony_ci#else
44570af302Sopenharmony_ci    return __builtin_strcpy(dest, src);
45570af302Sopenharmony_ci#endif
46570af302Sopenharmony_ci}
47570af302Sopenharmony_ci
48570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
49570af302Sopenharmony_cichar *stpcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src)
50570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
51570af302Sopenharmony_ci__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)),
52570af302Sopenharmony_ci    "'stpcpy' " CALLED_WITH_STRING_BIGGER_BUFFER)
53570af302Sopenharmony_ci{
54570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
55570af302Sopenharmony_ci    return __builtin___stpcpy_chk(dest, src, __DIAGNOSE_BOS(dest));
56570af302Sopenharmony_ci#else
57570af302Sopenharmony_ci    return __builtin_stpcpy(dest, src);
58570af302Sopenharmony_ci#endif
59570af302Sopenharmony_ci}
60570af302Sopenharmony_ci
61570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
62570af302Sopenharmony_civoid *memmove(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE0, const void *src, size_t len)
63570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
64570af302Sopenharmony_ci{
65570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
66570af302Sopenharmony_ci    return __builtin___memmove_chk(dest, src, len, __DIAGNOSE_BOS(dest));
67570af302Sopenharmony_ci#else
68570af302Sopenharmony_ci    return __builtin_memmove(dest, src, len);
69570af302Sopenharmony_ci#endif
70570af302Sopenharmony_ci}
71570af302Sopenharmony_ci
72570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
73570af302Sopenharmony_civoid *mempcpy(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const void *src, size_t copy_amount)
74570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
75570af302Sopenharmony_ci__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS0(dest), copy_amount),
76570af302Sopenharmony_ci    "'mempcpy' " CALLED_WITH_STRING_BIGGER_BUFFER)
77570af302Sopenharmony_ci{
78570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
79570af302Sopenharmony_ci    return __builtin___mempcpy_chk(dest, src, copy_amount, __DIAGNOSE_BOS0(dest));
80570af302Sopenharmony_ci#else
81570af302Sopenharmony_ci    return __builtin_mempcpy(dest, src, copy_amount);
82570af302Sopenharmony_ci#endif
83570af302Sopenharmony_ci}
84570af302Sopenharmony_ci
85570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
86570af302Sopenharmony_cichar *strcat(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src)
87570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
88570af302Sopenharmony_ci__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)),
89570af302Sopenharmony_ci    "'strcat' " CALLED_WITH_STRING_BIGGER_BUFFER)
90570af302Sopenharmony_ci{
91570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
92570af302Sopenharmony_ci    return __builtin___strcat_chk(dest, src, __DIAGNOSE_BOS(dest));
93570af302Sopenharmony_ci#else
94570af302Sopenharmony_ci    return __builtin_strcat(dest, src);
95570af302Sopenharmony_ci#endif
96570af302Sopenharmony_ci}
97570af302Sopenharmony_ci
98570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
99570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
100570af302Sopenharmony_cichar *strncat(char* const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char* src, size_t n)
101570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
102570af302Sopenharmony_ci{
103570af302Sopenharmony_ci    return __builtin___strncat_chk(dest, src, n, __DIAGNOSE_BOS(dest));
104570af302Sopenharmony_ci}
105570af302Sopenharmony_ci#endif
106570af302Sopenharmony_ci
107570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
108570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
109570af302Sopenharmony_cichar *stpncpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE,
110570af302Sopenharmony_ci    const char *const src __DIAGNOSE_PASS_OBJECT_SIZE, size_t n)
111570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
112570af302Sopenharmony_ci{
113570af302Sopenharmony_ci    size_t bos_dest = __DIAGNOSE_BOS(dest);
114570af302Sopenharmony_ci    return __builtin___stpncpy_chk(dest, src, n, bos_dest);
115570af302Sopenharmony_ci}
116570af302Sopenharmony_ci#endif
117570af302Sopenharmony_ci
118570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
119570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
120570af302Sopenharmony_cichar *strncpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE,
121570af302Sopenharmony_ci    const char *const src __DIAGNOSE_PASS_OBJECT_SIZE, size_t n)
122570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
123570af302Sopenharmony_ci{
124570af302Sopenharmony_ci    size_t bos_dest = __DIAGNOSE_BOS(dest);
125570af302Sopenharmony_ci    return __builtin___strncpy_chk(dest, src, n, bos_dest);
126570af302Sopenharmony_ci}
127570af302Sopenharmony_ci#endif
128570af302Sopenharmony_ci
129570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
130570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
131570af302Sopenharmony_civoid *memcpy(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE0, const void *src, size_t copy_amount)
132570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
133570af302Sopenharmony_ci{
134570af302Sopenharmony_ci    return __builtin___memcpy_chk(dest, src, copy_amount, __DIAGNOSE_BOS0(dest));
135570af302Sopenharmony_ci}
136570af302Sopenharmony_ci#endif
137570af302Sopenharmony_ci
138570af302Sopenharmony_ci#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
139570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
140570af302Sopenharmony_cisize_t strlcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src, size_t size)
141570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
142570af302Sopenharmony_ci__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS(dest), size),
143570af302Sopenharmony_ci    "'strlcpy' called with size bigger than buffer")
144570af302Sopenharmony_ci{
145570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
146570af302Sopenharmony_ci    return __strlcpy_chk(dest, src, size, __DIAGNOSE_BOS(dest));
147570af302Sopenharmony_ci#else
148570af302Sopenharmony_ci    return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strlcpy)(dest, src, size);
149570af302Sopenharmony_ci#endif
150570af302Sopenharmony_ci}
151570af302Sopenharmony_ci
152570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
153570af302Sopenharmony_cisize_t strlcat(char* const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char* src, size_t size)
154570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
155570af302Sopenharmony_ci__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS(dest), size),
156570af302Sopenharmony_ci    "'strlcat' called with size bigger than buffer")
157570af302Sopenharmony_ci{
158570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
159570af302Sopenharmony_ci    return __strlcat_chk(dest, src, size, __DIAGNOSE_BOS(dest));
160570af302Sopenharmony_ci#else
161570af302Sopenharmony_ci    return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strlcat)(dest, src, size);
162570af302Sopenharmony_ci#endif
163570af302Sopenharmony_ci}
164570af302Sopenharmony_ci#endif // defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
165570af302Sopenharmony_ci
166570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
167570af302Sopenharmony_civoid *memset(void *const s __DIAGNOSE_PASS_OBJECT_SIZE0, int c, size_t n)
168570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
169570af302Sopenharmony_ci__DIAGNOSE_WARNING_IF(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?")
170570af302Sopenharmony_ci{
171570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
172570af302Sopenharmony_ci    return __builtin___memset_chk(s, c, n, __DIAGNOSE_BOS0(s));
173570af302Sopenharmony_ci#else
174570af302Sopenharmony_ci    return __builtin_memset(s, c, n);
175570af302Sopenharmony_ci#endif
176570af302Sopenharmony_ci}
177570af302Sopenharmony_ci
178570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
179570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
180570af302Sopenharmony_civoid *memchr(const void *const s __DIAGNOSE_PASS_OBJECT_SIZE, int c, size_t n)
181570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
182570af302Sopenharmony_ci{
183570af302Sopenharmony_ci    size_t bos = __DIAGNOSE_BOS(s);
184570af302Sopenharmony_ci    if (__DIAGNOSE_BOS_TRIVIALLY_GE(bos, n)) {
185570af302Sopenharmony_ci        return __builtin_memchr(s, c, n);
186570af302Sopenharmony_ci    }
187570af302Sopenharmony_ci    return __memchr_chk(s, c, n, bos);
188570af302Sopenharmony_ci}
189570af302Sopenharmony_ci#endif // memchr __FORTIFY_RUNTIME
190570af302Sopenharmony_ci
191570af302Sopenharmony_ciextern void* __memrchr_real(const void*, int, size_t) __DIAGNOSE_RENAME(memrchr);
192570af302Sopenharmony_ci
193570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
194570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
195570af302Sopenharmony_civoid *memrchr(const void *const __DIAGNOSE_PASS_OBJECT_SIZE s, int c, size_t n)
196570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
197570af302Sopenharmony_ci{
198570af302Sopenharmony_ci    size_t bos = __DIAGNOSE_BOS(s);
199570af302Sopenharmony_ci    if (__DIAGNOSE_BOS_TRIVIALLY_GE(bos, n)) {
200570af302Sopenharmony_ci        return __memrchr_real(s, c, n);
201570af302Sopenharmony_ci    }
202570af302Sopenharmony_ci    return __memrchr_chk(s, c, n, bos);
203570af302Sopenharmony_ci}
204570af302Sopenharmony_ci#endif
205570af302Sopenharmony_ci
206570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
207570af302Sopenharmony_cichar* strchr(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE, int c)
208570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
209570af302Sopenharmony_ci{
210570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
211570af302Sopenharmony_ci    size_t bos = __DIAGNOSE_BOS(s);
212570af302Sopenharmony_ci
213570af302Sopenharmony_ci    if (bos != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE) {
214570af302Sopenharmony_ci        return __strchr_chk(s, c, bos);
215570af302Sopenharmony_ci    }
216570af302Sopenharmony_ci#endif
217570af302Sopenharmony_ci    return __builtin_strchr(s, c);
218570af302Sopenharmony_ci}
219570af302Sopenharmony_ci
220570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
221570af302Sopenharmony_cichar* strrchr(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE, int c)
222570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
223570af302Sopenharmony_ci{
224570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
225570af302Sopenharmony_ci    size_t bos = __DIAGNOSE_BOS(s);
226570af302Sopenharmony_ci
227570af302Sopenharmony_ci    if (bos != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE) {
228570af302Sopenharmony_ci        return __strrchr_chk(s, c, bos);
229570af302Sopenharmony_ci    }
230570af302Sopenharmony_ci#endif
231570af302Sopenharmony_ci    return __builtin_strrchr(s, c);
232570af302Sopenharmony_ci}
233570af302Sopenharmony_ci
234570af302Sopenharmony_ci#ifdef __FORTIFY_RUNTIME
235570af302Sopenharmony_ci__DIAGNOSE_FORTIFY_INLINE
236570af302Sopenharmony_cisize_t strlen(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE0)
237570af302Sopenharmony_ci__DIAGNOSE_OVERLOAD
238570af302Sopenharmony_ci{
239570af302Sopenharmony_ci    return __strlen_chk(s, __DIAGNOSE_BOS0(s));
240570af302Sopenharmony_ci}
241570af302Sopenharmony_ci#endif
242570af302Sopenharmony_ci
243570af302Sopenharmony_ci#endif // __FORTIFY_COMPILATION
244570af302Sopenharmony_ci#ifdef __cplusplus
245570af302Sopenharmony_ci}
246570af302Sopenharmony_ci#endif