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