]>
Commit | Line | Data |
---|---|---|
8215c9ec | 1 | /* Checking macros for wchar functions. |
dff8da6b | 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. |
8215c9ec UD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
8215c9ec UD |
18 | |
19 | #ifndef _WCHAR_H | |
de1c3ebb | 20 | # error "Never include <bits/wchar2.h> directly; use <wchar.h> instead." |
8215c9ec UD |
21 | #endif |
22 | ||
68444c04 AZ |
23 | __fortify_function __attribute_overloadable__ wchar_t * |
24 | __NTH (wmemcpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __s1), | |
25 | const wchar_t *__restrict __s2, size_t __n)) | |
26 | __fortify_clang_warning_only_if_bos0_lt2 (__n, __s1, sizeof (wchar_t), | |
27 | "wmemcpy called with length bigger " | |
28 | "than size of destination buffer") | |
8215c9ec | 29 | { |
a643f60c SP |
30 | return __glibc_fortify_n (wmemcpy, __n, sizeof (wchar_t), |
31 | __glibc_objsize0 (__s1), | |
32 | __s1, __s2, __n); | |
8215c9ec UD |
33 | } |
34 | ||
68444c04 AZ |
35 | __fortify_function __attribute_overloadable__ wchar_t * |
36 | __NTH (wmemmove (__fortify_clang_overload_arg (wchar_t *, ,__s1), | |
37 | const wchar_t *__s2, size_t __n)) | |
38 | __fortify_clang_warning_only_if_bos0_lt2 (__n, __s1, sizeof (wchar_t), | |
39 | "wmemmove called with length bigger " | |
40 | "than size of destination buffer") | |
8215c9ec | 41 | { |
a643f60c SP |
42 | return __glibc_fortify_n (wmemmove, __n, sizeof (wchar_t), |
43 | __glibc_objsize0 (__s1), | |
44 | __s1, __s2, __n); | |
8215c9ec UD |
45 | } |
46 | ||
8215c9ec | 47 | #ifdef __USE_GNU |
68444c04 AZ |
48 | __fortify_function __attribute_overloadable__ wchar_t * |
49 | __NTH (wmempcpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __s1), | |
50 | const wchar_t *__restrict __s2, size_t __n)) | |
51 | __fortify_clang_warning_only_if_bos0_lt2 (__n, __s1, sizeof (wchar_t), | |
52 | "wmempcpy called with length bigger " | |
53 | "than size of destination buffer") | |
8215c9ec | 54 | { |
a643f60c SP |
55 | return __glibc_fortify_n (wmempcpy, __n, sizeof (wchar_t), |
56 | __glibc_objsize0 (__s1), | |
57 | __s1, __s2, __n); | |
8215c9ec UD |
58 | } |
59 | #endif | |
60 | ||
68444c04 AZ |
61 | __fortify_function __attribute_overloadable__ wchar_t * |
62 | __NTH (wmemset (__fortify_clang_overload_arg (wchar_t *, ,__s), wchar_t __c, | |
63 | size_t __n)) | |
64 | __fortify_clang_warning_only_if_bos0_lt2 (__n, __s, sizeof (wchar_t), | |
65 | "wmemset called with length bigger " | |
66 | "than size of destination buffer") | |
8215c9ec | 67 | { |
a643f60c SP |
68 | return __glibc_fortify_n (wmemset, __n, sizeof (wchar_t), |
69 | __glibc_objsize0 (__s), | |
70 | __s, __c, __n); | |
8215c9ec UD |
71 | } |
72 | ||
68444c04 AZ |
73 | __fortify_function __attribute_overloadable__ wchar_t * |
74 | __NTH (wcscpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
75 | const wchar_t *__restrict __src)) | |
8215c9ec | 76 | { |
a643f60c SP |
77 | size_t sz = __glibc_objsize (__dest); |
78 | if (sz != (size_t) -1) | |
79 | return __wcscpy_chk (__dest, __src, sz / sizeof (wchar_t)); | |
8215c9ec UD |
80 | return __wcscpy_alias (__dest, __src); |
81 | } | |
82 | ||
68444c04 AZ |
83 | __fortify_function __attribute_overloadable__ wchar_t * |
84 | __NTH (wcpcpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
85 | const wchar_t *__restrict __src)) | |
8215c9ec | 86 | { |
a643f60c SP |
87 | size_t sz = __glibc_objsize (__dest); |
88 | if (sz != (size_t) -1) | |
89 | return __wcpcpy_chk (__dest, __src, sz / sizeof (wchar_t)); | |
8215c9ec UD |
90 | return __wcpcpy_alias (__dest, __src); |
91 | } | |
92 | ||
68444c04 AZ |
93 | __fortify_function __attribute_overloadable__ wchar_t * |
94 | __NTH (wcsncpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
95 | const wchar_t *__restrict __src, size_t __n)) | |
96 | __fortify_clang_warning_only_if_bos0_lt2 (__n, __dest, sizeof (wchar_t), | |
97 | "wcsncpy called with length bigger " | |
98 | "than size of destination buffer") | |
8215c9ec | 99 | { |
a643f60c SP |
100 | return __glibc_fortify_n (wcsncpy, __n, sizeof (wchar_t), |
101 | __glibc_objsize (__dest), | |
102 | __dest, __src, __n); | |
8215c9ec UD |
103 | } |
104 | ||
68444c04 AZ |
105 | __fortify_function __attribute_overloadable__ wchar_t * |
106 | __NTH (wcpncpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
107 | const wchar_t *__restrict __src, size_t __n)) | |
108 | __fortify_clang_warning_only_if_bos0_lt2 (__n, __dest, sizeof (wchar_t), | |
109 | "wcpncpy called with length bigger " | |
110 | "than size of destination buffer") | |
8215c9ec | 111 | { |
a643f60c SP |
112 | return __glibc_fortify_n (wcpncpy, __n, sizeof (wchar_t), |
113 | __glibc_objsize (__dest), | |
114 | __dest, __src, __n); | |
8215c9ec UD |
115 | } |
116 | ||
68444c04 AZ |
117 | __fortify_function __attribute_overloadable__ wchar_t * |
118 | __NTH (wcscat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
119 | const wchar_t *__restrict __src)) | |
8215c9ec | 120 | { |
a643f60c SP |
121 | size_t sz = __glibc_objsize (__dest); |
122 | if (sz != (size_t) -1) | |
123 | return __wcscat_chk (__dest, __src, sz / sizeof (wchar_t)); | |
8215c9ec UD |
124 | return __wcscat_alias (__dest, __src); |
125 | } | |
126 | ||
68444c04 AZ |
127 | __fortify_function __attribute_overloadable__ wchar_t * |
128 | __NTH (wcsncat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
129 | const wchar_t *__restrict __src, size_t __n)) | |
8215c9ec | 130 | { |
a643f60c SP |
131 | size_t sz = __glibc_objsize (__dest); |
132 | if (sz != (size_t) -1) | |
133 | return __wcsncat_chk (__dest, __src, __n, sz / sizeof (wchar_t)); | |
8215c9ec UD |
134 | return __wcsncat_alias (__dest, __src, __n); |
135 | } | |
136 | ||
b54e5d1c | 137 | #ifdef __USE_MISC |
68444c04 AZ |
138 | __fortify_function __attribute_overloadable__ size_t |
139 | __NTH (wcslcpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
140 | const wchar_t *__restrict __src, size_t __n)) | |
141 | __fortify_clang_warning_only_if_bos0_lt2 (__n, __dest, sizeof (wchar_t), | |
142 | "wcslcpy called with length bigger " | |
143 | "than size of destination buffer") | |
b54e5d1c FW |
144 | { |
145 | if (__glibc_objsize (__dest) != (size_t) -1 | |
146 | && (!__builtin_constant_p (__n | |
147 | > __glibc_objsize (__dest) / sizeof (wchar_t)) | |
148 | || __n > __glibc_objsize (__dest) / sizeof (wchar_t))) | |
149 | return __wcslcpy_chk (__dest, __src, __n, | |
150 | __glibc_objsize (__dest) / sizeof (wchar_t)); | |
151 | return __wcslcpy_alias (__dest, __src, __n); | |
152 | } | |
153 | ||
68444c04 AZ |
154 | __fortify_function __attribute_overloadable__ size_t |
155 | __NTH (wcslcat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), | |
156 | const wchar_t *__restrict __src, size_t __n)) | |
b54e5d1c FW |
157 | { |
158 | if (__glibc_objsize (__dest) != (size_t) -1 | |
159 | && (!__builtin_constant_p (__n > __glibc_objsize (__dest) | |
160 | / sizeof (wchar_t)) | |
161 | || __n > __glibc_objsize (__dest) / sizeof (wchar_t))) | |
162 | return __wcslcat_chk (__dest, __src, __n, | |
163 | __glibc_objsize (__dest) / sizeof (wchar_t)); | |
164 | return __wcslcat_alias (__dest, __src, __n); | |
165 | } | |
166 | #endif /* __USE_MISC */ | |
8215c9ec | 167 | |
de1c3ebb | 168 | #ifdef __va_arg_pack |
5ac3ea17 | 169 | __fortify_function int |
de1c3ebb | 170 | __NTH (swprintf (wchar_t *__restrict __s, size_t __n, |
a784e502 | 171 | const wchar_t *__restrict __fmt, ...)) |
de1c3ebb | 172 | { |
a643f60c SP |
173 | size_t sz = __glibc_objsize (__s); |
174 | if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) | |
d6cd6bf4 | 175 | return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, |
a643f60c | 176 | sz / sizeof (wchar_t), __fmt, __va_arg_pack ()); |
de1c3ebb UD |
177 | return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ()); |
178 | } | |
68444c04 AZ |
179 | #elif __fortify_use_clang |
180 | __fortify_function_error_function __attribute_overloadable__ int | |
181 | __NTH (swprintf (__fortify_clang_overload_arg (wchar_t *, __restrict, __s), | |
182 | size_t __n, const wchar_t *__restrict __fmt, ...)) | |
183 | { | |
184 | __gnuc_va_list __fortify_ap; | |
185 | __builtin_va_start (__fortify_ap, __fmt); | |
186 | int __r; | |
187 | if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) | |
188 | __r = __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | |
189 | __glibc_objsize (__s) / sizeof (wchar_t), | |
190 | __fmt, __fortify_ap); | |
191 | else | |
192 | __r = __vswprintf_alias (__s, __n, __fmt, __fortify_ap); | |
193 | __builtin_va_end (__fortify_ap); | |
194 | return __r; | |
195 | } | |
de1c3ebb | 196 | #elif !defined __cplusplus |
8215c9ec | 197 | /* XXX We might want to have support in gcc for swprintf. */ |
de1c3ebb | 198 | # define swprintf(s, n, ...) \ |
f9de8bfe | 199 | (__glibc_objsize (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \ |
d6cd6bf4 | 200 | ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, \ |
f9de8bfe | 201 | __glibc_objsize (s) / sizeof (wchar_t), __VA_ARGS__) \ |
757beee1 | 202 | : swprintf (s, n, __VA_ARGS__)) |
de1c3ebb | 203 | #endif |
8215c9ec | 204 | |
5ac3ea17 | 205 | __fortify_function int |
de1c3ebb | 206 | __NTH (vswprintf (wchar_t *__restrict __s, size_t __n, |
a784e502 | 207 | const wchar_t *__restrict __fmt, __gnuc_va_list __ap)) |
de1c3ebb | 208 | { |
a643f60c SP |
209 | size_t sz = __glibc_objsize (__s); |
210 | if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) | |
d6cd6bf4 | 211 | return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, |
a643f60c | 212 | sz / sizeof (wchar_t), __fmt, __ap); |
de1c3ebb UD |
213 | return __vswprintf_alias (__s, __n, __fmt, __ap); |
214 | } | |
8215c9ec UD |
215 | |
216 | ||
217 | #if __USE_FORTIFY_LEVEL > 1 | |
218 | ||
de1c3ebb | 219 | # ifdef __va_arg_pack |
5ac3ea17 | 220 | __fortify_function int |
a784e502 | 221 | wprintf (const wchar_t *__restrict __fmt, ...) |
de1c3ebb UD |
222 | { |
223 | return __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ()); | |
224 | } | |
225 | ||
5ac3ea17 | 226 | __fortify_function int |
a784e502 | 227 | fwprintf (__FILE *__restrict __stream, const wchar_t *__restrict __fmt, ...) |
de1c3ebb UD |
228 | { |
229 | return __fwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, | |
230 | __va_arg_pack ()); | |
231 | } | |
232 | # elif !defined __cplusplus | |
233 | # define wprintf(...) \ | |
8215c9ec | 234 | __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__) |
de1c3ebb | 235 | # define fwprintf(stream, ...) \ |
8215c9ec | 236 | __fwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) |
de1c3ebb UD |
237 | # endif |
238 | ||
5ac3ea17 | 239 | __fortify_function int |
a784e502 | 240 | vwprintf (const wchar_t *__restrict __fmt, __gnuc_va_list __ap) |
de1c3ebb UD |
241 | { |
242 | return __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap); | |
243 | } | |
244 | ||
5ac3ea17 | 245 | __fortify_function int |
de1c3ebb | 246 | vfwprintf (__FILE *__restrict __stream, |
a784e502 | 247 | const wchar_t *__restrict __fmt, __gnuc_va_list __ap) |
de1c3ebb UD |
248 | { |
249 | return __vfwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); | |
250 | } | |
8215c9ec UD |
251 | |
252 | #endif | |
68444c04 AZ |
253 | __fortify_function __attribute_overloadable__ __wur wchar_t * |
254 | fgetws (__fortify_clang_overload_arg (wchar_t *, __restrict, __s), int __n, | |
255 | __FILE *__restrict __stream) | |
256 | __fortify_clang_warning_only_if_bos_lt2 (__n, __s, sizeof (wchar_t), | |
257 | "fgetws called with length bigger " | |
258 | "than size of destination buffer") | |
8215c9ec | 259 | { |
a643f60c SP |
260 | size_t sz = __glibc_objsize (__s); |
261 | if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) | |
262 | return __fgetws_alias (__s, __n, __stream); | |
68444c04 | 263 | #if !__fortify_use_clang |
a643f60c SP |
264 | if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) |
265 | return __fgetws_chk_warn (__s, sz / sizeof (wchar_t), __n, __stream); | |
68444c04 | 266 | #endif |
a643f60c | 267 | return __fgetws_chk (__s, sz / sizeof (wchar_t), __n, __stream); |
8215c9ec UD |
268 | } |
269 | ||
270 | #ifdef __USE_GNU | |
68444c04 AZ |
271 | __fortify_function __attribute_overloadable__ __wur wchar_t * |
272 | fgetws_unlocked (__fortify_clang_overload_arg (wchar_t *, __restrict, __s), | |
273 | int __n, __FILE *__restrict __stream) | |
274 | __fortify_clang_warning_only_if_bos_lt2 (__n, __s, sizeof (wchar_t), | |
275 | "fgetws_unlocked called with length bigger " | |
276 | "than size of destination buffer") | |
8215c9ec | 277 | { |
a643f60c SP |
278 | size_t sz = __glibc_objsize (__s); |
279 | if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) | |
280 | return __fgetws_unlocked_alias (__s, __n, __stream); | |
68444c04 | 281 | # if !__fortify_use_clang |
a643f60c SP |
282 | if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) |
283 | return __fgetws_unlocked_chk_warn (__s, sz / sizeof (wchar_t), __n, | |
284 | __stream); | |
68444c04 | 285 | # endif |
a643f60c | 286 | return __fgetws_unlocked_chk (__s, sz / sizeof (wchar_t), __n, __stream); |
8215c9ec UD |
287 | } |
288 | #endif | |
df6f8969 | 289 | |
68444c04 AZ |
290 | __fortify_function __attribute_overloadable__ __wur size_t |
291 | __NTH (wcrtomb (__fortify_clang_overload_arg (char *, __restrict, __s), | |
292 | wchar_t __wchar, mbstate_t *__restrict __ps)) | |
df6f8969 UD |
293 | { |
294 | /* We would have to include <limits.h> to get a definition of MB_LEN_MAX. | |
295 | But this would only disturb the namespace. So we define our own | |
296 | version here. */ | |
297 | #define __WCHAR_MB_LEN_MAX 16 | |
298 | #if defined MB_LEN_MAX && MB_LEN_MAX != __WCHAR_MB_LEN_MAX | |
299 | # error "Assumed value of MB_LEN_MAX wrong" | |
300 | #endif | |
f9de8bfe SP |
301 | if (__glibc_objsize (__s) != (size_t) -1 |
302 | && __WCHAR_MB_LEN_MAX > __glibc_objsize (__s)) | |
303 | return __wcrtomb_chk (__s, __wchar, __ps, __glibc_objsize (__s)); | |
df6f8969 UD |
304 | return __wcrtomb_alias (__s, __wchar, __ps); |
305 | } | |
306 | ||
68444c04 AZ |
307 | __fortify_function __attribute_overloadable__ size_t |
308 | __NTH (mbsrtowcs (__fortify_clang_overload_arg (wchar_t *, __restrict, __dst), | |
309 | const char **__restrict __src, | |
dc4bb1c2 | 310 | size_t __len, mbstate_t *__restrict __ps)) |
68444c04 AZ |
311 | __fortify_clang_warning_only_if_bos_lt2 (__len, __dst, sizeof (wchar_t), |
312 | "mbsrtowcs called with dst buffer " | |
313 | "smaller than len * sizeof (wchar_t)") | |
df6f8969 | 314 | { |
a643f60c SP |
315 | return __glibc_fortify_n (mbsrtowcs, __len, sizeof (wchar_t), |
316 | __glibc_objsize (__dst), | |
317 | __dst, __src, __len, __ps); | |
df6f8969 UD |
318 | } |
319 | ||
68444c04 AZ |
320 | __fortify_function __attribute_overloadable__ size_t |
321 | __NTH (wcsrtombs (__fortify_clang_overload_arg (char *, __restrict, __dst), | |
322 | const wchar_t **__restrict __src, | |
dc4bb1c2 | 323 | size_t __len, mbstate_t *__restrict __ps)) |
68444c04 AZ |
324 | __fortify_clang_warning_only_if_bos_lt (__len, __dst, |
325 | "wcsrtombs called with dst buffer " | |
326 | "smaller than len") | |
df6f8969 | 327 | { |
a643f60c SP |
328 | return __glibc_fortify (wcsrtombs, __len, sizeof (char), |
329 | __glibc_objsize (__dst), | |
330 | __dst, __src, __len, __ps); | |
df6f8969 UD |
331 | } |
332 | ||
333 | ||
fcfc9086 | 334 | #ifdef __USE_XOPEN2K8 |
68444c04 AZ |
335 | __fortify_function __attribute_overloadable__ size_t |
336 | __NTH (mbsnrtowcs (__fortify_clang_overload_arg (wchar_t *, __restrict, __dst), | |
337 | const char **__restrict __src, size_t __nmc, size_t __len, | |
338 | mbstate_t *__restrict __ps)) | |
339 | __fortify_clang_warning_only_if_bos_lt (sizeof (wchar_t) * __len, __dst, | |
340 | "mbsnrtowcs called with dst buffer " | |
341 | "smaller than len * sizeof (wchar_t)") | |
df6f8969 | 342 | { |
a643f60c SP |
343 | return __glibc_fortify_n (mbsnrtowcs, __len, sizeof (wchar_t), |
344 | __glibc_objsize (__dst), | |
345 | __dst, __src, __nmc, __len, __ps); | |
df6f8969 UD |
346 | } |
347 | ||
68444c04 AZ |
348 | __fortify_function __attribute_overloadable__ size_t |
349 | __NTH (wcsnrtombs (__fortify_clang_overload_arg (char *, __restrict, __dst), | |
350 | const wchar_t **__restrict __src, size_t __nwc, | |
351 | size_t __len, mbstate_t *__restrict __ps)) | |
352 | __fortify_clang_warning_only_if_bos_lt (__len, __dst, | |
353 | "wcsnrtombs called with dst buffer " | |
354 | "smaller than len") | |
df6f8969 | 355 | { |
a643f60c SP |
356 | return __glibc_fortify (wcsnrtombs, __len, sizeof (char), |
357 | __glibc_objsize (__dst), | |
358 | __dst, __src, __nwc, __len, __ps); | |
df6f8969 UD |
359 | } |
360 | #endif |