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__ __INTRODUCED_IN(24);
71 extern "C++" const char* strchrnul(const char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
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) __INTRODUCED_IN(23);
146 extern "C++" const char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
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, const void* _Nonnull __restrict src, size_t copy_amount)
172 __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, const void* _Nonnull src, size_t len)
178 __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, const char* _Nonnull __restrict src)
186 __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, const char* _Nonnull __restrict src)
194 __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, const char* _Nonnull __restrict src)
200 __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, const char* _Nonnull __restrict src, size_t n)
206 __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) __overloadable {
212 return __builtin___memset_chk(s, c, n, __bos0(s));
213 }
214 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
215
216
217 #if defined(__clang__)
218
219 #define __error_if_overflows_dst(name, dst, n, what) \
220 __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
221 __bos0(dst) < (n), "selected when the buffer is too small") \
222 __errorattr(#name " called with " what " bigger than buffer")
223
224 /*
225 * N.B. _Nonnull isn't necessary on params, since these functions just emit
226 * errors.
227 */
228 __BIONIC_ERROR_FUNCTION_VISIBILITY
229 void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
230 __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
231
232 __BIONIC_ERROR_FUNCTION_VISIBILITY
233 void* memmove(void *dst, const void* src, size_t len) __overloadable
234 __error_if_overflows_dst(memmove, dst, len, "size");
235
236 __BIONIC_ERROR_FUNCTION_VISIBILITY
237 void* memset(void* s, int c, size_t n) __overloadable
238 __error_if_overflows_dst(memset, s, n, "size");
239
240 __BIONIC_ERROR_FUNCTION_VISIBILITY
241 char* stpcpy(char* dst, const char* src) __overloadable
242 __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
243
244 __BIONIC_ERROR_FUNCTION_VISIBILITY
245 char* strcpy(char* dst, const char* src) __overloadable
246 __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
247
248 #if __ANDROID_API__ >= __ANDROID_API_M__
249 __BIONIC_FORTIFY_INLINE
memchr(const void * const _Nonnull s __pass_object_size,int c,size_t n)250 void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
251 __overloadable {
252 size_t bos = __bos(s);
253
254 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
255 return __builtin_memchr(s, c, n);
256 }
257
258 return __memchr_chk(s, c, n, bos);
259 }
260
261 __BIONIC_FORTIFY_INLINE
memrchr(const void * const _Nonnull s __pass_object_size,int c,size_t n)262 void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
263 __overloadable {
264 size_t bos = __bos(s);
265
266 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
267 return __call_bypassing_fortify(memrchr)(s, c, n);
268 }
269
270 return __memrchr_chk(s, c, n, bos);
271 }
272 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
273
274 #if __ANDROID_API__ >= __ANDROID_API_L__
275 __BIONIC_FORTIFY_INLINE
stpncpy(char * __restrict const _Nonnull dst __pass_object_size,const char * __restrict const _Nonnull src __pass_object_size,size_t n)276 char* stpncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
277 __overloadable {
278 size_t bos_dst = __bos(dst);
279 size_t bos_src = __bos(src);
280
281 /* Ignore dst size checks; they're handled in strncpy_chk */
282 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
283 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
284 }
285
286 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
287 }
288
289 __BIONIC_FORTIFY_INLINE
strncpy(char * __restrict const _Nonnull dst __pass_object_size,const char * __restrict const _Nonnull src __pass_object_size,size_t n)290 char* strncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
291 __overloadable {
292 size_t bos_dst = __bos(dst);
293 size_t bos_src = __bos(src);
294
295 /* Ignore dst size checks; they're handled in strncpy_chk */
296 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
297 return __builtin___strncpy_chk(dst, src, n, bos_dst);
298 }
299
300 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
301 }
302 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
303
304 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
305 __BIONIC_FORTIFY_INLINE
strlcpy(char * const _Nonnull __restrict dst __pass_object_size,const char * _Nonnull __restrict src,size_t size)306 size_t strlcpy(char* const _Nonnull __restrict dst __pass_object_size, const char *_Nonnull __restrict src, size_t size)
307 __overloadable {
308 size_t bos = __bos(dst);
309
310 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
311 return __call_bypassing_fortify(strlcpy)(dst, src, size);
312 }
313
314 return __strlcpy_chk(dst, src, size, bos);
315 }
316
317 __BIONIC_FORTIFY_INLINE
strlcat(char * const _Nonnull __restrict dst __pass_object_size,const char * _Nonnull __restrict src,size_t size)318 size_t strlcat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size)
319 __overloadable {
320 size_t bos = __bos(dst);
321
322 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
323 return __call_bypassing_fortify(strlcat)(dst, src, size);
324 }
325
326 return __strlcat_chk(dst, src, size, bos);
327 }
328
329 /*
330 * If we can evaluate the size of s at compile-time, just call __builtin_strlen
331 * on it directly. This makes it way easier for compilers to fold things like
332 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
333 * because it's large.
334 */
335 __BIONIC_FORTIFY_INLINE
strlen(const char * const _Nonnull s __pass_object_size)336 size_t strlen(const char* const _Nonnull s __pass_object_size)
337 __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
338 "enabled if s is a known good string.") {
339 return __builtin_strlen(s);
340 }
341
342 __BIONIC_FORTIFY_INLINE
strlen(const char * const _Nonnull s __pass_object_size0)343 size_t strlen(const char* const _Nonnull s __pass_object_size0)
344 __overloadable {
345 size_t bos = __bos0(s);
346
347 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
348 return __builtin_strlen(s);
349 }
350
351 // return __builtin_strlen(s);
352 return __strlen_chk(s, bos);
353 }
354 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
355
356 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
357 __BIONIC_FORTIFY_INLINE
strchr(const char * const _Nonnull s __pass_object_size,int c)358 char* strchr(const char* const _Nonnull s __pass_object_size, int c)
359 __overloadable {
360 size_t bos = __bos(s);
361
362 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
363 return __builtin_strchr(s, c);
364 }
365
366 return __strchr_chk(s, c, bos);
367 }
368
369 __BIONIC_FORTIFY_INLINE
strrchr(const char * const _Nonnull s __pass_object_size,int c)370 char* strrchr(const char* const _Nonnull s __pass_object_size, int c)
371 __overloadable {
372 size_t bos = __bos(s);
373
374 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
375 return __builtin_strrchr(s, c);
376 }
377
378 return __strrchr_chk(s, c, bos);
379 }
380 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
381
382 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
383 /* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
384 * flipped the size + value arguments. However, there may be cases (e.g. with
385 * macros) where it's okay for the size to fold to zero. We should warn on this,
386 * but we should also provide a FORTIFY'ed escape hatch.
387 */
388 __BIONIC_ERROR_FUNCTION_VISIBILITY
389 void* memset(void* _Nonnull s, int c, size_t n, struct __bionic_zero_size_is_okay_t ok)
390 __overloadable
391 __error_if_overflows_dst(memset, s, n, "size");
392
393 __BIONIC_FORTIFY_INLINE
memset(void * const _Nonnull s __pass_object_size0,int c,size_t n,struct __bionic_zero_size_is_okay_t ok)394 void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n, struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
395 __overloadable {
396 return __builtin___memset_chk(s, c, n, __bos0(s));
397 }
398
399 extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
400 /* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
401 * flipping size + count will do nothing.
402 */
403 __BIONIC_ERROR_FUNCTION_VISIBILITY
404 void* memset(void* _Nonnull s, int c, size_t n) __overloadable
405 __enable_if(c && !n, "selected when we'll set zero bytes")
406 __RENAME_CLANG(memset)
407 __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
408 "(Add __bionic_zero_size_is_okay as a fourth argument "
409 "to silence this.)");
410 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
411
412 #undef __error_zero_size
413 #undef __error_if_overflows_dst
414 #else // defined(__clang__)
415 extern char* __strncpy_real(char* __restrict, const char*, size_t) __RENAME(strncpy);
416 extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
417 extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
418 __RENAME(strlcpy);
419 extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
420 __RENAME(strlcat);
421
422 __errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
423 __errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
424
425 #if __ANDROID_API__ >= __ANDROID_API_M__
426 __BIONIC_FORTIFY_INLINE
memchr(const void * _Nonnull s __pass_object_size,int c,size_t n)427 void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) {
428 size_t bos = __bos(s);
429
430 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
431 return __builtin_memchr(s, c, n);
432 }
433
434 if (__builtin_constant_p(n) && (n > bos)) {
435 __memchr_buf_size_error();
436 }
437
438 if (__builtin_constant_p(n) && (n <= bos)) {
439 return __builtin_memchr(s, c, n);
440 }
441
442 return __memchr_chk(s, c, n, bos);
443 }
444
445 __BIONIC_FORTIFY_INLINE
memrchr(const void * s,int c,size_t n)446 void* memrchr(const void* s, int c, size_t n) {
447 size_t bos = __bos(s);
448
449 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
450 return __memrchr_real(s, c, n);
451 }
452
453 if (__builtin_constant_p(n) && (n > bos)) {
454 __memrchr_buf_size_error();
455 }
456
457 if (__builtin_constant_p(n) && (n <= bos)) {
458 return __memrchr_real(s, c, n);
459 }
460
461 return __memrchr_chk(s, c, n, bos);
462 }
463 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
464
465 #if __ANDROID_API__ >= __ANDROID_API_L__
466 __BIONIC_FORTIFY_INLINE
stpncpy(char * _Nonnull __restrict dst,const char * _Nonnull __restrict src,size_t n)467 char* stpncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
468 size_t bos_dst = __bos(dst);
469 size_t bos_src = __bos(src);
470
471 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
472 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
473 }
474
475 if (__builtin_constant_p(n) && (n <= bos_src)) {
476 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
477 }
478
479 size_t slen = __builtin_strlen(src);
480 if (__builtin_constant_p(slen)) {
481 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
482 }
483
484 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
485 }
486
487 __BIONIC_FORTIFY_INLINE
strncpy(char * _Nonnull __restrict dst,const char * _Nonnull __restrict src,size_t n)488 char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
489 size_t bos_dst = __bos(dst);
490 size_t bos_src = __bos(src);
491
492 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
493 return __strncpy_real(dst, src, n);
494 }
495
496 if (__builtin_constant_p(n) && (n <= bos_src)) {
497 return __builtin___strncpy_chk(dst, src, n, bos_dst);
498 }
499
500 size_t slen = __builtin_strlen(src);
501 if (__builtin_constant_p(slen)) {
502 return __builtin___strncpy_chk(dst, src, n, bos_dst);
503 }
504
505 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
506 }
507 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
508
509 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
510 __BIONIC_FORTIFY_INLINE
strlcpy(char * _Nonnull __restrict dst __pass_object_size,const char * _Nonnull __restrict src,size_t size)511 size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size) {
512 size_t bos = __bos(dst);
513
514 // Compiler doesn't know destination size. Don't call __strlcpy_chk
515 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
516 return __strlcpy_real(dst, src, size);
517 }
518
519 // Compiler can prove, at compile time, that the passed in size
520 // is always <= the actual object size. Don't call __strlcpy_chk
521 if (__builtin_constant_p(size) && (size <= bos)) {
522 return __strlcpy_real(dst, src, size);
523 }
524
525 return __strlcpy_chk(dst, src, size, bos);
526 }
527
528 __BIONIC_FORTIFY_INLINE
strlcat(char * _Nonnull __restrict dst,const char * _Nonnull __restrict src,size_t size)529 size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
530 size_t bos = __bos(dst);
531
532 // Compiler doesn't know destination size. Don't call __strlcat_chk
533 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
534 return __strlcat_real(dst, src, size);
535 }
536
537 // Compiler can prove, at compile time, that the passed in size
538 // is always <= the actual object size. Don't call __strlcat_chk
539 if (__builtin_constant_p(size) && (size <= bos)) {
540 return __strlcat_real(dst, src, size);
541 }
542
543 return __strlcat_chk(dst, src, size, bos);
544 }
545
546 __BIONIC_FORTIFY_INLINE
strlen(const char * _Nonnull s)547 size_t strlen(const char* _Nonnull s) __overloadable {
548 size_t bos = __bos(s);
549
550 // Compiler doesn't know destination size. Don't call __strlen_chk
551 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
552 return __builtin_strlen(s);
553 }
554
555 size_t slen = __builtin_strlen(s);
556 if (__builtin_constant_p(slen)) {
557 return slen;
558 }
559
560 return __strlen_chk(s, bos);
561 }
562 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
563
564 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
565 __BIONIC_FORTIFY_INLINE
strchr(const char * _Nonnull s,int c)566 char* strchr(const char* _Nonnull s, int c) {
567 size_t bos = __bos(s);
568
569 // Compiler doesn't know destination size. Don't call __strchr_chk
570 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
571 return __builtin_strchr(s, c);
572 }
573
574 size_t slen = __builtin_strlen(s);
575 if (__builtin_constant_p(slen) && (slen < bos)) {
576 return __builtin_strchr(s, c);
577 }
578
579 return __strchr_chk(s, c, bos);
580 }
581
582 __BIONIC_FORTIFY_INLINE
strrchr(const char * _Nonnull s,int c)583 char* strrchr(const char* _Nonnull s, int c) {
584 size_t bos = __bos(s);
585
586 // Compiler doesn't know destination size. Don't call __strrchr_chk
587 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
588 return __builtin_strrchr(s, c);
589 }
590
591 size_t slen = __builtin_strlen(s);
592 if (__builtin_constant_p(slen) && (slen < bos)) {
593 return __builtin_strrchr(s, c);
594 }
595
596 return __strrchr_chk(s, c, bos);
597 }
598 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
599 #endif /* defined(__clang__) */
600 #endif /* defined(__BIONIC_FORTIFY) */
601
602 /* Const-correct overloads. Placed after FORTIFY so we call those functions, if possible. */
603 #if defined(__cplusplus) && defined(__clang__)
604 /*
605 * Use two enable_ifs so these overloads don't conflict with + are preferred over libcxx's. This can
606 * be reduced to 1 after libcxx recognizes that we have const-correct overloads.
607 */
608 #define __prefer_this_overload __enable_if(true, "preferred overload") __enable_if(true, "")
609 extern "C++" {
610 inline __always_inline
__bionic_memchr(const void * const _Nonnull s __pass_object_size,int c,size_t n)611 void* __bionic_memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n) {
612 return memchr(s, c, n);
613 }
614
615 inline __always_inline
memchr(const void * const _Nonnull s __pass_object_size,int c,size_t n)616 const void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
617 __prefer_this_overload {
618 return __bionic_memchr(s, c, n);
619 }
620
621 inline __always_inline
memchr(void * const _Nonnull s __pass_object_size,int c,size_t n)622 void* memchr(void* const _Nonnull s __pass_object_size, int c, size_t n) __prefer_this_overload {
623 return __bionic_memchr(s, c, n);
624 }
625
626 inline __always_inline
__bionic_strchr(const char * const _Nonnull s __pass_object_size,int c)627 char* __bionic_strchr(const char* const _Nonnull s __pass_object_size, int c) {
628 return strchr(s, c);
629 }
630
631 inline __always_inline
strchr(const char * const _Nonnull s __pass_object_size,int c)632 const char* strchr(const char* const _Nonnull s __pass_object_size, int c)
633 __prefer_this_overload {
634 return __bionic_strchr(s, c);
635 }
636
637 inline __always_inline
strchr(char * const _Nonnull s __pass_object_size,int c)638 char* strchr(char* const _Nonnull s __pass_object_size, int c)
639 __prefer_this_overload {
640 return __bionic_strchr(s, c);
641 }
642
643 inline __always_inline
__bionic_strrchr(const char * const _Nonnull s __pass_object_size,int c)644 char* __bionic_strrchr(const char* const _Nonnull s __pass_object_size, int c) {
645 return strrchr(s, c);
646 }
647
648 inline __always_inline
strrchr(const char * const _Nonnull s __pass_object_size,int c)649 const char* strrchr(const char* const _Nonnull s __pass_object_size, int c) __prefer_this_overload {
650 return __bionic_strrchr(s, c);
651 }
652
653 inline __always_inline
strrchr(char * const _Nonnull s __pass_object_size,int c)654 char* strrchr(char* const _Nonnull s __pass_object_size, int c) __prefer_this_overload {
655 return __bionic_strrchr(s, c);
656 }
657
658 /* Functions with no FORTIFY counterpart. */
659 inline __always_inline
__bionic_strstr(const char * _Nonnull h,const char * _Nonnull n)660 char* __bionic_strstr(const char* _Nonnull h, const char* _Nonnull n) { return strstr(h, n); }
661
662 inline __always_inline
strstr(const char * _Nonnull h,const char * _Nonnull n)663 const char* strstr(const char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
664 return __bionic_strstr(h, n);
665 }
666
667 inline __always_inline
strstr(char * _Nonnull h,const char * _Nonnull n)668 char* strstr(char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
669 return __bionic_strstr(h, n);
670 }
671
672 inline __always_inline
__bionic_strpbrk(const char * _Nonnull h,const char * _Nonnull n)673 char* __bionic_strpbrk(const char* _Nonnull h, const char* _Nonnull n) { return strpbrk(h, n); }
674
675 inline __always_inline
strpbrk(char * _Nonnull h,const char * _Nonnull n)676 char* strpbrk(char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
677 return __bionic_strpbrk(h, n);
678 }
679
680 inline __always_inline
strpbrk(const char * _Nonnull h,const char * _Nonnull n)681 const char* strpbrk(const char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
682 return __bionic_strpbrk(h, n);
683 }
684 }
685 #undef __prefer_this_overload
686 #endif
687
688 #if defined(__clang__)
689 #pragma clang diagnostic pop
690 #endif
691
692 __END_DECLS
693
694 #endif /* _STRING_H */
695