string.h revision e087eac404b0e30de427392065e2750acf92bd4a
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#ifndef _STRING_H_ 29#define _STRING_H_ 30 31#include <sys/cdefs.h> 32#include <stddef.h> 33#include <malloc.h> 34#include <xlocale.h> 35 36__BEGIN_DECLS 37 38extern void* memccpy(void* __restrict, const void* __restrict, int, size_t); 39extern void* memchr(const void *, int, size_t) __purefunc; 40extern void* memrchr(const void *, int, size_t) __purefunc; 41extern int memcmp(const void *, const void *, size_t) __purefunc; 42extern void* memcpy(void* __restrict, const void* __restrict, size_t); 43extern void* memmove(void *, const void *, size_t); 44extern void* memset(void *, int, size_t); 45extern void* memmem(const void *, size_t, const void *, size_t) __purefunc; 46 47extern char* strchr(const char *, int) __purefunc; 48extern char* __strchr_chk(const char *, int, size_t); 49 50extern char* strrchr(const char *, int) __purefunc; 51extern char* __strrchr_chk(const char *, int, size_t); 52 53extern size_t strlen(const char *) __purefunc; 54extern size_t __strlen_chk(const char *, size_t); 55extern int strcmp(const char *, const char *) __purefunc; 56extern char* stpcpy(char* __restrict, const char* __restrict); 57extern char* strcpy(char* __restrict, const char* __restrict); 58extern char* strcat(char* __restrict, const char* __restrict); 59 60extern int strcasecmp(const char *, const char *) __purefunc; 61extern int strncasecmp(const char *, const char *, size_t) __purefunc; 62extern char* strdup(const char *); 63 64extern char* strstr(const char *, const char *) __purefunc; 65extern char* strcasestr(const char *haystack, const char *needle) __purefunc; 66extern char* strtok(char* __restrict, const char* __restrict); 67extern char* strtok_r(char* __restrict, const char* __restrict, char** __restrict); 68 69extern char* strerror(int); 70extern int strerror_r(int errnum, char *buf, size_t n); 71 72extern size_t strnlen(const char *, size_t) __purefunc; 73extern char* strncat(char* __restrict, const char* __restrict, size_t); 74extern char* strndup(const char *, size_t); 75extern int strncmp(const char *, const char *, size_t) __purefunc; 76extern char* stpncpy(char* __restrict, const char* __restrict, size_t); 77extern char* strncpy(char* __restrict, const char* __restrict, size_t); 78 79extern size_t strlcat(char* __restrict, const char* __restrict, size_t); 80extern size_t strlcpy(char* __restrict, const char* __restrict, size_t); 81 82extern size_t strcspn(const char *, const char *) __purefunc; 83extern char* strpbrk(const char *, const char *) __purefunc; 84extern char* strsep(char** __restrict, const char* __restrict); 85extern size_t strspn(const char *, const char *); 86 87extern char* strsignal(int sig); 88 89extern int strcoll(const char *, const char *) __purefunc; 90extern size_t strxfrm(char* __restrict, const char* __restrict, size_t); 91 92extern int strcoll_l(const char *, const char *, locale_t) __purefunc; 93extern size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t); 94 95#if defined(__BIONIC_FORTIFY) 96 97__errordecl(__memcpy_dest_size_error, "memcpy: prevented write past end of buffer"); 98__errordecl(__memcpy_src_size_error, "memcpy: prevented read past end of buffer"); 99 100__BIONIC_FORTIFY_INLINE 101void* memcpy(void* __restrict dest, const void* __restrict src, size_t copy_amount) { 102 char *d = (char *) dest; 103 const char *s = (const char *) src; 104 size_t s_len = __bos0(s); 105 size_t d_len = __bos0(d); 106 107 if (__builtin_constant_p(copy_amount) && (copy_amount > d_len)) { 108 __memcpy_dest_size_error(); 109 } 110 111 if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) { 112 __memcpy_src_size_error(); 113 } 114 115 return __builtin___memcpy_chk(dest, src, copy_amount, d_len); 116} 117 118__BIONIC_FORTIFY_INLINE 119void* memmove(void *dest, const void *src, size_t len) { 120 return __builtin___memmove_chk(dest, src, len, __bos0(dest)); 121} 122 123__BIONIC_FORTIFY_INLINE 124char* stpcpy(char* __restrict dest, const char* __restrict src) { 125 return __builtin___stpcpy_chk(dest, src, __bos(dest)); 126} 127 128__BIONIC_FORTIFY_INLINE 129char* strcpy(char* __restrict dest, const char* __restrict src) { 130 return __builtin___strcpy_chk(dest, src, __bos(dest)); 131} 132 133__errordecl(__stpncpy_error, "stpncpy: prevented write past end of buffer"); 134extern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t); 135 136__BIONIC_FORTIFY_INLINE 137char* stpncpy(char* __restrict dest, const char* __restrict src, size_t n) { 138 size_t bos_dest = __bos(dest); 139 size_t bos_src = __bos(src); 140 if (__builtin_constant_p(n) && (n > bos_dest)) { 141 __stpncpy_error(); 142 } 143 144 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 145 return __builtin___stpncpy_chk(dest, src, n, bos_dest); 146 } 147 148 if (__builtin_constant_p(n) && (n <= bos_src)) { 149 return __builtin___stpncpy_chk(dest, src, n, bos_dest); 150 } 151 152 size_t slen = __builtin_strlen(src); 153 if (__builtin_constant_p(slen)) { 154 return __builtin___stpncpy_chk(dest, src, n, bos_dest); 155 } 156 157 return __stpncpy_chk2(dest, src, n, bos_dest, bos_src); 158} 159 160__errordecl(__strncpy_error, "strncpy: prevented write past end of buffer"); 161extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t); 162 163__BIONIC_FORTIFY_INLINE 164char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) { 165 size_t bos_dest = __bos(dest); 166 size_t bos_src = __bos(src); 167 if (__builtin_constant_p(n) && (n > bos_dest)) { 168 __strncpy_error(); 169 } 170 171 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 172 return __builtin___strncpy_chk(dest, src, n, bos_dest); 173 } 174 175 if (__builtin_constant_p(n) && (n <= bos_src)) { 176 return __builtin___strncpy_chk(dest, src, n, bos_dest); 177 } 178 179 size_t slen = __builtin_strlen(src); 180 if (__builtin_constant_p(slen)) { 181 return __builtin___strncpy_chk(dest, src, n, bos_dest); 182 } 183 184 return __strncpy_chk2(dest, src, n, bos_dest, bos_src); 185} 186 187__BIONIC_FORTIFY_INLINE 188char* strcat(char* __restrict dest, const char* __restrict src) { 189 return __builtin___strcat_chk(dest, src, __bos(dest)); 190} 191 192__BIONIC_FORTIFY_INLINE 193char *strncat(char* __restrict dest, const char* __restrict src, size_t n) { 194 return __builtin___strncat_chk(dest, src, n, __bos(dest)); 195} 196 197__BIONIC_FORTIFY_INLINE 198void* memset(void *s, int c, size_t n) { 199 return __builtin___memset_chk(s, c, n, __bos0(s)); 200} 201 202extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t) 203 __asm__(__USER_LABEL_PREFIX__ "strlcpy"); 204__errordecl(__strlcpy_error, "strlcpy: prevented write past end of buffer"); 205extern size_t __strlcpy_chk(char *, const char *, size_t, size_t); 206 207__BIONIC_FORTIFY_INLINE 208size_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) { 209 size_t bos = __bos(dest); 210 211#if !defined(__clang__) 212 // Compiler doesn't know destination size. Don't call __strlcpy_chk 213 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 214 return __strlcpy_real(dest, src, size); 215 } 216 217 // Compiler can prove, at compile time, that the passed in size 218 // is always <= the actual object size. Don't call __strlcpy_chk 219 if (__builtin_constant_p(size) && (size <= bos)) { 220 return __strlcpy_real(dest, src, size); 221 } 222 223 // Compiler can prove, at compile time, that the passed in size 224 // is always > the actual object size. Force a compiler error. 225 if (__builtin_constant_p(size) && (size > bos)) { 226 __strlcpy_error(); 227 } 228#endif /* !defined(__clang__) */ 229 230 return __strlcpy_chk(dest, src, size, bos); 231} 232 233extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t) 234 __asm__(__USER_LABEL_PREFIX__ "strlcat"); 235__errordecl(__strlcat_error, "strlcat: prevented write past end of buffer"); 236extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t); 237 238 239__BIONIC_FORTIFY_INLINE 240size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) { 241 size_t bos = __bos(dest); 242 243#if !defined(__clang__) 244 // Compiler doesn't know destination size. Don't call __strlcat_chk 245 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 246 return __strlcat_real(dest, src, size); 247 } 248 249 // Compiler can prove, at compile time, that the passed in size 250 // is always <= the actual object size. Don't call __strlcat_chk 251 if (__builtin_constant_p(size) && (size <= bos)) { 252 return __strlcat_real(dest, src, size); 253 } 254 255 // Compiler can prove, at compile time, that the passed in size 256 // is always > the actual object size. Force a compiler error. 257 if (__builtin_constant_p(size) && (size > bos)) { 258 __strlcat_error(); 259 } 260#endif /* !defined(__clang__) */ 261 262 return __strlcat_chk(dest, src, size, bos); 263} 264 265__BIONIC_FORTIFY_INLINE 266size_t strlen(const char *s) { 267 size_t bos = __bos(s); 268 269#if !defined(__clang__) 270 // Compiler doesn't know destination size. Don't call __strlen_chk 271 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 272 return __builtin_strlen(s); 273 } 274 275 size_t slen = __builtin_strlen(s); 276 if (__builtin_constant_p(slen)) { 277 return slen; 278 } 279#endif /* !defined(__clang__) */ 280 281 return __strlen_chk(s, bos); 282} 283 284__BIONIC_FORTIFY_INLINE 285char* strchr(const char *s, int c) { 286 size_t bos = __bos(s); 287 288#if !defined(__clang__) 289 // Compiler doesn't know destination size. Don't call __strchr_chk 290 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 291 return __builtin_strchr(s, c); 292 } 293 294 size_t slen = __builtin_strlen(s); 295 if (__builtin_constant_p(slen) && (slen < bos)) { 296 return __builtin_strchr(s, c); 297 } 298#endif /* !defined(__clang__) */ 299 300 return __strchr_chk(s, c, bos); 301} 302 303__BIONIC_FORTIFY_INLINE 304char* strrchr(const char *s, int c) { 305 size_t bos = __bos(s); 306 307#if !defined(__clang__) 308 // Compiler doesn't know destination size. Don't call __strrchr_chk 309 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 310 return __builtin_strrchr(s, c); 311 } 312 313 size_t slen = __builtin_strlen(s); 314 if (__builtin_constant_p(slen) && (slen < bos)) { 315 return __builtin_strrchr(s, c); 316 } 317#endif /* !defined(__clang__) */ 318 319 return __strrchr_chk(s, c, bos); 320} 321 322 323#endif /* defined(__BIONIC_FORTIFY) */ 324 325__END_DECLS 326 327#endif /* _STRING_H_ */ 328