Home | History | Annotate | Download | only in include
      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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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