master
  1/* Checking macros for wchar functions.
  2   Copyright (C) 2005-2025 Free Software Foundation, Inc.
  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
 16   License along with the GNU C Library; if not, see
 17   <https://www.gnu.org/licenses/>.  */
 18
 19#ifndef _WCHAR_H
 20# error "Never include <bits/wchar2.h> directly; use <wchar.h> instead."
 21#endif
 22
 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")
 29{
 30  return __glibc_fortify_n (wmemcpy, __n, sizeof (wchar_t),
 31			    __glibc_objsize0 (__s1),
 32			    __s1, __s2, __n);
 33}
 34
 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")
 41{
 42  return __glibc_fortify_n (wmemmove, __n, sizeof (wchar_t),
 43			    __glibc_objsize0 (__s1),
 44			    __s1, __s2, __n);
 45}
 46
 47#ifdef __USE_GNU
 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")
 54{
 55  return __glibc_fortify_n (wmempcpy, __n, sizeof (wchar_t),
 56			    __glibc_objsize0 (__s1),
 57			    __s1, __s2, __n);
 58}
 59#endif
 60
 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")
 67{
 68  return __glibc_fortify_n (wmemset, __n, sizeof (wchar_t),
 69			    __glibc_objsize0 (__s),
 70			    __s, __c, __n);
 71}
 72
 73__fortify_function __attribute_overloadable__ wchar_t *
 74__NTH (wcscpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest),
 75	       const wchar_t *__restrict __src))
 76{
 77  size_t __sz = __glibc_objsize (__dest);
 78  if (__sz != (size_t) -1)
 79    return __wcscpy_chk (__dest, __src, __sz / sizeof (wchar_t));
 80  return __wcscpy_alias (__dest, __src);
 81}
 82
 83__fortify_function __attribute_overloadable__ wchar_t *
 84__NTH (wcpcpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest),
 85	       const wchar_t *__restrict __src))
 86{
 87  size_t __sz = __glibc_objsize (__dest);
 88  if (__sz != (size_t) -1)
 89    return __wcpcpy_chk (__dest, __src, __sz / sizeof (wchar_t));
 90  return __wcpcpy_alias (__dest, __src);
 91}
 92
 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")
 99{
100  return __glibc_fortify_n (wcsncpy, __n, sizeof (wchar_t),
101			    __glibc_objsize (__dest),
102			    __dest, __src, __n);
103}
104
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")
111{
112  return __glibc_fortify_n (wcpncpy, __n, sizeof (wchar_t),
113			    __glibc_objsize (__dest),
114			    __dest, __src, __n);
115}
116
117__fortify_function __attribute_overloadable__ wchar_t *
118__NTH (wcscat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest),
119	       const wchar_t *__restrict __src))
120{
121  size_t __sz = __glibc_objsize (__dest);
122  if (__sz != (size_t) -1)
123    return __wcscat_chk (__dest, __src, __sz / sizeof (wchar_t));
124  return __wcscat_alias (__dest, __src);
125}
126
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))
130{
131  size_t __sz = __glibc_objsize (__dest);
132  if (__sz != (size_t) -1)
133    return __wcsncat_chk (__dest, __src, __n, __sz / sizeof (wchar_t));
134  return __wcsncat_alias (__dest, __src, __n);
135}
136
137#ifdef __USE_MISC
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")
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
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))
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 */
167
168#ifdef __va_arg_pack
169__fortify_function int
170__NTH (swprintf (wchar_t *__restrict __s, size_t __n,
171		 const wchar_t *__restrict __fmt, ...))
172{
173  size_t __sz = __glibc_objsize (__s);
174  if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
175    return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
176			   __sz / sizeof (wchar_t), __fmt, __va_arg_pack ());
177  return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
178}
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}
196#elif !defined __cplusplus
197/* XXX We might want to have support in gcc for swprintf.  */
198# define swprintf(s, n, ...) \
199  (__glibc_objsize (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1		      \
200   ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1,			      \
201		     __glibc_objsize (s) / sizeof (wchar_t), __VA_ARGS__)	      \
202   : swprintf (s, n, __VA_ARGS__))
203#endif
204
205__fortify_function int
206__NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
207		  const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
208{
209  size_t __sz = __glibc_objsize (__s);
210  if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
211    return __vswprintf_chk (__s, __n,  __USE_FORTIFY_LEVEL - 1,
212			    __sz / sizeof (wchar_t), __fmt, __ap);
213  return __vswprintf_alias (__s, __n, __fmt, __ap);
214}
215
216
217#if __USE_FORTIFY_LEVEL > 1
218
219# ifdef __va_arg_pack
220__fortify_function int
221wprintf (const wchar_t *__restrict __fmt, ...)
222{
223  return __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
224}
225
226__fortify_function int
227fwprintf (__FILE *__restrict __stream, const wchar_t *__restrict __fmt, ...)
228{
229  return __fwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
230			 __va_arg_pack ());
231}
232# elif !defined __cplusplus
233#  define wprintf(...) \
234  __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
235#  define fwprintf(stream, ...) \
236  __fwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
237# endif
238
239__fortify_function int
240vwprintf (const wchar_t *__restrict __fmt, __gnuc_va_list __ap)
241{
242  return __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap);
243}
244
245__fortify_function int
246vfwprintf (__FILE *__restrict __stream,
247	   const wchar_t *__restrict __fmt, __gnuc_va_list __ap)
248{
249  return __vfwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
250}
251
252#endif
253__fortify_function __attribute_overloadable__ __wur wchar_t *
254fgetws (__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")
259{
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);
263#if !__fortify_use_clang
264  if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz))
265    return __fgetws_chk_warn (__s, __sz / sizeof (wchar_t), __n, __stream);
266#endif
267  return __fgetws_chk (__s, __sz / sizeof (wchar_t), __n, __stream);
268}
269
270#ifdef __USE_GNU
271__fortify_function __attribute_overloadable__ __wur wchar_t *
272fgetws_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")
277{
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);
281# if !__fortify_use_clang
282  if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz))
283    return __fgetws_unlocked_chk_warn (__s, __sz / sizeof (wchar_t), __n,
284				       __stream);
285# endif
286  return __fgetws_unlocked_chk (__s, __sz / sizeof (wchar_t), __n, __stream);
287}
288#endif
289
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))
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
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));
304  return __wcrtomb_alias (__s, __wchar, __ps);
305}
306
307__fortify_function __attribute_overloadable__ size_t
308__NTH (mbsrtowcs (__fortify_clang_overload_arg (wchar_t *, __restrict, __dst),
309		  const char **__restrict __src,
310		  size_t __len, mbstate_t *__restrict __ps))
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)")
314{
315  return __glibc_fortify_n (mbsrtowcs, __len, sizeof (wchar_t),
316			    __glibc_objsize (__dst),
317			    __dst, __src, __len, __ps);
318}
319
320__fortify_function __attribute_overloadable__ size_t
321__NTH (wcsrtombs (__fortify_clang_overload_arg (char *, __restrict, __dst),
322		  const wchar_t **__restrict __src,
323		  size_t __len, mbstate_t *__restrict __ps))
324     __fortify_clang_warning_only_if_bos_lt (__len, __dst,
325					     "wcsrtombs called with dst buffer "
326					     "smaller than len")
327{
328  return __glibc_fortify (wcsrtombs, __len, sizeof (char),
329			  __glibc_objsize (__dst),
330			  __dst, __src, __len, __ps);
331}
332
333
334#ifdef	__USE_XOPEN2K8
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)")
342{
343  return __glibc_fortify_n (mbsnrtowcs, __len, sizeof (wchar_t),
344			    __glibc_objsize (__dst),
345			    __dst, __src, __nmc, __len, __ps);
346}
347
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")
355{
356  return __glibc_fortify (wcsnrtombs, __len, sizeof (char),
357			  __glibc_objsize (__dst),
358			  __dst, __src, __nwc, __len, __ps);
359}
360#endif