blob: 0e205d30a278a8121d1b62cc5807f1a44b8b39b8 [file] [log] [blame]
George Burgess IVb97049c2017-07-24 15:05:05 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#ifndef _STRING_H
30#error "Never include this file directly; instead, include <string.h>"
31#endif
32
Elliott Hughes3f66e742017-08-01 13:24:40 -070033void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
34void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
35char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
36char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
37size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
38size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
George Burgess IVb97049c2017-07-24 15:05:05 -070039
George Burgess IVb97049c2017-07-24 15:05:05 -070040#if defined(__BIONIC_FORTIFY)
Elliott Hughesdf9a4892017-08-23 14:34:03 -070041extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
42
George Burgess IVb97049c2017-07-24 15:05:05 -070043#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
44__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070045void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
46 __overloadable
George Burgess IV5273dc52019-05-09 13:46:57 -070047 __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
George Burgess IVb6300462017-07-31 21:29:42 -070048 "'memcpy' called with size bigger than buffer") {
George Burgess IV5da5dd52019-05-09 14:32:43 -070049 size_t bos_dst = __bos0(dst);
50 if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
51 return __builtin_memcpy(dst, src, copy_amount);
52 }
53 return __builtin___memcpy_chk(dst, src, copy_amount, bos_dst);
George Burgess IVb97049c2017-07-24 15:05:05 -070054}
55
56__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070057void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
58 __overloadable
George Burgess IV5273dc52019-05-09 13:46:57 -070059 __clang_error_if(__bos_unevaluated_lt(__bos0(dst), len),
George Burgess IVb6300462017-07-31 21:29:42 -070060 "'memmove' called with size bigger than buffer") {
George Burgess IV5da5dd52019-05-09 14:32:43 -070061 size_t bos_dst = __bos0(dst);
62 if (__bos_trivially_not_lt(bos_dst, len)) {
63 return __builtin_memmove(dst, src, len);
64 }
65 return __builtin___memmove_chk(dst, src, len, bos_dst);
George Burgess IVb97049c2017-07-24 15:05:05 -070066}
67#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
68
69#if __ANDROID_API__ >= __ANDROID_API_L__
70__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070071char* stpcpy(char* const dst __pass_object_size, const char* src)
72 __overloadable
George Burgess IVc03d5962019-05-23 15:22:01 -070073 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
George Burgess IVb6300462017-07-31 21:29:42 -070074 "'stpcpy' called with string bigger than buffer") {
George Burgess IV5da5dd52019-05-09 14:32:43 -070075 size_t bos_dst = __bos(dst);
George Burgess IVc03d5962019-05-23 15:22:01 -070076 if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
George Burgess IV5da5dd52019-05-09 14:32:43 -070077 return __builtin_stpcpy(dst, src);
78 }
79 return __builtin___stpcpy_chk(dst, src, bos_dst);
George Burgess IVb97049c2017-07-24 15:05:05 -070080}
81#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
82
83#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
84__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070085char* strcpy(char* const dst __pass_object_size, const char* src)
86 __overloadable
George Burgess IVc03d5962019-05-23 15:22:01 -070087 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
George Burgess IVb6300462017-07-31 21:29:42 -070088 "'strcpy' called with string bigger than buffer") {
George Burgess IV5da5dd52019-05-09 14:32:43 -070089 size_t bos_dst = __bos(dst);
George Burgess IVc03d5962019-05-23 15:22:01 -070090 if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
George Burgess IV5da5dd52019-05-09 14:32:43 -070091 return __builtin_strcpy(dst, src);
92 }
93 return __builtin___strcpy_chk(dst, src, bos_dst);
George Burgess IVb97049c2017-07-24 15:05:05 -070094}
95
96__BIONIC_FORTIFY_INLINE
George Burgess IV77f99aa2019-06-06 14:14:52 -070097char* strcat(char* const dst __pass_object_size, const char* src)
98 __overloadable
99 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
100 "'strcat' called with string bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -0700101 return __builtin___strcat_chk(dst, src, __bos(dst));
102}
103
104__BIONIC_FORTIFY_INLINE
George Burgess IV77f99aa2019-06-06 14:14:52 -0700105char* strncat(char* const dst __pass_object_size, const char* src, size_t n)
106 __overloadable
107 __clang_error_if(__bos_unevaluated_lt(__bos(dst), n),
108 "'strncat' called with size bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -0700109 return __builtin___strncat_chk(dst, src, n, __bos(dst));
110}
111
112__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700113void* memset(void* const s __pass_object_size0, int c, size_t n)
114 __overloadable
George Burgess IV5273dc52019-05-09 13:46:57 -0700115 __clang_error_if(__bos_unevaluated_lt(__bos0(s), n),
George Burgess IVb6300462017-07-31 21:29:42 -0700116 "'memset' called with size bigger than buffer")
117 /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
118 __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
George Burgess IV5da5dd52019-05-09 14:32:43 -0700119 size_t bos = __bos0(s);
120 if (__bos_trivially_not_lt(bos, n)) {
121 return __builtin_memset(s, c, n);
122 }
123 return __builtin___memset_chk(s, c, n, bos);
George Burgess IVb97049c2017-07-24 15:05:05 -0700124}
125#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
126
George Burgess IVb97049c2017-07-24 15:05:05 -0700127#if __ANDROID_API__ >= __ANDROID_API_M__
128__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700129void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700130 size_t bos = __bos(s);
131
George Burgess IVc03d5962019-05-23 15:22:01 -0700132 if (__bos_trivially_ge(bos, n)) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700133 return __builtin_memchr(s, c, n);
134 }
135
136 return __memchr_chk(s, c, n, bos);
137}
138
139__BIONIC_FORTIFY_INLINE
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700140void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700141 size_t bos = __bos(s);
142
George Burgess IVc03d5962019-05-23 15:22:01 -0700143 if (__bos_trivially_ge(bos, n)) {
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700144 return __memrchr_real(s, c, n);
George Burgess IVb97049c2017-07-24 15:05:05 -0700145 }
146
147 return __memrchr_chk(s, c, n, bos);
148}
149#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
150
151#if __ANDROID_API__ >= __ANDROID_API_L__
152__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700153char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IV77f99aa2019-06-06 14:14:52 -0700154 __overloadable
155 __clang_error_if(__bos_unevaluated_lt(__bos(dst), n),
156 "'stpncpy' called with size bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -0700157 size_t bos_dst = __bos(dst);
158 size_t bos_src = __bos(src);
159
160 /* Ignore dst size checks; they're handled in strncpy_chk */
161 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
162 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
163 }
164
165 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
166}
167
168__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700169char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IV77f99aa2019-06-06 14:14:52 -0700170 __overloadable
171 __clang_error_if(__bos_unevaluated_lt(__bos(dst), n),
172 "'strncpy' called with size bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -0700173 size_t bos_dst = __bos(dst);
174 size_t bos_src = __bos(src);
175
176 /* Ignore dst size checks; they're handled in strncpy_chk */
177 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
178 return __builtin___strncpy_chk(dst, src, n, bos_dst);
179 }
180
181 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
182}
183#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
184
185#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
186__BIONIC_FORTIFY_INLINE
George Burgess IV77f99aa2019-06-06 14:14:52 -0700187size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size)
188 __overloadable
189 __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
190 "'strlcpy' called with size bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -0700191 size_t bos = __bos(dst);
192
193 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
194 return __call_bypassing_fortify(strlcpy)(dst, src, size);
195 }
196
197 return __strlcpy_chk(dst, src, size, bos);
198}
199
200__BIONIC_FORTIFY_INLINE
George Burgess IV77f99aa2019-06-06 14:14:52 -0700201size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size)
202 __overloadable
203 __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
204 "'strlcat' called with size bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -0700205 size_t bos = __bos(dst);
206
207 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
208 return __call_bypassing_fortify(strlcat)(dst, src, size);
209 }
210
211 return __strlcat_chk(dst, src, size, bos);
212}
213
George Burgess IVb97049c2017-07-24 15:05:05 -0700214__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700215size_t strlen(const char* const s __pass_object_size0) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700216 size_t bos = __bos0(s);
217
George Burgess IVa1a09b22019-05-13 17:16:20 -0700218 if (__bos_trivially_gt(bos, __builtin_strlen(s))) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700219 return __builtin_strlen(s);
220 }
221
George Burgess IVb97049c2017-07-24 15:05:05 -0700222 return __strlen_chk(s, bos);
223}
224#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
225
226#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
227__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700228char* strchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700229 size_t bos = __bos(s);
230
231 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
232 return __builtin_strchr(s, c);
233 }
234
235 return __strchr_chk(s, c, bos);
236}
237
238__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700239char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700240 size_t bos = __bos(s);
241
242 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
243 return __builtin_strrchr(s, c);
244 }
245
246 return __strrchr_chk(s, c, bos);
247}
248#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
249
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700250#if __ANDROID_API__ >= __ANDROID_API_M__
251#if defined(__cplusplus)
252extern "C++" {
253__BIONIC_FORTIFY_INLINE
254void* memrchr(void* const __pass_object_size s, int c, size_t n) {
255 return __memrchr_fortify(s, c, n);
256}
257
258__BIONIC_FORTIFY_INLINE
259const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
260 return __memrchr_fortify(s, c, n);
261}
262}
263#else
264__BIONIC_FORTIFY_INLINE
265void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
266 return __memrchr_fortify(s, c, n);
267}
268#endif
269#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
270
George Burgess IVb97049c2017-07-24 15:05:05 -0700271#endif /* defined(__BIONIC_FORTIFY) */