string.h revision b6300463a829762841e3fb7126833f77f62f7100
1/* 2 * Copyright (C) 2017 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#error "Never include this file directly; instead, include <string.h>" 31#endif 32 33void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23); 34void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23); 35char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21); 36char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21); 37size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17); 38size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17); 39 40#if defined(__BIONIC_FORTIFY) 41// These can share their implementation between gcc and clang with minimal 42// trickery... 43#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 44__BIONIC_FORTIFY_INLINE 45void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount) 46 __overloadable 47 __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < copy_amount, 48 "'memcpy' called with size bigger than buffer") { 49 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst)); 50} 51 52__BIONIC_FORTIFY_INLINE 53void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) 54 __overloadable 55 __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < len, 56 "'memmove' called with size bigger than buffer") { 57 return __builtin___memmove_chk(dst, src, len, __bos0(dst)); 58} 59#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 60 61#if __ANDROID_API__ >= __ANDROID_API_L__ 62__BIONIC_FORTIFY_INLINE 63char* stpcpy(char* const dst __pass_object_size, const char* src) 64 __overloadable 65 __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && 66 __bos(dst) <= __builtin_strlen(src), 67 "'stpcpy' called with string bigger than buffer") { 68 return __builtin___stpcpy_chk(dst, src, __bos(dst)); 69} 70#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */ 71 72#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 73__BIONIC_FORTIFY_INLINE 74char* strcpy(char* const dst __pass_object_size, const char* src) 75 __overloadable 76 __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && 77 __bos(dst) <= __builtin_strlen(src), 78 "'strcpy' called with string bigger than buffer") { 79 return __builtin___strcpy_chk(dst, src, __bos(dst)); 80} 81 82__BIONIC_FORTIFY_INLINE 83char* strcat(char* const dst __pass_object_size, const char* src) __overloadable { 84 return __builtin___strcat_chk(dst, src, __bos(dst)); 85} 86 87__BIONIC_FORTIFY_INLINE 88char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable { 89 return __builtin___strncat_chk(dst, src, n, __bos(dst)); 90} 91 92__BIONIC_FORTIFY_INLINE 93void* memset(void* const s __pass_object_size0, int c, size_t n) 94 __overloadable 95 __clang_error_if(__bos0(s) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(s) < n, 96 "'memset' called with size bigger than buffer") 97 /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */ 98 __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") { 99 return __builtin___memset_chk(s, c, n, __bos0(s)); 100} 101#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 102 103 104#if defined(__clang__) 105 106#if __ANDROID_API__ >= __ANDROID_API_M__ 107__BIONIC_FORTIFY_INLINE 108void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable { 109 size_t bos = __bos(s); 110 111 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 112 return __builtin_memchr(s, c, n); 113 } 114 115 return __memchr_chk(s, c, n, bos); 116} 117 118__BIONIC_FORTIFY_INLINE 119void* memrchr(const void* const s __pass_object_size, int c, size_t n) __overloadable { 120 size_t bos = __bos(s); 121 122 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 123 return __call_bypassing_fortify(memrchr)(s, c, n); 124 } 125 126 return __memrchr_chk(s, c, n, bos); 127} 128#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ 129 130#if __ANDROID_API__ >= __ANDROID_API_L__ 131__BIONIC_FORTIFY_INLINE 132char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n) 133 __overloadable { 134 size_t bos_dst = __bos(dst); 135 size_t bos_src = __bos(src); 136 137 /* Ignore dst size checks; they're handled in strncpy_chk */ 138 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 139 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 140 } 141 142 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src); 143} 144 145__BIONIC_FORTIFY_INLINE 146char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n) 147 __overloadable { 148 size_t bos_dst = __bos(dst); 149 size_t bos_src = __bos(src); 150 151 /* Ignore dst size checks; they're handled in strncpy_chk */ 152 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 153 return __builtin___strncpy_chk(dst, src, n, bos_dst); 154 } 155 156 return __strncpy_chk2(dst, src, n, bos_dst, bos_src); 157} 158#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */ 159 160#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 161__BIONIC_FORTIFY_INLINE 162size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable { 163 size_t bos = __bos(dst); 164 165 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 166 return __call_bypassing_fortify(strlcpy)(dst, src, size); 167 } 168 169 return __strlcpy_chk(dst, src, size, bos); 170} 171 172__BIONIC_FORTIFY_INLINE 173size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable { 174 size_t bos = __bos(dst); 175 176 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 177 return __call_bypassing_fortify(strlcat)(dst, src, size); 178 } 179 180 return __strlcat_chk(dst, src, size, bos); 181} 182 183/* 184 * If we can evaluate the size of s at compile-time, just call __builtin_strlen 185 * on it directly. This makes it way easier for compilers to fold things like 186 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply 187 * because it's large. 188 */ 189__BIONIC_FORTIFY_INLINE 190size_t strlen(const char* const s __pass_object_size) 191 __overloadable __enable_if(__builtin_strlen(s) != -1ULL, 192 "enabled if s is a known good string.") { 193 return __builtin_strlen(s); 194} 195 196__BIONIC_FORTIFY_INLINE 197size_t strlen(const char* const s __pass_object_size0) __overloadable { 198 size_t bos = __bos0(s); 199 200 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 201 return __builtin_strlen(s); 202 } 203 204 return __strlen_chk(s, bos); 205} 206#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 207 208#if __ANDROID_API__ >= __ANDROID_API_J_MR2__ 209__BIONIC_FORTIFY_INLINE 210char* strchr(const char* const s __pass_object_size, int c) __overloadable { 211 size_t bos = __bos(s); 212 213 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 214 return __builtin_strchr(s, c); 215 } 216 217 return __strchr_chk(s, c, bos); 218} 219 220__BIONIC_FORTIFY_INLINE 221char* strrchr(const char* const s __pass_object_size, int c) __overloadable { 222 size_t bos = __bos(s); 223 224 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 225 return __builtin_strrchr(s, c); 226 } 227 228 return __strrchr_chk(s, c, bos); 229} 230#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */ 231 232#else // defined(__clang__) 233extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy); 234extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr); 235extern size_t __strlcpy_real(char*, const char*, size_t) 236 __RENAME(strlcpy); 237extern size_t __strlcat_real(char*, const char*, size_t) 238 __RENAME(strlcat); 239 240__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer"); 241__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer"); 242 243#if __ANDROID_API__ >= __ANDROID_API_M__ 244__BIONIC_FORTIFY_INLINE 245void* memchr(const void* s __pass_object_size, int c, size_t n) { 246 size_t bos = __bos(s); 247 248 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 249 return __builtin_memchr(s, c, n); 250 } 251 252 if (__builtin_constant_p(n) && (n > bos)) { 253 __memchr_buf_size_error(); 254 } 255 256 if (__builtin_constant_p(n) && (n <= bos)) { 257 return __builtin_memchr(s, c, n); 258 } 259 260 return __memchr_chk(s, c, n, bos); 261} 262 263__BIONIC_FORTIFY_INLINE 264void* memrchr(const void* s, int c, size_t n) { 265 size_t bos = __bos(s); 266 267 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 268 return __memrchr_real(s, c, n); 269 } 270 271 if (__builtin_constant_p(n) && (n > bos)) { 272 __memrchr_buf_size_error(); 273 } 274 275 if (__builtin_constant_p(n) && (n <= bos)) { 276 return __memrchr_real(s, c, n); 277 } 278 279 return __memrchr_chk(s, c, n, bos); 280} 281#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ 282 283#if __ANDROID_API__ >= __ANDROID_API_L__ 284__BIONIC_FORTIFY_INLINE 285char* stpncpy(char* dst, const char* src, size_t n) { 286 size_t bos_dst = __bos(dst); 287 size_t bos_src = __bos(src); 288 289 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 290 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 291 } 292 293 if (__builtin_constant_p(n) && (n <= bos_src)) { 294 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 295 } 296 297 size_t slen = __builtin_strlen(src); 298 if (__builtin_constant_p(slen)) { 299 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 300 } 301 302 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src); 303} 304 305__BIONIC_FORTIFY_INLINE 306char* strncpy(char* dst, const char* src, size_t n) { 307 size_t bos_dst = __bos(dst); 308 size_t bos_src = __bos(src); 309 310 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 311 return __strncpy_real(dst, src, n); 312 } 313 314 if (__builtin_constant_p(n) && (n <= bos_src)) { 315 return __builtin___strncpy_chk(dst, src, n, bos_dst); 316 } 317 318 size_t slen = __builtin_strlen(src); 319 if (__builtin_constant_p(slen)) { 320 return __builtin___strncpy_chk(dst, src, n, bos_dst); 321 } 322 323 return __strncpy_chk2(dst, src, n, bos_dst, bos_src); 324} 325#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */ 326 327#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 328__BIONIC_FORTIFY_INLINE 329size_t strlcpy(char* dst __pass_object_size, const char* src, size_t size) { 330 size_t bos = __bos(dst); 331 332 // Compiler doesn't know destination size. Don't call __strlcpy_chk 333 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 334 return __strlcpy_real(dst, src, size); 335 } 336 337 // Compiler can prove, at compile time, that the passed in size 338 // is always <= the actual object size. Don't call __strlcpy_chk 339 if (__builtin_constant_p(size) && (size <= bos)) { 340 return __strlcpy_real(dst, src, size); 341 } 342 343 return __strlcpy_chk(dst, src, size, bos); 344} 345 346__BIONIC_FORTIFY_INLINE 347size_t strlcat(char* dst, const char* src, size_t size) { 348 size_t bos = __bos(dst); 349 350 // Compiler doesn't know destination size. Don't call __strlcat_chk 351 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 352 return __strlcat_real(dst, src, size); 353 } 354 355 // Compiler can prove, at compile time, that the passed in size 356 // is always <= the actual object size. Don't call __strlcat_chk 357 if (__builtin_constant_p(size) && (size <= bos)) { 358 return __strlcat_real(dst, src, size); 359 } 360 361 return __strlcat_chk(dst, src, size, bos); 362} 363 364__BIONIC_FORTIFY_INLINE 365size_t strlen(const char* s) __overloadable { 366 size_t bos = __bos(s); 367 368 // Compiler doesn't know destination size. Don't call __strlen_chk 369 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 370 return __builtin_strlen(s); 371 } 372 373 size_t slen = __builtin_strlen(s); 374 if (__builtin_constant_p(slen)) { 375 return slen; 376 } 377 378 return __strlen_chk(s, bos); 379} 380#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 381 382#if __ANDROID_API__ >= __ANDROID_API_J_MR2__ 383__BIONIC_FORTIFY_INLINE 384char* strchr(const char* s, int c) { 385 size_t bos = __bos(s); 386 387 // Compiler doesn't know destination size. Don't call __strchr_chk 388 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 389 return __builtin_strchr(s, c); 390 } 391 392 size_t slen = __builtin_strlen(s); 393 if (__builtin_constant_p(slen) && (slen < bos)) { 394 return __builtin_strchr(s, c); 395 } 396 397 return __strchr_chk(s, c, bos); 398} 399 400__BIONIC_FORTIFY_INLINE 401char* strrchr(const char* s, int c) { 402 size_t bos = __bos(s); 403 404 // Compiler doesn't know destination size. Don't call __strrchr_chk 405 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 406 return __builtin_strrchr(s, c); 407 } 408 409 size_t slen = __builtin_strlen(s); 410 if (__builtin_constant_p(slen) && (slen < bos)) { 411 return __builtin_strrchr(s, c); 412 } 413 414 return __strrchr_chk(s, c, bos); 415} 416#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */ 417#endif /* defined(__clang__) */ 418#endif /* defined(__BIONIC_FORTIFY) */ 419