• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
37 extern void*  memccpy(void* __restrict, const void* __restrict, int, size_t);
38 extern void*  memchr(const void *, int, size_t) __purefunc;
39 extern void*  memrchr(const void *, int, size_t) __purefunc;
40 extern int    memcmp(const void *, const void *, size_t) __purefunc;
41 extern void*  memcpy(void* __restrict, const void* __restrict, size_t);
42 extern void*  memmove(void *, const void *, size_t);
43 extern void*  memset(void *, int, size_t);
44 extern void*  memmem(const void *, size_t, const void *, size_t) __purefunc;
45 
46 extern char*  strchr(const char *, int) __purefunc;
47 extern char* __strchr_chk(const char *, int, size_t);
48 
49 extern char*  strrchr(const char *, int) __purefunc;
50 extern char* __strrchr_chk(const char *, int, size_t);
51 
52 extern size_t strlen(const char *) __purefunc;
53 extern size_t __strlen_chk(const char *, size_t);
54 extern int    strcmp(const char *, const char *) __purefunc;
55 extern char*  stpcpy(char* __restrict, const char* __restrict);
56 extern char*  strcpy(char* __restrict, const char* __restrict);
57 extern char*  strcat(char* __restrict, const char* __restrict);
58 
59 extern int    strcasecmp(const char *, const char *) __purefunc;
60 extern int    strncasecmp(const char *, const char *, size_t) __purefunc;
61 extern char*  strdup(const char *);
62 
63 extern char*  strstr(const char *, const char *) __purefunc;
64 extern char*  strcasestr(const char *haystack, const char *needle) __purefunc;
65 extern char*  strtok(char* __restrict, const char* __restrict);
66 extern char*  strtok_r(char* __restrict, const char* __restrict, char** __restrict);
67 
68 extern char*  strerror(int);
69 extern int    strerror_r(int errnum, char *buf, size_t n);
70 
71 extern size_t strnlen(const char *, size_t) __purefunc;
72 extern char*  strncat(char* __restrict, const char* __restrict, size_t);
73 extern char*  strndup(const char *, size_t);
74 extern int    strncmp(const char *, const char *, size_t) __purefunc;
75 extern char*  stpncpy(char* __restrict, const char* __restrict, size_t);
76 extern char*  strncpy(char* __restrict, const char* __restrict, size_t);
77 
78 extern size_t strlcat(char* __restrict, const char* __restrict, size_t);
79 extern size_t strlcpy(char* __restrict, const char* __restrict, size_t);
80 
81 extern size_t strcspn(const char *, const char *) __purefunc;
82 extern char*  strpbrk(const char *, const char *) __purefunc;
83 extern char*  strsep(char** __restrict, const char* __restrict);
84 extern size_t strspn(const char *, const char *);
85 
86 extern char*  strsignal(int  sig);
87 
88 extern int    strcoll(const char *, const char *) __purefunc;
89 extern 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
memcpy(void * __restrict dest,const void * __restrict src,size_t copy_amount)97 void* 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
memmove(void * dest,const void * src,size_t len)115 void* 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
stpcpy(char * __restrict dest,const char * __restrict src)120 char* stpcpy(char* __restrict dest, const char* __restrict src) {
121     return __builtin___stpcpy_chk(dest, src, __bos(dest));
122 }
123 
124 __BIONIC_FORTIFY_INLINE
strcpy(char * __restrict dest,const char * __restrict src)125 char* 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");
130 extern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
131 
132 __BIONIC_FORTIFY_INLINE
stpncpy(char * __restrict dest,const char * __restrict src,size_t n)133 char* 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");
157 extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
158 
159 __BIONIC_FORTIFY_INLINE
strncpy(char * __restrict dest,const char * __restrict src,size_t n)160 char* 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
strcat(char * __restrict dest,const char * __restrict src)184 char* strcat(char* __restrict dest, const char* __restrict src) {
185     return __builtin___strcat_chk(dest, src, __bos(dest));
186 }
187 
188 __BIONIC_FORTIFY_INLINE
strncat(char * __restrict dest,const char * __restrict src,size_t n)189 char *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
memset(void * s,int c,size_t n)194 void* memset(void *s, int c, size_t n) {
195     return __builtin___memset_chk(s, c, n, __bos0(s));
196 }
197 
198 extern 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");
201 extern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
202 
203 __BIONIC_FORTIFY_INLINE
strlcpy(char * __restrict dest,const char * __restrict src,size_t size)204 size_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 
229 extern 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");
232 extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t);
233 
234 
235 __BIONIC_FORTIFY_INLINE
strlcat(char * __restrict dest,const char * __restrict src,size_t size)236 size_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
strlen(const char * s)262 size_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
strchr(const char * s,int c)281 char* 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
strrchr(const char * s,int c)300 char* 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