• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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