Added
Link Here
|
1 |
/*- |
2 |
* Copyright (c) 2015 Olivér Pintér |
3 |
* Copyright (C) 2008 The Android Open Source Project |
4 |
* All rights reserved. |
5 |
* |
6 |
* Redistribution and use in source and binary forms, with or without |
7 |
* modification, are permitted provided that the following conditions |
8 |
* are met: |
9 |
* * Redistributions of source code must retain the above copyright |
10 |
* notice, this list of conditions and the following disclaimer. |
11 |
* * Redistributions in binary form must reproduce the above copyright |
12 |
* notice, this list of conditions and the following disclaimer in |
13 |
* the documentation and/or other materials provided with the |
14 |
* distribution. |
15 |
* |
16 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
19 |
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
20 |
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
21 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
22 |
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
23 |
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
24 |
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
25 |
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
26 |
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 |
* SUCH DAMAGE. |
28 |
* |
29 |
* bionic rev: 9ef26a3c4cd2e6d469f771815a07cb820800beb6 |
30 |
* |
31 |
* $FreeBSD$ |
32 |
*/ |
33 |
|
34 |
#ifndef _STRING_H_ |
35 |
#error "You should not use <secure/_string.h> directly; include <string.h> instead." |
36 |
#endif |
37 |
|
38 |
#ifndef _SECURE_STRING_H_ |
39 |
#define _SECURE_STRING_H_ |
40 |
|
41 |
#include <secure/security.h> |
42 |
|
43 |
__BEGIN_DECLS |
44 |
|
45 |
extern void *__memccpy_chk(void *, const void *, int, size_t, size_t); |
46 |
extern void *__memccpy_real(void *, const void *, int, size_t) __RENAME(memccpy); |
47 |
extern void *__memchr_chk(const void *, int, size_t, size_t); |
48 |
extern void *__memchr_real(const void *, int, size_t) __RENAME(memchr); |
49 |
extern void *__memcpy_chk(void *, const void *, size_t, size_t); |
50 |
extern void *__memcpy_real(void *, const void *, size_t) __RENAME(memcpy); |
51 |
__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer"); |
52 |
extern void *__memmove_chk(void *, const void *, size_t, size_t); |
53 |
extern void *__memmove_real(void *, const void *, size_t) __RENAME(memmove); |
54 |
extern void *__memrchr_chk(const void *, int, size_t, size_t); |
55 |
extern void *__memrchr_real(const void *, int, size_t) __RENAME(memrchr); |
56 |
__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer"); |
57 |
extern void *__memset_chk(void *, int, size_t, size_t); |
58 |
extern void *__memset_real(void *, int, size_t) __RENAME(memset); |
59 |
extern char *__strcat_chk(char *__restrict, const char *__restrict, size_t); |
60 |
extern char *__strcat_real(char *__restrict, const char *__restrict) __RENAME(strcat); |
61 |
extern char *__strncat_chk(char *__restrict, const char *__restrict, size_t, size_t); |
62 |
extern char *__strncat_real(char *__restrict, const char *__restrict, size_t) __RENAME(strncat); |
63 |
extern char *__stpcpy_chk(char *, const char *, size_t); |
64 |
extern char *__stpcpy_real(char *, const char *) __RENAME(stpcpy); |
65 |
extern char *__stpncpy_chk(char * __restrict, const char * __restrict, size_t, size_t); |
66 |
extern char *__stpncpy_chk2(char * __restrict, const char * __restrict, size_t, size_t, size_t); |
67 |
extern char *__stpncpy_real(char * __restrict, const char * __restrict, size_t) __RENAME(stpncpy); |
68 |
extern char *__strcpy_chk(char *, const char *, size_t); |
69 |
extern char *__strcpy_real(char *, const char *) __RENAME(strcpy); |
70 |
extern char *__strncpy_chk(char *, const char *, size_t, size_t); |
71 |
extern char *__strncpy_chk2(char * __restrict, const char * __restrict, size_t, size_t, size_t); |
72 |
extern char *__strncpy_real(char *, const char *, size_t) __RENAME(strncpy); |
73 |
extern size_t __strlcpy_chk(char *, const char *, size_t, size_t); |
74 |
extern size_t __strlcpy_real(char * __restrict, const char * __restrict, size_t) __RENAME(strlcpy); |
75 |
extern size_t __strlcat_chk(char * __restrict, const char * __restrict, size_t, size_t); |
76 |
extern size_t __strlcat_real(char * __restrict, const char * __restrict, size_t) __RENAME(strlcat); |
77 |
extern size_t __strlen_chk(const char *, size_t); |
78 |
extern size_t __strlen_real(const char *) __RENAME(strlen); |
79 |
extern char *__strchr_chk(const char *, int, size_t); |
80 |
extern char *__strchr_real(const char *, int) __RENAME(strchr); |
81 |
extern char *__strchrnul_chk(const char *, int, size_t); |
82 |
extern char *__strchrnul_real(const char *, int) __RENAME(strchrnul); |
83 |
extern char *__strrchr_chk(const char *, int, size_t); |
84 |
extern char *__strrchr_real(const char *, int) __RENAME(strrchr); |
85 |
|
86 |
#ifdef __BSD_FORTIFY |
87 |
|
88 |
#if __XSI_VISIBLE >= 600 |
89 |
__FORTIFY_INLINE void * |
90 |
memccpy(void * __restrict _d, const void * __restrict _s, int _c, size_t _n) |
91 |
{ |
92 |
size_t _bos = __bos0(_d); |
93 |
|
94 |
#ifndef __clang__ |
95 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
96 |
return (__memccpy_real(_d, _s, _c, _n)); |
97 |
#endif |
98 |
|
99 |
return (__memccpy_chk(_d, _s, _c, _n, _bos)); |
100 |
} |
101 |
#endif /* __XSI_VISIBLE */ |
102 |
|
103 |
|
104 |
__FORTIFY_INLINE void * |
105 |
memchr(const void *_s, int _c, size_t _n) |
106 |
{ |
107 |
size_t _bos = __bos(_s); |
108 |
|
109 |
#ifndef __clang__ |
110 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
111 |
return (__memchr_real(_s, _c, _n)); |
112 |
|
113 |
if (__builtin_constant_p(_n) && (_n > _bos)) |
114 |
__memchr_buf_size_error(); |
115 |
|
116 |
/* |
117 |
* Compiler can prove, at compile time, that the passed in size |
118 |
* is always <= the actual object size. Don't call __memchr_chk. |
119 |
*/ |
120 |
if (__builtin_constant_p(_n) && (_n <= _bos)) |
121 |
return (__memchr_real(_s, _c, _n)); |
122 |
#endif |
123 |
|
124 |
return (__memchr_chk(_s, _c, _n, _bos)); |
125 |
} |
126 |
|
127 |
|
128 |
#if __BSD_VISIBLE |
129 |
__FORTIFY_INLINE void * |
130 |
memrchr(const void *_s, int _c, size_t _n) |
131 |
{ |
132 |
size_t _bos = __bos(_s); |
133 |
|
134 |
#ifndef __clang__ |
135 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
136 |
return (__memrchr_real(_s, _c, _n)); |
137 |
|
138 |
if (__builtin_constant_p(_n) && (_n > _bos)) |
139 |
(__memrchr_buf_size_error()); |
140 |
|
141 |
if (__builtin_constant_p(_n) && (_n <= _bos)) |
142 |
return __memrchr_real(_s, _c, _n); |
143 |
#endif |
144 |
|
145 |
return (__memrchr_chk(_s, _c, _n, _bos)); |
146 |
} |
147 |
#endif /* __BSD_VISIBLE */ |
148 |
|
149 |
|
150 |
__FORTIFY_INLINE void * |
151 |
memcpy(void * __restrict _d, const void * __restrict _s, size_t _n) |
152 |
{ |
153 |
size_t _bos = __bos0(_d); |
154 |
|
155 |
#ifndef __clang__ |
156 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
157 |
return (__memcpy_real(_d, _s, _n)); |
158 |
#endif |
159 |
|
160 |
return (__memcpy_chk(_d, _s, _n, _bos)); |
161 |
} |
162 |
|
163 |
|
164 |
__FORTIFY_INLINE void * |
165 |
memmove(void *_d, const void *_s, size_t _n) |
166 |
{ |
167 |
size_t _bos = __bos0(_d); |
168 |
|
169 |
#ifndef __clang__ |
170 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
171 |
return (__memmove_real(_d, _s, _n)); |
172 |
#endif |
173 |
|
174 |
return (__memmove_chk(_d, _s, _n, _bos)); |
175 |
} |
176 |
|
177 |
|
178 |
#if __POSIX_VISIBLE >= 200809 |
179 |
__FORTIFY_INLINE char * |
180 |
stpcpy(char * __restrict _d, const char * __restrict _s) |
181 |
{ |
182 |
size_t _bos = __bos(_d); |
183 |
|
184 |
#ifndef __clang__ |
185 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
186 |
return (__stpcpy_real(_d, _s)); |
187 |
#endif |
188 |
|
189 |
return (__stpcpy_chk(_d, _s, _bos)); |
190 |
} |
191 |
#endif /* __POSIX_VISIBLE */ |
192 |
|
193 |
|
194 |
__FORTIFY_INLINE char * |
195 |
strcpy(char * __restrict _d, const char * __restrict _s) |
196 |
{ |
197 |
size_t _bos = __bos(_d); |
198 |
|
199 |
#ifndef __clang__ |
200 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
201 |
return (__strcpy_real(_d, _s)); |
202 |
#endif |
203 |
|
204 |
return (__strcpy_chk(_d, _s, _bos)); |
205 |
} |
206 |
|
207 |
|
208 |
#if __POSIX_VISIBLE >= 200809 |
209 |
__FORTIFY_INLINE char * |
210 |
stpncpy(char * __restrict _d, const char * __restrict _s, size_t _n) |
211 |
{ |
212 |
size_t _d_bos = __bos(_d); |
213 |
size_t _s_bos = __bos(_s); |
214 |
#ifndef __clang__ |
215 |
size_t _slen; |
216 |
|
217 |
if (_d_bos == __FORTIFY_UNKNOWN_SIZE) |
218 |
return (__stpncpy_real(_d, _s, _n)); |
219 |
|
220 |
if (_s_bos == __FORTIFY_UNKNOWN_SIZE) |
221 |
return (__stpncpy_chk(_d, _s, _n, _d_bos)); |
222 |
|
223 |
if (__builtin_constant_p(_n) && (_n <= _s_bos)) |
224 |
return (__stpncpy_chk(_d, _s, _n, _d_bos)); |
225 |
|
226 |
_slen = __builtin_strlen(_s); |
227 |
if (__builtin_constant_p(_slen)) |
228 |
return (__stpncpy_chk(_d, _s, _n, _d_bos)); |
229 |
#endif |
230 |
|
231 |
return (__stpncpy_chk2(_d, _s, _n, _d_bos, _s_bos)); |
232 |
} |
233 |
#endif /* __POSIX_VISIBLE */ |
234 |
|
235 |
|
236 |
__FORTIFY_INLINE char * |
237 |
strncpy(char * __restrict _d, const char * __restrict _s, size_t _n) |
238 |
{ |
239 |
size_t _d_bos = __bos(_d); |
240 |
size_t _s_bos = __bos(_s); |
241 |
#ifndef __clang__ |
242 |
size_t _slen; |
243 |
|
244 |
if (_d_bos == __FORTIFY_UNKNOWN_SIZE) |
245 |
return (__strncpy_real(_d, _s, _n)); |
246 |
|
247 |
if (_s_bos == __FORTIFY_UNKNOWN_SIZE) |
248 |
return (__strncpy_chk(_d, _s, _n, _d_bos)); |
249 |
|
250 |
if (__builtin_constant_p(_n) && (_n <= _s_bos)) |
251 |
return (__strncpy_chk(_d, _s, _n, _d_bos)); |
252 |
|
253 |
_slen = __builtin_strlen(_s); |
254 |
if (__builtin_constant_p(_slen)) |
255 |
return (__strncpy_chk(_d, _s, _n, _d_bos)); |
256 |
#endif |
257 |
|
258 |
return (__strncpy_chk2(_d, _s, _n, _d_bos, _s_bos)); |
259 |
} |
260 |
|
261 |
|
262 |
__FORTIFY_INLINE char * |
263 |
strcat(char * __restrict _d, const char * __restrict _s) |
264 |
{ |
265 |
size_t _bos = __bos(_d); |
266 |
|
267 |
#ifndef __clang__ |
268 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
269 |
return (__strcat_real(_d, _s)); |
270 |
#endif |
271 |
|
272 |
return (__strcat_chk(_d, _s, _bos)); |
273 |
} |
274 |
|
275 |
|
276 |
__FORTIFY_INLINE char * |
277 |
strncat(char * __restrict _d, const char * __restrict _s, size_t _n) |
278 |
{ |
279 |
size_t _bos = __bos(_d); |
280 |
|
281 |
#ifndef __clang__ |
282 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
283 |
return (__strncat_real(_d, _s, _n)); |
284 |
#endif |
285 |
|
286 |
return (__strncat_chk(_d, _s, _n, _bos)); |
287 |
} |
288 |
|
289 |
|
290 |
__FORTIFY_INLINE void * |
291 |
memset(void *_s, int _c, size_t _n) |
292 |
{ |
293 |
size_t _bos = __bos(_s); |
294 |
|
295 |
#ifndef __clang__ |
296 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
297 |
return (__memset_real(_s, _c, _n)); |
298 |
#endif |
299 |
|
300 |
return (__memset_chk(_s, _c, _n, _bos)); |
301 |
} |
302 |
|
303 |
|
304 |
#if __BSD_VISIBLE |
305 |
__FORTIFY_INLINE size_t |
306 |
strlcpy(char * __restrict _d, const char * __restrict _s, size_t _n) |
307 |
{ |
308 |
size_t _bos = __bos(_d); |
309 |
|
310 |
#ifndef __clang__ |
311 |
/* Compiler doesn't know destination size. Don't call __strlcpy_chk. */ |
312 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
313 |
return (__strlcpy_real(_d, _s, _n)); |
314 |
|
315 |
/* |
316 |
* Compiler can prove, at compile time, that the passed in size |
317 |
* is always <= the actual object size. Don't call __strlcpy_chk. |
318 |
*/ |
319 |
if (__builtin_constant_p(_n) && (_n <= _bos)) |
320 |
return (__strlcpy_real(_d, _s, _n)); |
321 |
#endif |
322 |
|
323 |
return (__strlcpy_chk(_d, _s, _n, _bos)); |
324 |
} |
325 |
#endif /* __BSD_VISIBLE */ |
326 |
|
327 |
|
328 |
#if __BSD_VISIBLE |
329 |
__FORTIFY_INLINE size_t |
330 |
strlcat(char * __restrict _d, const char * __restrict _s, size_t _n) |
331 |
{ |
332 |
size_t _bos = __bos(_d); |
333 |
|
334 |
#ifndef __clang__ |
335 |
/* Compiler doesn't know destination size. Don't call __strlcat_chk. */ |
336 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
337 |
return (__strlcat_real(_d, _s, _n)); |
338 |
|
339 |
/* |
340 |
* Compiler can prove, at compile time, that the passed in size |
341 |
* is always <= the actual object size. Don't call __strlcat_chk. |
342 |
*/ |
343 |
if (__builtin_constant_p(_n) && (_n <= _bos)) |
344 |
return (__strlcat_real(_d, _s, _n)); |
345 |
#endif |
346 |
|
347 |
return (__strlcat_chk(_d, _s, _n, _bos)); |
348 |
} |
349 |
#endif /* __BSD_VISIBLE */ |
350 |
|
351 |
|
352 |
__FORTIFY_INLINE size_t |
353 |
strlen(const char *_s) |
354 |
{ |
355 |
size_t _bos = __bos(_s); |
356 |
#ifndef __clang__ |
357 |
size_t _slen; |
358 |
|
359 |
/* Compiler doesn't know destination size. Don't call __strlen_chk. */ |
360 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
361 |
return (__strlen_real(_s)); |
362 |
|
363 |
_slen = __builtin_strlen(_s); |
364 |
if (__builtin_constant_p(_slen)) |
365 |
return (_slen); |
366 |
#endif |
367 |
|
368 |
return (__strlen_chk(_s, _bos)); |
369 |
} |
370 |
|
371 |
__FORTIFY_INLINE char * |
372 |
strchr(const char *_s, int _c) |
373 |
{ |
374 |
size_t _bos = __bos(_s); |
375 |
#ifndef __clang__ |
376 |
size_t _slen; |
377 |
|
378 |
/* Compiler doesn't know destination size. Don't call __strchr_chk. */ |
379 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
380 |
return (__strchr_real(_s, _c)); |
381 |
|
382 |
/* |
383 |
* Compiler can prove, at compile time, that the passed in size |
384 |
* is always <= the actual object size. Don't call __strlchr_chk. |
385 |
*/ |
386 |
_slen = __builtin_strlen(_s); |
387 |
if (__builtin_constant_p(_slen) && (_slen < _bos)) |
388 |
return (__strchr_real(_s, _c)); |
389 |
#endif |
390 |
|
391 |
return (__strchr_chk(_s, _c, _bos)); |
392 |
} |
393 |
|
394 |
|
395 |
#if __BSD_VISIBLE |
396 |
__FORTIFY_INLINE char * |
397 |
strchrnul(const char *_s, int _c) |
398 |
{ |
399 |
size_t _bos = __bos(_s); |
400 |
#ifndef __clang__ |
401 |
size_t _slen; |
402 |
|
403 |
/* Compiler doesn't know destination size. Don't call __strchr_chk. */ |
404 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
405 |
return (__strchrnul_real(_s, _c)); |
406 |
/* |
407 |
* Compiler can prove, at compile time, that the passed in size |
408 |
* is always <= the actual object size. Don't call __strlchrnul_chk. |
409 |
*/ |
410 |
_slen = __builtin_strlen(_s); |
411 |
if (__builtin_constant_p(_slen) && (_slen < _bos)) |
412 |
return (__strchrnul_real(_s, _c)); |
413 |
#endif |
414 |
|
415 |
return (__strchrnul_chk(_s, _c, _bos)); |
416 |
} |
417 |
#endif |
418 |
|
419 |
|
420 |
__FORTIFY_INLINE char * |
421 |
strrchr(const char *_s, int _c) |
422 |
{ |
423 |
size_t _bos = __bos(_s); |
424 |
#ifndef __clang__ |
425 |
size_t _slen; |
426 |
|
427 |
/* Compiler doesn't know destination size. Don't call __strrchr_chk. */ |
428 |
if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) |
429 |
return (__strrchr_real(_s, _c)); |
430 |
|
431 |
/* |
432 |
* Compiler can prove, at compile time, that the passed in size |
433 |
* is always <= the actual object size. Don't call __strlen_chk. |
434 |
*/ |
435 |
_slen = __strlen_real(_s); |
436 |
if (__builtin_constant_p(_slen) && (_slen < _bos)) |
437 |
return (__strrchr_real(_s, _c)); |
438 |
#endif |
439 |
|
440 |
return (__strrchr_chk(_s, _c, _bos)); |
441 |
} |
442 |
|
443 |
|
444 |
#endif /* defined(__BSD_FORTIFY) */ |
445 |
|
446 |
__END_DECLS |
447 |
|
448 |
#endif /* !_SECURE_STRING_H */ |