1 /*
2 * Copyright (C) 2008 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 #define _STRING_H
31
32 #include <sys/cdefs.h>
33 #include <stddef.h>
34 #include <xlocale.h>
35
36 #include <bits/strcasecmp.h>
37
38 __BEGIN_DECLS
39
40 #if defined(__clang__)
41 #pragma clang diagnostic push
42 #pragma clang diagnostic ignored "-Wnullability-completeness"
43 #endif
44
45 #if defined(__USE_BSD)
46 #include <strings.h>
47 #endif
48
49 void* memccpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, int, size_t);
50 void* memchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable
51 __RENAME_CLANG(memchr);
52 void* memrchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable
53 __RENAME_CLANG(memrchr);
54 int memcmp(const void* _Nonnull, const void* _Nonnull, size_t) __attribute_pure__;
55 void* memcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t)
56 __overloadable __RENAME_CLANG(memcpy);
57 #if defined(__USE_GNU)
58 void* mempcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t) __INTRODUCED_IN(23);
59 #endif
60 void* memmove(void* _Nonnull, const void* _Nonnull, size_t) __overloadable
61 __RENAME_CLANG(memmove);
62 void* memset(void* _Nonnull, int, size_t) __overloadable __RENAME_CLANG(memset);
63 void* memmem(const void* _Nonnull, size_t, const void* _Nonnull, size_t) __attribute_pure__;
64
65 char* strchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
66 __RENAME_CLANG(strchr);
67 char* __strchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
68 #if defined(__USE_GNU)
69 #if defined(__cplusplus)
70 extern "C++" char* strchrnul(char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__;
71 extern "C++" const char* strchrnul(const char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__;
72 #else
73 char* strchrnul(const char* _Nonnull, int) __attribute_pure__ __INTRODUCED_IN(24);
74 #endif
75 #endif
76
77 char* strrchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
78 __RENAME_CLANG(strrchr);
79 char* __strrchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
80
81 size_t strlen(const char* _Nonnull) __attribute_pure__ __overloadable
82 __RENAME_CLANG(strlen);
83 size_t __strlen_chk(const char* _Nonnull, size_t) __INTRODUCED_IN(17);
84
85 int strcmp(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
86 char* stpcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
87 __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21);
88 char* strcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
89 __overloadable __RENAME_CLANG(strcpy);
90 char* strcat(char* _Nonnull __restrict, const char* _Nonnull __restrict)
91 __overloadable __RENAME_CLANG(strcat);
92 char* strdup(const char* _Nonnull);
93
94 char* strstr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
95 char* strcasestr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
96 char* strtok(char* __restrict, const char* _Nonnull __restrict);
97 char* strtok_r(char* __restrict, const char* _Nonnull __restrict, char** _Nonnull __restrict);
98
99 char* strerror(int);
100 char* strerror_l(int, locale_t) __INTRODUCED_IN(23);
101 #if defined(__USE_GNU) && __ANDROID_API__ >= 23
102 char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r) __INTRODUCED_IN(23);
103 #else /* POSIX */
104 int strerror_r(int, char*, size_t);
105 #endif
106
107 size_t strnlen(const char* _Nonnull, size_t) __attribute_pure__;
108 char* strncat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
109 __overloadable __RENAME_CLANG(strncat);
110 char* strndup(const char* _Nonnull, size_t);
111 int strncmp(const char* _Nonnull, const char* _Nonnull, size_t) __attribute_pure__;
112 char* stpncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
113 __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21);
114 char* strncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
115 __overloadable __RENAME_CLANG(strncpy);
116
117 size_t strlcat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
118 __overloadable __RENAME_CLANG(strlcat);
119 size_t strlcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
120 __overloadable __RENAME_CLANG(strlcpy);
121
122 size_t strcspn(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
123 char* strpbrk(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
124 char* strsep(char** _Nonnull __restrict, const char* _Nonnull __restrict);
125 size_t strspn(const char* _Nonnull, const char* _Nonnull);
126
127 char* strsignal(int);
128
129 int strcoll(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
130 size_t strxfrm(char* __restrict, const char* _Nonnull __restrict, size_t);
131
132 #if __ANDROID_API__ >= __ANDROID_API_L__
133 int strcoll_l(const char* _Nonnull, const char* _Nonnull, locale_t) __attribute_pure__ __INTRODUCED_IN(21);
134 size_t strxfrm_l(char* __restrict, const char* _Nonnull __restrict, size_t, locale_t) __INTRODUCED_IN(21);
135 #else
136 // Implemented as static inlines before 21.
137 #endif
138
139 #if defined(__USE_GNU) && !defined(basename)
140 /*
141 * glibc has a basename in <string.h> that's different to the POSIX one in <libgen.h>.
142 * It doesn't modify its argument, and in C++ it's const-correct.
143 */
144 #if defined(__cplusplus)
145 extern "C++" char* basename(char* _Nonnull) __RENAME(__gnu_basename);
146 extern "C++" const char* basename(const char* _Nonnull) __RENAME(__gnu_basename);
147 #else
148 char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
149 #endif
150 #endif
151
152 void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
153 void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
154 char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
155 __INTRODUCED_IN(21);
156 char* __strncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
157 __INTRODUCED_IN(21);
158 size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
159 size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
160
161 /* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we
162 * have the definition out here.
163 */
164 struct __bionic_zero_size_is_okay_t {};
165
166 #if defined(__BIONIC_FORTIFY)
167 // These can share their implementation between gcc and clang with minimal
168 // trickery...
169 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
170 __BIONIC_FORTIFY_INLINE
memcpy(void * _Nonnull __restrict const dst __pass_object_size0,const void * _Nonnull __restrict src,size_t copy_amount)171 void* memcpy(void* _Nonnull __restrict const dst __pass_object_size0,
172 const void* _Nonnull __restrict src, size_t copy_amount) __overloadable {
173 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
174 }
175
176 __BIONIC_FORTIFY_INLINE
memmove(void * const _Nonnull dst __pass_object_size0,const void * _Nonnull src,size_t len)177 void* memmove(void* const _Nonnull dst __pass_object_size0,
178 const void* _Nonnull src, size_t len) __overloadable {
179 return __builtin___memmove_chk(dst, src, len, __bos0(dst));
180 }
181 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
182
183 #if __ANDROID_API__ >= __ANDROID_API_L__
184 __BIONIC_FORTIFY_INLINE
stpcpy(char * _Nonnull __restrict const dst __pass_object_size,const char * _Nonnull __restrict src)185 char* stpcpy(char* _Nonnull __restrict const dst __pass_object_size,
186 const char* _Nonnull __restrict src) __overloadable {
187 return __builtin___stpcpy_chk(dst, src, __bos(dst));
188 }
189 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
190
191 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
192 __BIONIC_FORTIFY_INLINE
strcpy(char * _Nonnull __restrict const dst __pass_object_size,const char * _Nonnull __restrict src)193 char* strcpy(char* _Nonnull __restrict const dst __pass_object_size,
194 const char* _Nonnull __restrict src) __overloadable {
195 return __builtin___strcpy_chk(dst, src, __bos(dst));
196 }
197
198 __BIONIC_FORTIFY_INLINE
strcat(char * _Nonnull __restrict const dst __pass_object_size,const char * _Nonnull __restrict src)199 char* strcat(char* _Nonnull __restrict const dst __pass_object_size,
200 const char* _Nonnull __restrict src) __overloadable {
201 return __builtin___strcat_chk(dst, src, __bos(dst));
202 }
203
204 __BIONIC_FORTIFY_INLINE
strncat(char * const _Nonnull __restrict dst __pass_object_size,const char * _Nonnull __restrict src,size_t n)205 char* strncat(char* const _Nonnull __restrict dst __pass_object_size,
206 const char* _Nonnull __restrict src, size_t n) __overloadable {
207 return __builtin___strncat_chk(dst, src, n, __bos(dst));
208 }
209
210 __BIONIC_FORTIFY_INLINE
memset(void * const _Nonnull s __pass_object_size0,int c,size_t n)211 void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n)
212 __overloadable {
213 return __builtin___memset_chk(s, c, n, __bos0(s));
214 }
215 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
216
217
218 #if defined(__clang__)
219
220 #define __error_if_overflows_dst(name, dst, n, what) \
221 __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
222 __bos0(dst) < (n), "selected when the buffer is too small") \
223 __errorattr(#name " called with " what " bigger than buffer")
224
225 /*
226 * N.B. _Nonnull isn't necessary on params, since these functions just emit
227 * errors.
228 */
229 __BIONIC_ERROR_FUNCTION_VISIBILITY
230 void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
231 __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
232
233 __BIONIC_ERROR_FUNCTION_VISIBILITY
234 void* memmove(void *dst, const void* src, size_t len) __overloadable
235 __error_if_overflows_dst(memmove, dst, len, "size");
236
237 __BIONIC_ERROR_FUNCTION_VISIBILITY
238 void* memset(void* s, int c, size_t n) __overloadable
239 __error_if_overflows_dst(memset, s, n, "size");
240
241 __BIONIC_ERROR_FUNCTION_VISIBILITY
242 char* stpcpy(char* dst, const char* src) __overloadable
243 __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
244
245 __BIONIC_ERROR_FUNCTION_VISIBILITY
246 char* strcpy(char* dst, const char* src) __overloadable
247 __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
248
249 #if __ANDROID_API__ >= __ANDROID_API_M__
250 __BIONIC_FORTIFY_INLINE
memchr(const void * const _Nonnull s __pass_object_size,int c,size_t n)251 void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
252 __overloadable {
253 size_t bos = __bos(s);
254
255 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
256 return __builtin_memchr(s, c, n);
257 }
258
259 return __memchr_chk(s, c, n, bos);
260 }
261
262 __BIONIC_FORTIFY_INLINE
memrchr(const void * const _Nonnull s __pass_object_size,int c,size_t n)263 void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
264 __overloadable {
265 size_t bos = __bos(s);
266
267 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
268 return __call_bypassing_fortify(memrchr)(s, c, n);
269 }
270
271 return __memrchr_chk(s, c, n, bos);
272 }
273 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
274
275 #if __ANDROID_API__ >= __ANDROID_API_L__
276 __BIONIC_FORTIFY_INLINE
stpncpy(char * __restrict const _Nonnull dst __pass_object_size,const char * __restrict const _Nonnull src __pass_object_size,size_t n)277 char* stpncpy(char* __restrict const _Nonnull dst __pass_object_size,
278 const char* __restrict const _Nonnull src __pass_object_size,
279 size_t n) __overloadable {
280 size_t bos_dst = __bos(dst);
281 size_t bos_src = __bos(src);
282
283 /* Ignore dst size checks; they're handled in strncpy_chk */
284 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
285 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
286 }
287
288 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
289 }
290
291 __BIONIC_FORTIFY_INLINE
strncpy(char * __restrict const _Nonnull dst __pass_object_size,const char * __restrict const _Nonnull src __pass_object_size,size_t n)292 char* strncpy(char* __restrict const _Nonnull dst __pass_object_size,
293 const char* __restrict const _Nonnull src __pass_object_size,
294 size_t n) __overloadable {
295 size_t bos_dst = __bos(dst);
296 size_t bos_src = __bos(src);
297
298 /* Ignore dst size checks; they're handled in strncpy_chk */
299 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
300 return __builtin___strncpy_chk(dst, src, n, bos_dst);
301 }
302
303 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
304 }
305 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
306
307 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
308 __BIONIC_FORTIFY_INLINE
strlcpy(char * const _Nonnull __restrict dst __pass_object_size,const char * _Nonnull __restrict src,size_t size)309 size_t strlcpy(char* const _Nonnull __restrict dst __pass_object_size,
310 const char *_Nonnull __restrict src, size_t size) __overloadable {
311 size_t bos = __bos(dst);
312
313 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
314 return __call_bypassing_fortify(strlcpy)(dst, src, size);
315 }
316
317 return __strlcpy_chk(dst, src, size, bos);
318 }
319
320 __BIONIC_FORTIFY_INLINE
strlcat(char * const _Nonnull __restrict dst __pass_object_size,const char * _Nonnull __restrict src,size_t size)321 size_t strlcat(char* const _Nonnull __restrict dst __pass_object_size,
322 const char* _Nonnull __restrict src, size_t size) __overloadable {
323 size_t bos = __bos(dst);
324
325 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
326 return __call_bypassing_fortify(strlcat)(dst, src, size);
327 }
328
329 return __strlcat_chk(dst, src, size, bos);
330 }
331
332 /*
333 * If we can evaluate the size of s at compile-time, just call __builtin_strlen
334 * on it directly. This makes it way easier for compilers to fold things like
335 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
336 * because it's large.
337 */
338 __BIONIC_FORTIFY_INLINE
strlen(const char * const _Nonnull s __pass_object_size)339 size_t strlen(const char* const _Nonnull s __pass_object_size)
340 __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
341 "enabled if s is a known good string.") {
342 return __builtin_strlen(s);
343 }
344
345 __BIONIC_FORTIFY_INLINE
strlen(const char * const _Nonnull s __pass_object_size0)346 size_t strlen(const char* const _Nonnull s __pass_object_size0)
347 __overloadable {
348 size_t bos = __bos0(s);
349
350 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
351 return __builtin_strlen(s);
352 }
353
354 // return __builtin_strlen(s);
355 return __strlen_chk(s, bos);
356 }
357 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
358
359 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
360 __BIONIC_FORTIFY_INLINE
strchr(const char * const _Nonnull s __pass_object_size0,int c)361 char* strchr(const char* const _Nonnull s __pass_object_size0, int c)
362 __overloadable {
363 size_t bos = __bos0(s);
364
365 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
366 return __builtin_strchr(s, c);
367 }
368
369 // return __builtin_strchr(s, c);
370 return __strchr_chk(s, c, bos);
371 }
372
373 __BIONIC_FORTIFY_INLINE
strrchr(const char * const _Nonnull s __pass_object_size,int c)374 char* strrchr(const char* const _Nonnull s __pass_object_size, int c)
375 __overloadable {
376 size_t bos = __bos(s);
377
378 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
379 return __builtin_strrchr(s, c);
380 }
381
382 return __strrchr_chk(s, c, bos);
383 }
384 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
385
386 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
387 /* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
388 * flipped the size + value arguments. However, there may be cases (e.g. with
389 * macros) where it's okay for the size to fold to zero. We should warn on this,
390 * but we should also provide a FORTIFY'ed escape hatch.
391 */
392 __BIONIC_ERROR_FUNCTION_VISIBILITY
393 void* memset(void* _Nonnull s, int c, size_t n,
394 struct __bionic_zero_size_is_okay_t ok)
395 __overloadable
396 __error_if_overflows_dst(memset, s, n, "size");
397
398 __BIONIC_FORTIFY_INLINE
memset(void * const _Nonnull s __pass_object_size0,int c,size_t n,struct __bionic_zero_size_is_okay_t ok)399 void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n,
400 struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
401 __overloadable {
402 return __builtin___memset_chk(s, c, n, __bos0(s));
403 }
404
405 extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
406 /* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
407 * flipping size + count will do nothing.
408 */
409 __BIONIC_ERROR_FUNCTION_VISIBILITY
410 void* memset(void* _Nonnull s, int c, size_t n) __overloadable
411 __enable_if(c && !n, "selected when we'll set zero bytes")
412 __RENAME_CLANG(memset)
413 __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
414 "(Add __bionic_zero_size_is_okay as a fourth argument "
415 "to silence this.)");
416 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
417
418 #undef __error_zero_size
419 #undef __error_if_overflows_dst
420 #else // defined(__clang__)
421 extern char* __strncpy_real(char* __restrict, const char*, size_t) __RENAME(strncpy);
422 extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
423 extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
424 __RENAME(strlcpy);
425 extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
426 __RENAME(strlcat);
427
428 __errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
429 __errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
430
431 #if __ANDROID_API__ >= __ANDROID_API_M__
432 __BIONIC_FORTIFY_INLINE
memchr(const void * _Nonnull s __pass_object_size,int c,size_t n)433 void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) {
434 size_t bos = __bos(s);
435
436 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
437 return __builtin_memchr(s, c, n);
438 }
439
440 if (__builtin_constant_p(n) && (n > bos)) {
441 __memchr_buf_size_error();
442 }
443
444 if (__builtin_constant_p(n) && (n <= bos)) {
445 return __builtin_memchr(s, c, n);
446 }
447
448 return __memchr_chk(s, c, n, bos);
449 }
450
451 __BIONIC_FORTIFY_INLINE
memrchr(const void * s,int c,size_t n)452 void* memrchr(const void* s, int c, size_t n) {
453 size_t bos = __bos(s);
454
455 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
456 return __memrchr_real(s, c, n);
457 }
458
459 if (__builtin_constant_p(n) && (n > bos)) {
460 __memrchr_buf_size_error();
461 }
462
463 if (__builtin_constant_p(n) && (n <= bos)) {
464 return __memrchr_real(s, c, n);
465 }
466
467 return __memrchr_chk(s, c, n, bos);
468 }
469 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
470
471 #if __ANDROID_API__ >= __ANDROID_API_L__
472 __BIONIC_FORTIFY_INLINE
stpncpy(char * _Nonnull __restrict dst,const char * _Nonnull __restrict src,size_t n)473 char* stpncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
474 size_t bos_dst = __bos(dst);
475 size_t bos_src = __bos(src);
476
477 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
478 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
479 }
480
481 if (__builtin_constant_p(n) && (n <= bos_src)) {
482 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
483 }
484
485 size_t slen = __builtin_strlen(src);
486 if (__builtin_constant_p(slen)) {
487 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
488 }
489
490 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
491 }
492
493 __BIONIC_FORTIFY_INLINE
strncpy(char * _Nonnull __restrict dst,const char * _Nonnull __restrict src,size_t n)494 char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
495 size_t bos_dst = __bos(dst);
496 size_t bos_src = __bos(src);
497
498 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
499 return __strncpy_real(dst, src, n);
500 }
501
502 if (__builtin_constant_p(n) && (n <= bos_src)) {
503 return __builtin___strncpy_chk(dst, src, n, bos_dst);
504 }
505
506 size_t slen = __builtin_strlen(src);
507 if (__builtin_constant_p(slen)) {
508 return __builtin___strncpy_chk(dst, src, n, bos_dst);
509 }
510
511 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
512 }
513 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
514
515 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
516 __BIONIC_FORTIFY_INLINE
strlcpy(char * _Nonnull __restrict dst __pass_object_size,const char * _Nonnull __restrict src,size_t size)517 size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size,
518 const char* _Nonnull __restrict src, size_t size) {
519 size_t bos = __bos(dst);
520
521 // Compiler doesn't know destination size. Don't call __strlcpy_chk
522 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
523 return __strlcpy_real(dst, src, size);
524 }
525
526 // Compiler can prove, at compile time, that the passed in size
527 // is always <= the actual object size. Don't call __strlcpy_chk
528 if (__builtin_constant_p(size) && (size <= bos)) {
529 return __strlcpy_real(dst, src, size);
530 }
531
532 return __strlcpy_chk(dst, src, size, bos);
533 }
534
535 __BIONIC_FORTIFY_INLINE
strlcat(char * _Nonnull __restrict dst,const char * _Nonnull __restrict src,size_t size)536 size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
537 size_t bos = __bos(dst);
538
539 // Compiler doesn't know destination size. Don't call __strlcat_chk
540 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
541 return __strlcat_real(dst, src, size);
542 }
543
544 // Compiler can prove, at compile time, that the passed in size
545 // is always <= the actual object size. Don't call __strlcat_chk
546 if (__builtin_constant_p(size) && (size <= bos)) {
547 return __strlcat_real(dst, src, size);
548 }
549
550 return __strlcat_chk(dst, src, size, bos);
551 }
552
553 __BIONIC_FORTIFY_INLINE
strlen(const char * _Nonnull s)554 size_t strlen(const char* _Nonnull s) __overloadable {
555 size_t bos = __bos(s);
556
557 // Compiler doesn't know destination size. Don't call __strlen_chk
558 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
559 return __builtin_strlen(s);
560 }
561
562 size_t slen = __builtin_strlen(s);
563 if (__builtin_constant_p(slen)) {
564 return slen;
565 }
566
567 return __strlen_chk(s, bos);
568 }
569 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
570
571 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
572 __BIONIC_FORTIFY_INLINE
strchr(const char * _Nonnull s,int c)573 char* strchr(const char* _Nonnull s, int c) {
574 size_t bos = __bos(s);
575
576 // Compiler doesn't know destination size. Don't call __strchr_chk
577 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
578 return __builtin_strchr(s, c);
579 }
580
581 size_t slen = __builtin_strlen(s);
582 if (__builtin_constant_p(slen) && (slen < bos)) {
583 return __builtin_strchr(s, c);
584 }
585
586 return __strchr_chk(s, c, bos);
587 }
588
589 __BIONIC_FORTIFY_INLINE
strrchr(const char * _Nonnull s,int c)590 char* strrchr(const char* _Nonnull s, int c) {
591 size_t bos = __bos(s);
592
593 // Compiler doesn't know destination size. Don't call __strrchr_chk
594 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
595 return __builtin_strrchr(s, c);
596 }
597
598 size_t slen = __builtin_strlen(s);
599 if (__builtin_constant_p(slen) && (slen < bos)) {
600 return __builtin_strrchr(s, c);
601 }
602
603 return __strrchr_chk(s, c, bos);
604 }
605 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
606 #endif /* defined(__clang__) */
607 #endif /* defined(__BIONIC_FORTIFY) */
608
609 #if defined(__clang__)
610 #pragma clang diagnostic pop
611 #endif
612
613 __END_DECLS
614
615 #endif /* _STRING_H */
616