1 /* Copyright (c) 2017 Yaakov Selkowitz <yselkowi@redhat.com> */
2 #ifndef _SSP_WCHAR_H_
3 #define _SSP_WCHAR_H_
4 
5 #include <sys/cdefs.h>
6 #include <ssp/ssp.h>
7 
8 #if __SSP_FORTIFY_LEVEL > 0
9 
10 /* wide character variant, __wlen is number of wchar_t */
11 #define __ssp_redirect_wc(rtype, fun, args, call, cond, bos) \
12 __ssp_decl(rtype, fun, args) \
13 { \
14 	if (cond) \
15 		__ssp_check(__buf, __wlen * sizeof(wchar_t), bos); \
16 	return __ssp_real_(fun) call; \
17 }
18 
19 #define __ssp_bos_wicheck3(fun) \
20 __ssp_redirect_wc(wchar_t *, fun, \
21     (wchar_t *__buf, const wchar_t *__src, size_t __wlen), \
22     (__buf, __src, __wlen), 1, __ssp_bos0)
23 
24 #define __ssp_bos_wicheck3_restrict(fun) \
25 __ssp_redirect_wc(wchar_t *, fun, \
26     (wchar_t *__restrict __buf, const wchar_t *__restrict __src, size_t __wlen), \
27     (__buf, __src, __wlen), 1, __ssp_bos0)
28 
29 #define __ssp_bos_wicheck2_restrict(fun) \
30 __ssp_decl(wchar_t *, fun, (wchar_t *__restrict __buf, const wchar_t *__restrict __src)) \
31 { \
32   __ssp_check(__buf, (wcslen(__src) + 1) * sizeof(wchar_t), __ssp_bos0); \
33   return __ssp_real_(fun) (__buf, __src); \
34 }
35 
36 __BEGIN_DECLS
37 #if __POSIX_VISIBLE >= 200809
__ssp_bos_wicheck2_restrict(wcpcpy)38 __ssp_bos_wicheck2_restrict(wcpcpy)
39 __ssp_bos_wicheck3_restrict(wcpncpy)
40 #endif
41 __ssp_bos_wicheck2_restrict(wcscpy)
42 __ssp_bos_wicheck2_restrict(wcscat)
43 __ssp_bos_wicheck3_restrict(wcsncpy)
44 __ssp_bos_wicheck3_restrict(wcsncat)
45 __ssp_bos_wicheck3_restrict(wmemcpy)
46 __ssp_bos_wicheck3(wmemmove)
47 #if __GNU_VISIBLE
48 __ssp_bos_wicheck3_restrict(wmempcpy)
49 #endif
50 __ssp_redirect_wc(wchar_t *, wmemset, \
51     (wchar_t *__buf, wchar_t __src, size_t __wlen), \
52     (__buf, __src, __wlen), 1, __ssp_bos0)
53 
54 __ssp_decl(size_t, wcrtomb, (char *__buf, wchar_t __src, mbstate_t *__ps))
55 {
56   if (__buf != NULL && __src != L'\0')
57     __ssp_check(__buf, sizeof(wchar_t), __ssp_bos);
58   return __ssp_real_wcrtomb (__buf, __src, __ps);
59 }
60 
61 __ssp_redirect_wc(size_t, mbsrtowcs, \
62     (wchar_t *__buf, const char **__src, size_t __wlen, mbstate_t *__ps), \
63     (__buf, __src, __wlen, __ps), __buf != NULL, __ssp_bos)
64 
65 __ssp_redirect_raw(size_t, wcsrtombs, \
66     (char *__buf, const wchar_t **__src, size_t __len, mbstate_t *__ps), \
67     (__buf, __src, __len, __ps), __buf != NULL, __ssp_bos)
68 
69 #if __POSIX_VISIBLE >= 200809
70 __ssp_redirect_wc(size_t, mbsnrtowcs, \
71     (wchar_t *__buf, const char **__src, size_t __nms, size_t __wlen, mbstate_t *__ps), \
72     (__buf, __src, __nms, __wlen, __ps), __buf != NULL, __ssp_bos)
73 
74 __ssp_redirect_raw(size_t, wcsnrtombs, \
75     (char *__buf, const wchar_t **__src, size_t __nwc, size_t __len, mbstate_t *__ps), \
76     (__buf, __src, __nwc, __len, __ps), __buf != NULL, __ssp_bos)
77 #endif
78 
79 __ssp_decl(wchar_t *, fgetws, (wchar_t *__restrict __buf, int __wlen, __FILE *__restrict __fp))
80 {
81   if (__wlen > 0)
82     __ssp_check(__buf, (size_t)__wlen * sizeof(wchar_t) , __ssp_bos);
83   return __ssp_real_fgetws(__buf, __wlen, __fp);
84 }
85 
86 #if __GNU_VISIBLE
87 __ssp_decl(wchar_t *, fgetws_unlocked, (wchar_t *__buf, int __wlen, __FILE *__fp))
88 {
89   if (__wlen > 0)
90     __ssp_check(__buf, (size_t)__wlen * sizeof(wchar_t) , __ssp_bos);
91   return __ssp_real_fgetws_unlocked(__buf, __wlen, __fp);
92 }
93 #endif /* __GNU_VISIBLE */
94 
95 __END_DECLS
96 
97 #endif /* __SSP_FORTIFY_LEVEL > 0 */
98 #endif /* _SSP_WCHAR_H_ */
99