1 | /* Copyright (C) 2004-2016 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2.1 of the License, or (at your option) any later version. |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ |
17 | |
18 | #ifndef _STRING_H |
19 | # error "Never use <bits/string3.h> directly; include <string.h> instead." |
20 | #endif |
21 | |
22 | #if !__GNUC_PREREQ (5,0) |
23 | __warndecl (__warn_memset_zero_len, |
24 | "memset used with constant zero length parameter; this could be due to transposed parameters" ); |
25 | #endif |
26 | |
27 | #ifndef __cplusplus |
28 | /* XXX This is temporarily. We should not redefine any of the symbols |
29 | and instead integrate the error checking into the original |
30 | definitions. */ |
31 | # undef memcpy |
32 | # undef memmove |
33 | # undef memset |
34 | # undef strcat |
35 | # undef strcpy |
36 | # undef strncat |
37 | # undef strncpy |
38 | # ifdef __USE_GNU |
39 | # undef mempcpy |
40 | # undef stpcpy |
41 | # endif |
42 | # ifdef __USE_MISC |
43 | # undef bcopy |
44 | # undef bzero |
45 | # endif |
46 | #endif |
47 | |
48 | |
49 | __fortify_function void * |
50 | __NTH (memcpy (void *__restrict __dest, const void *__restrict __src, |
51 | size_t __len)) |
52 | { |
53 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); |
54 | } |
55 | |
56 | __fortify_function void * |
57 | __NTH (memmove (void *__dest, const void *__src, size_t __len)) |
58 | { |
59 | return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest)); |
60 | } |
61 | |
62 | #ifdef __USE_GNU |
63 | __fortify_function void * |
64 | __NTH (mempcpy (void *__restrict __dest, const void *__restrict __src, |
65 | size_t __len)) |
66 | { |
67 | return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest)); |
68 | } |
69 | #endif |
70 | |
71 | |
72 | /* The first two tests here help to catch a somewhat common problem |
73 | where the second and third parameter are transposed. This is |
74 | especially problematic if the intended fill value is zero. In this |
75 | case no work is done at all. We detect these problems by referring |
76 | non-existing functions. */ |
77 | __fortify_function void * |
78 | __NTH (memset (void *__dest, int __ch, size_t __len)) |
79 | { |
80 | /* GCC-5.0 and newer implements these checks in the compiler, so we don't |
81 | need them here. */ |
82 | #if !__GNUC_PREREQ (5,0) |
83 | if (__builtin_constant_p (__len) && __len == 0 |
84 | && (!__builtin_constant_p (__ch) || __ch != 0)) |
85 | { |
86 | __warn_memset_zero_len (); |
87 | return __dest; |
88 | } |
89 | #endif |
90 | return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest)); |
91 | } |
92 | |
93 | #ifdef __USE_MISC |
94 | __fortify_function void |
95 | __NTH (bcopy (const void *__src, void *__dest, size_t __len)) |
96 | { |
97 | (void) __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest)); |
98 | } |
99 | |
100 | __fortify_function void |
101 | __NTH (bzero (void *__dest, size_t __len)) |
102 | { |
103 | (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest)); |
104 | } |
105 | #endif |
106 | |
107 | __fortify_function char * |
108 | __NTH (strcpy (char *__restrict __dest, const char *__restrict __src)) |
109 | { |
110 | return __builtin___strcpy_chk (__dest, __src, __bos (__dest)); |
111 | } |
112 | |
113 | #ifdef __USE_GNU |
114 | __fortify_function char * |
115 | __NTH (stpcpy (char *__restrict __dest, const char *__restrict __src)) |
116 | { |
117 | return __builtin___stpcpy_chk (__dest, __src, __bos (__dest)); |
118 | } |
119 | #endif |
120 | |
121 | |
122 | __fortify_function char * |
123 | __NTH (strncpy (char *__restrict __dest, const char *__restrict __src, |
124 | size_t __len)) |
125 | { |
126 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); |
127 | } |
128 | |
129 | // XXX We have no corresponding builtin yet. |
130 | extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, |
131 | size_t __destlen) __THROW; |
132 | extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src, |
133 | size_t __n), stpncpy); |
134 | |
135 | __fortify_function char * |
136 | __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) |
137 | { |
138 | if (__bos (__dest) != (size_t) -1 |
139 | && (!__builtin_constant_p (__n) || __n > __bos (__dest))) |
140 | return __stpncpy_chk (__dest, __src, __n, __bos (__dest)); |
141 | return __stpncpy_alias (__dest, __src, __n); |
142 | } |
143 | |
144 | |
145 | __fortify_function char * |
146 | __NTH (strcat (char *__restrict __dest, const char *__restrict __src)) |
147 | { |
148 | return __builtin___strcat_chk (__dest, __src, __bos (__dest)); |
149 | } |
150 | |
151 | |
152 | __fortify_function char * |
153 | __NTH (strncat (char *__restrict __dest, const char *__restrict __src, |
154 | size_t __len)) |
155 | { |
156 | return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest)); |
157 | } |
158 | |