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