Line data Source code
1 : /*
2 : * Copyright (C) 2015-2017 Dimitris Papastamos <sin@2f30.org>
3 : * Copyright (C) 2022 q66 <q66@chimera-linux.org>
4 : *
5 : * Permission to use, copy, modify, and/or distribute this software for any
6 : * purpose with or without fee is hereby granted.
7 : *
8 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : */
16 :
17 : #ifndef _FORTIFY_WCHAR_H
18 : #define _FORTIFY_WCHAR_H
19 :
20 : #if !defined(__cplusplus) && !defined(__clang__)
21 : __extension__
22 : #endif
23 : #include_next <wchar.h>
24 :
25 : #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
26 : #include "fortify-headers.h"
27 :
28 : #ifdef __cplusplus
29 : extern "C" {
30 : #endif
31 :
32 : #undef fgetws
33 : #undef mbsrtowcs
34 : #undef wcrtomb
35 : #undef wcscat
36 : #undef wcscpy
37 : #undef wcsncat
38 : #undef wcsncpy
39 : #undef wcsrtombs
40 : #undef wmemcpy
41 : #undef wmemmove
42 : #undef wmemset
43 :
44 : #if __has_builtin(__builtin_fgetws)
45 : __diagnose_as_builtin(__builtin_fgetws, 1, 2, 3)
46 : #endif
47 : _FORTIFY_FN(fgetws) wchar_t *fgetws(wchar_t * _FORTIFY_POS0 __s,
48 : int __n, FILE *__f)
49 : {
50 : __fh_size_t __b = __fh_bos(__s, 0);
51 :
52 1 : if ((__fh_size_t)__n > __b / sizeof(wchar_t))
53 2 : __builtin_trap();
54 0 : return __orig_fgetws(__s, __n, __f);
55 : }
56 :
57 : #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
58 : || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
59 : #undef mbsnrtowcs
60 : #if __has_builtin(__builtin_mbsnrtowcs)
61 : __diagnose_as_builtin(__builtin_mbsnrtowcs, 1, 2, 3, 4, 5)
62 : #endif
63 : _FORTIFY_FN(mbsnrtowcs) size_t mbsnrtowcs(wchar_t * _FORTIFY_POS0 __d,
64 : const char **__s, size_t __n,
65 : size_t __wn, mbstate_t *__st)
66 : {
67 : __fh_size_t __b = __fh_bos(__d, 0);
68 : __fh_size_t __r;
69 :
70 : if (__wn > __n / sizeof(wchar_t)) {
71 : __b /= sizeof(wchar_t);
72 : __r = __orig_mbsnrtowcs(__d, __s, __n, __wn > __b ? __b : __wn, __st);
73 : if (__b < __wn && __d && *__s && __r != (__fh_size_t)-1)
74 : __builtin_trap();
75 : } else {
76 : __r = __orig_mbsnrtowcs(__d, __s, __n > __b ? __b : __n, __wn, __st);
77 : if (__b < __n && __d && *__s && __r != (__fh_size_t)-1)
78 : __builtin_trap();
79 : }
80 : return __r;
81 : }
82 : #endif
83 :
84 : #if __has_builtin(__builtin_mbsrtowcs)
85 : __diagnose_as_builtin(__builtin_mbsrtowcs, 1, 2, 3, 4)
86 : #endif
87 : _FORTIFY_FN(mbsrtowcs) size_t mbsrtowcs(wchar_t * _FORTIFY_POS0 __d,
88 : const char **__s, size_t __wn,
89 : mbstate_t *__st)
90 : {
91 : __fh_size_t __b = __fh_bos(__d, 0);
92 : __fh_size_t __r;
93 :
94 : __b /= sizeof(wchar_t);
95 2 : __r = __orig_mbsrtowcs(__d, __s, __wn > __b ? __b : __wn, __st);
96 2 : if (__b < __wn && __d && *__s && __r != (__fh_size_t)-1)
97 0 : __builtin_trap();
98 : return __r;
99 : }
100 :
101 : /* FIXME clang */
102 : #ifndef __clang__
103 : #if __has_builtin(__builtin_wcrtomb)
104 : __diagnose_as_builtin(__builtin_wcrtomb, 1, 2, 3)
105 : #endif
106 : _FORTIFY_FN(wcrtomb) size_t wcrtomb(char * __s, wchar_t __w, mbstate_t *__st)
107 : {
108 : // In glibc, MB_LEN_MAX is typically 16 (6 in glibc versions earlier than 2.2)
109 : if (__s && 16 > __fh_bos(__s, 2)) {
110 : char __buf[16];
111 : __fh_size_t __r;
112 :
113 : __r = __orig_wcrtomb(__buf, __w, __st);
114 : if (__r == (__fh_size_t)-1)
115 : return __r;
116 : if (__r > __fh_bos(__s, 0))
117 : __builtin_trap();
118 : __builtin_memcpy(__s, __buf, __r);
119 : return __r;
120 : }
121 : return __orig_wcrtomb(__s, __w, __st);
122 : }
123 : #endif
124 :
125 : #if __has_builtin(__builtin_wcscat)
126 : __diagnose_as_builtin(__builtin_wcscat, 1, 2)
127 : #endif
128 : _FORTIFY_FN(wcscat) wchar_t *wcscat(wchar_t * _FORTIFY_POS0 __d,
129 : const wchar_t *__s)
130 : {
131 : __fh_size_t __b = __fh_bos(__d, 0);
132 :
133 2 : if (wcslen(__s) + wcslen(__d) + 1 > __b / sizeof(wchar_t))
134 1 : __builtin_trap();
135 1 : return __orig_wcscat(__d, __s);
136 : }
137 :
138 : #if __has_builtin(__builtin_wcscpy)
139 : __diagnose_as_builtin(__builtin_wcscpy, 1, 2)
140 : #endif
141 : _FORTIFY_FN(wcscpy) wchar_t *wcscpy(wchar_t * _FORTIFY_POS0 __d,
142 : const wchar_t *__s)
143 : {
144 : __fh_size_t __b = __fh_bos(__d, 0);
145 :
146 2 : if (wcslen(__s) + 1 > __b / sizeof(wchar_t))
147 1 : __builtin_trap();
148 1 : return __orig_wcscpy(__d, __s);
149 : }
150 :
151 : #if __has_builtin(__builtin_wcsncat)
152 : __diagnose_as_builtin(__builtin_wcsncat, 1, 2, 3)
153 : #endif
154 : _FORTIFY_FN(wcsncat) wchar_t *wcsncat(wchar_t * _FORTIFY_POS0 __d,
155 : const wchar_t *__s, size_t __n)
156 : {
157 : __fh_size_t __b = __fh_bos(__d, 0);
158 : __fh_size_t __sl, __dl;
159 :
160 : if (__n > __b / sizeof(wchar_t)) {
161 1 : __sl = wcslen(__s);
162 1 : __dl = wcslen(__d);
163 : if (__sl > __n)
164 : __sl = __n;
165 1 : if (__sl + __dl + 1 > __b / sizeof(wchar_t))
166 1 : __builtin_trap();
167 : }
168 1 : return __orig_wcsncat(__d, __s, __n);
169 : }
170 :
171 : #if __has_builtin(__builtin_wcsncpy)
172 : __diagnose_as_builtin(__builtin_wcsncpy, 1, 2, 3)
173 : #endif
174 : _FORTIFY_FN(wcsncpy) wchar_t *wcsncpy(wchar_t * _FORTIFY_POS0 __d,
175 : const wchar_t *__s, size_t __n)
176 : {
177 : __fh_size_t __b = __fh_bos(__d, 0);
178 :
179 : if (__n > __b / sizeof(wchar_t))
180 1 : __builtin_trap();
181 1 : return __orig_wcsncpy(__d, __s, __n);
182 : }
183 :
184 : #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
185 : || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
186 : #undef wcsnrtombs
187 : #if __has_builtin(__builtin_wcsnrtombs)
188 : __diagnose_as_builtin(__builtin_wcsnrtombs, 1, 2, 3, 4, 5)
189 : #endif
190 : _FORTIFY_FN(wcsnrtombs) size_t wcsnrtombs(char * _FORTIFY_POS0 __d,
191 : const wchar_t **__s, size_t __wn,
192 : size_t __n, mbstate_t *__st)
193 : {
194 : __fh_size_t __b = __fh_bos(__d, 0);
195 : __fh_size_t __r;
196 :
197 : if (__wn > __n / sizeof(wchar_t)) {
198 : __b /= sizeof(wchar_t);
199 : __r = __orig_wcsnrtombs(__d, __s, __wn > __b ? __b : __wn, __n, __st);
200 : if (__b < __wn && __d && *__s && __r != (__fh_size_t)-1)
201 : __builtin_trap();
202 : } else {
203 : __r = __orig_wcsnrtombs(__d, __s, __wn, __n > __b ? __b : __n, __st);
204 : if (__b < __n && __d && *__s && __r != (__fh_size_t)-1)
205 : __builtin_trap();
206 : }
207 : return __r;
208 : }
209 : #endif
210 :
211 : #if __has_builtin(__builtin_wcsrtombs)
212 : __diagnose_as_builtin(__builtin_wcsrtombs, 1, 2, 3, 4)
213 : #endif
214 : _FORTIFY_FN(wcsrtombs) size_t wcsrtombs(char * _FORTIFY_POS0 __d,
215 : const wchar_t **__s, size_t __n,
216 : mbstate_t *__st)
217 : {
218 : __fh_size_t __b = __fh_bos(__d, 0);
219 : __fh_size_t __r;
220 :
221 : __r = __orig_wcsrtombs(__d, __s, __n > __b ? __b : __n, __st);
222 : if (__b < __n && __d && *__s && __r != (__fh_size_t)-1)
223 : __builtin_trap();
224 : return __r;
225 : }
226 :
227 : #if __has_builtin(__builtin_wmemcpy)
228 : __diagnose_as_builtin(__builtin_wmemcpy, 1, 2, 3)
229 : #endif
230 : _FORTIFY_FN(wmemcpy) wchar_t *wmemcpy(wchar_t * _FORTIFY_POS0 __d,
231 : const wchar_t *__s, size_t __n)
232 : {
233 : __fh_size_t __b = __fh_bos(__d, 0);
234 :
235 1 : if (__n > __b / sizeof(wchar_t))
236 2 : __builtin_trap();
237 2 : return __orig_wmemcpy(__d, __s, __n);
238 : }
239 :
240 : #if __has_builtin(__builtin_wmemmove)
241 : __diagnose_as_builtin(__builtin_wmemmove, 1, 2, 3)
242 : #endif
243 : _FORTIFY_FN(wmemmove) wchar_t *wmemmove(wchar_t * _FORTIFY_POS0 __d,
244 : const wchar_t *__s, size_t __n)
245 : {
246 : __fh_size_t __b = __fh_bos(__d, 0);
247 :
248 1 : if (__n > __b / sizeof(wchar_t))
249 2 : __builtin_trap();
250 2 : return __orig_wmemmove(__d, __s, __n);
251 : }
252 :
253 : #if __has_builtin(__builtin_wmemset)
254 : __diagnose_as_builtin(__builtin_wmemset, 1, 2, 3)
255 : #endif
256 : _FORTIFY_FN(wmemset) wchar_t *wmemset(wchar_t * _FORTIFY_POS0 __s,
257 : wchar_t __c, size_t __n)
258 : {
259 : __fh_size_t __b = __fh_bos(__s, 0);
260 :
261 1 : if (__n > __b / sizeof(wchar_t))
262 2 : __builtin_trap();
263 2 : return __orig_wmemset(__s, __c, __n);
264 : }
265 :
266 : #ifdef __cplusplus
267 : }
268 : #endif
269 :
270 : #endif
271 :
272 : #endif
|