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__BEGIN_DECLS
37
38#if defined(__USE_BSD)
39#include <strings.h>
40#endif
41
42extern void*  memccpy(void* __restrict, const void* __restrict, int, size_t);
43extern void*  memchr(const void *, int, size_t) __purefunc;
44extern void*  memrchr(const void *, int, size_t) __purefunc;
45extern int    memcmp(const void *, const void *, size_t) __purefunc;
46extern void*  memcpy(void* __restrict, const void* __restrict, size_t);
47#if defined(__USE_GNU)
48extern void*  mempcpy(void* __restrict, const void* __restrict, size_t);
49#endif
50extern void*  memmove(void *, const void *, size_t);
51extern void*  memset(void *, int, size_t);
52extern void*  memmem(const void *, size_t, const void *, size_t) __purefunc;
53
54extern char*  strchr(const char *, int) __purefunc;
55extern char* __strchr_chk(const char *, int, size_t);
56
57extern char*  strrchr(const char *, int) __purefunc;
58extern char* __strrchr_chk(const char *, int, size_t);
59
60extern size_t strlen(const char *) __purefunc;
61extern size_t __strlen_chk(const char *, size_t);
62extern int    strcmp(const char *, const char *) __purefunc;
63extern char*  stpcpy(char* __restrict, const char* __restrict);
64extern char*  strcpy(char* __restrict, const char* __restrict);
65extern char*  strcat(char* __restrict, const char* __restrict);
66
67int strcasecmp(const char*, const char*) __purefunc;
68int strcasecmp_l(const char*, const char*, locale_t) __purefunc;
69int strncasecmp(const char*, const char*, size_t) __purefunc;
70int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;
71
72extern char*  strdup(const char *);
73
74extern char*  strstr(const char *, const char *) __purefunc;
75extern char*  strcasestr(const char *haystack, const char *needle) __purefunc;
76extern char*  strtok(char* __restrict, const char* __restrict);
77extern char*  strtok_r(char* __restrict, const char* __restrict, char** __restrict);
78
79extern char* strerror(int);
80extern char* strerror_l(int, locale_t);
81#if defined(__USE_GNU)
82extern char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r);
83#else /* POSIX */
84extern int strerror_r(int, char*, size_t);
85#endif
86
87extern size_t strnlen(const char *, size_t) __purefunc;
88extern char*  strncat(char* __restrict, const char* __restrict, size_t);
89extern char*  strndup(const char *, size_t);
90extern int    strncmp(const char *, const char *, size_t) __purefunc;
91extern char*  stpncpy(char* __restrict, const char* __restrict, size_t);
92extern char*  strncpy(char* __restrict, const char* __restrict, size_t);
93
94extern size_t strlcat(char* __restrict, const char* __restrict, size_t);
95extern size_t strlcpy(char* __restrict, const char* __restrict, size_t);
96
97extern size_t strcspn(const char *, const char *) __purefunc;
98extern char*  strpbrk(const char *, const char *) __purefunc;
99extern char*  strsep(char** __restrict, const char* __restrict);
100extern size_t strspn(const char *, const char *);
101
102extern char*  strsignal(int  sig);
103
104extern int    strcoll(const char *, const char *) __purefunc;
105extern size_t strxfrm(char* __restrict, const char* __restrict, size_t);
106
107extern int    strcoll_l(const char *, const char *, locale_t) __purefunc;
108extern size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t);
109
110#if defined(__USE_GNU) && !defined(__bionic_using_posix_basename)
111/*
112 * glibc has a basename in <string.h> that's different to the POSIX one in <libgen.h>.
113 * It doesn't modify its argument, and in C++ it's const-correct.
114 */
115#if defined(__cplusplus)
116extern "C++" char* basename(char*) __RENAME(__gnu_basename) __nonnull((1));
117extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));
118#else
119extern char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));
120#endif
121#define __bionic_using_gnu_basename
122#endif
123
124extern void* __memchr_chk(const void*, int, size_t, size_t);
125__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
126
127extern void* __memrchr_chk(const void*, int, size_t, size_t);
128__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
129extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
130
131extern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
132extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
133extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcpy);
134extern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
135extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcat);
136extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t);
137
138#if defined(__BIONIC_FORTIFY)
139
140__BIONIC_FORTIFY_INLINE
141void* memchr(const void *s, int c, size_t n) {
142    size_t bos = __bos(s);
143
144#if !defined(__clang__)
145    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
146        return __builtin_memchr(s, c, n);
147    }
148
149    if (__builtin_constant_p(n) && (n > bos)) {
150        __memchr_buf_size_error();
151    }
152
153    if (__builtin_constant_p(n) && (n <= bos)) {
154        return __builtin_memchr(s, c, n);
155    }
156#endif
157
158    return __memchr_chk(s, c, n, bos);
159}
160
161__BIONIC_FORTIFY_INLINE
162void* memrchr(const void *s, int c, size_t n) {
163    size_t bos = __bos(s);
164
165#if !defined(__clang__)
166    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
167        return __memrchr_real(s, c, n);
168    }
169
170    if (__builtin_constant_p(n) && (n > bos)) {
171        __memrchr_buf_size_error();
172    }
173
174    if (__builtin_constant_p(n) && (n <= bos)) {
175        return __memrchr_real(s, c, n);
176    }
177#endif
178
179    return __memrchr_chk(s, c, n, bos);
180}
181
182__BIONIC_FORTIFY_INLINE
183void* memcpy(void* __restrict dest, const void* __restrict src, size_t copy_amount) {
184    return __builtin___memcpy_chk(dest, src, copy_amount, __bos0(dest));
185}
186
187__BIONIC_FORTIFY_INLINE
188void* memmove(void *dest, const void *src, size_t len) {
189    return __builtin___memmove_chk(dest, src, len, __bos0(dest));
190}
191
192__BIONIC_FORTIFY_INLINE
193char* stpcpy(char* __restrict dest, const char* __restrict src) {
194    return __builtin___stpcpy_chk(dest, src, __bos(dest));
195}
196
197__BIONIC_FORTIFY_INLINE
198char* strcpy(char* __restrict dest, const char* __restrict src) {
199    return __builtin___strcpy_chk(dest, src, __bos(dest));
200}
201
202__BIONIC_FORTIFY_INLINE
203char* stpncpy(char* __restrict dest, const char* __restrict src, size_t n) {
204    size_t bos_dest = __bos(dest);
205    size_t bos_src = __bos(src);
206
207    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
208        return __builtin___stpncpy_chk(dest, src, n, bos_dest);
209    }
210
211    if (__builtin_constant_p(n) && (n <= bos_src)) {
212        return __builtin___stpncpy_chk(dest, src, n, bos_dest);
213    }
214
215    size_t slen = __builtin_strlen(src);
216    if (__builtin_constant_p(slen)) {
217        return __builtin___stpncpy_chk(dest, src, n, bos_dest);
218    }
219
220    return __stpncpy_chk2(dest, src, n, bos_dest, bos_src);
221}
222
223__BIONIC_FORTIFY_INLINE
224char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
225    size_t bos_dest = __bos(dest);
226    size_t bos_src = __bos(src);
227
228    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
229        return __builtin___strncpy_chk(dest, src, n, bos_dest);
230    }
231
232    if (__builtin_constant_p(n) && (n <= bos_src)) {
233        return __builtin___strncpy_chk(dest, src, n, bos_dest);
234    }
235
236    size_t slen = __builtin_strlen(src);
237    if (__builtin_constant_p(slen)) {
238        return __builtin___strncpy_chk(dest, src, n, bos_dest);
239    }
240
241    return __strncpy_chk2(dest, src, n, bos_dest, bos_src);
242}
243
244__BIONIC_FORTIFY_INLINE
245char* strcat(char* __restrict dest, const char* __restrict src) {
246    return __builtin___strcat_chk(dest, src, __bos(dest));
247}
248
249__BIONIC_FORTIFY_INLINE
250char *strncat(char* __restrict dest, const char* __restrict src, size_t n) {
251    return __builtin___strncat_chk(dest, src, n, __bos(dest));
252}
253
254__BIONIC_FORTIFY_INLINE
255void* memset(void *s, int c, size_t n) {
256    return __builtin___memset_chk(s, c, n, __bos0(s));
257}
258
259__BIONIC_FORTIFY_INLINE
260size_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) {
261    size_t bos = __bos(dest);
262
263#if !defined(__clang__)
264    // Compiler doesn't know destination size. Don't call __strlcpy_chk
265    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
266        return __strlcpy_real(dest, src, size);
267    }
268
269    // Compiler can prove, at compile time, that the passed in size
270    // is always <= the actual object size. Don't call __strlcpy_chk
271    if (__builtin_constant_p(size) && (size <= bos)) {
272        return __strlcpy_real(dest, src, size);
273    }
274#endif /* !defined(__clang__) */
275
276    return __strlcpy_chk(dest, src, size, bos);
277}
278
279
280__BIONIC_FORTIFY_INLINE
281size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) {
282    size_t bos = __bos(dest);
283
284#if !defined(__clang__)
285    // Compiler doesn't know destination size. Don't call __strlcat_chk
286    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
287        return __strlcat_real(dest, src, size);
288    }
289
290    // Compiler can prove, at compile time, that the passed in size
291    // is always <= the actual object size. Don't call __strlcat_chk
292    if (__builtin_constant_p(size) && (size <= bos)) {
293        return __strlcat_real(dest, src, size);
294    }
295#endif /* !defined(__clang__) */
296
297    return __strlcat_chk(dest, src, size, bos);
298}
299
300__BIONIC_FORTIFY_INLINE
301size_t strlen(const char *s) {
302    size_t bos = __bos(s);
303
304#if !defined(__clang__)
305    // Compiler doesn't know destination size. Don't call __strlen_chk
306    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
307        return __builtin_strlen(s);
308    }
309
310    size_t slen = __builtin_strlen(s);
311    if (__builtin_constant_p(slen)) {
312        return slen;
313    }
314#endif /* !defined(__clang__) */
315
316    return __strlen_chk(s, bos);
317}
318
319__BIONIC_FORTIFY_INLINE
320char* strchr(const char *s, int c) {
321    size_t bos = __bos(s);
322
323#if !defined(__clang__)
324    // Compiler doesn't know destination size. Don't call __strchr_chk
325    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
326        return __builtin_strchr(s, c);
327    }
328
329    size_t slen = __builtin_strlen(s);
330    if (__builtin_constant_p(slen) && (slen < bos)) {
331        return __builtin_strchr(s, c);
332    }
333#endif /* !defined(__clang__) */
334
335    return __strchr_chk(s, c, bos);
336}
337
338__BIONIC_FORTIFY_INLINE
339char* strrchr(const char *s, int c) {
340    size_t bos = __bos(s);
341
342#if !defined(__clang__)
343    // Compiler doesn't know destination size. Don't call __strrchr_chk
344    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
345        return __builtin_strrchr(s, c);
346    }
347
348    size_t slen = __builtin_strlen(s);
349    if (__builtin_constant_p(slen) && (slen < bos)) {
350        return __builtin_strrchr(s, c);
351    }
352#endif /* !defined(__clang__) */
353
354    return __strrchr_chk(s, c, bos);
355}
356
357
358#endif /* defined(__BIONIC_FORTIFY) */
359
360__END_DECLS
361
362#endif /* _STRING_H */
363