fortify-headers

standalone fortify-source implementation
git clone git://git.2f30.org/fortify-headers
Log | Files | Refs | README | LICENSE

wchar.h (7879B)


      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 	if ((__fh_size_t)__n > __b / sizeof(wchar_t))
     53 		__builtin_trap();
     54 	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 	__r = __orig_mbsrtowcs(__d, __s, __wn > __b ? __b : __wn, __st);
     96 	if (__b < __wn && __d && *__s && __r != (__fh_size_t)-1)
     97 		__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 	if (wcslen(__s) + wcslen(__d) + 1 > __b / sizeof(wchar_t))
    134 		__builtin_trap();
    135 	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 	if (wcslen(__s) + 1 > __b / sizeof(wchar_t))
    147 		__builtin_trap();
    148 	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 		__sl = wcslen(__s);
    162 		__dl = wcslen(__d);
    163 		if (__sl > __n)
    164 			__sl = __n;
    165 		if (__sl + __dl + 1 > __b / sizeof(wchar_t))
    166 			__builtin_trap();
    167 	}
    168 	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 		__builtin_trap();
    181 	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 	if (__n > __b / sizeof(wchar_t))
    236 		__builtin_trap();
    237 	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 	if (__n > __b / sizeof(wchar_t))
    249 		__builtin_trap();
    250 	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 	if (__n > __b / sizeof(wchar_t))
    262 		__builtin_trap();
    263 	return __orig_wmemset(__s, __c, __n);
    264 }
    265 
    266 #ifdef __cplusplus
    267 }
    268 #endif
    269 
    270 #endif
    271 
    272 #endif