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