diff options
| author | info@mobile-stream.com | 2019-03-06 16:28:48 +0300 |
|---|---|---|
| committer | sin | 2019-03-07 00:05:34 +0000 |
| commit | 9b796691eb794e9f5279886e917c028a09f8a728 (patch) | |
| tree | 74bba58483d903c2aa83b8c920784d7bb5e2f6ba /include/wchar.h | |
| parent | ff82ffbc74d82091527449e31fe351d15830f716 (diff) | |
wctomb, wcrtomb: guard slow/trap path with MB_LEN_MAX
This allows the compiler to optimize out the slow/trap path at all
for the typical correct code:
char buf[MB_LEN_MAX];
r = wctomb(buf, c);
The change tries to keep the "unknown object size" case handling in
wcrtomb() as is even if it seems redundant and not helping (we copy
__buf to possibly undersized __s in any case) and inconsistent with
wctomb() (where we let the original library method itself overwrite
the possibly undersized __s).
Diffstat (limited to '')
| -rw-r--r-- | include/wchar.h | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/include/wchar.h b/include/wchar.h index 09ffa97..c5d0e5d 100644 --- a/include/wchar.h +++ b/include/wchar.h | |||
| @@ -111,15 +111,14 @@ _FORTIFY_FN(mbstowcs) size_t mbstowcs(wchar_t *__ws, const char *__s, size_t __w | |||
| 111 | 111 | ||
| 112 | _FORTIFY_FN(wcrtomb) size_t wcrtomb(char *__s, wchar_t __w, mbstate_t *__st) | 112 | _FORTIFY_FN(wcrtomb) size_t wcrtomb(char *__s, wchar_t __w, mbstate_t *__st) |
| 113 | { | 113 | { |
| 114 | char __buf[MB_LEN_MAX]; | 114 | if (__s && MB_LEN_MAX > __builtin_object_size(__s, 2)) { |
| 115 | size_t __b = __builtin_object_size(__s, 0); | 115 | char __buf[MB_LEN_MAX]; |
| 116 | size_t __r; | 116 | size_t __r; |
| 117 | 117 | ||
| 118 | if (__s) { | ||
| 119 | __r = __orig_wcrtomb(__buf, __w, __st); | 118 | __r = __orig_wcrtomb(__buf, __w, __st); |
| 120 | if (__r == (size_t)-1) | 119 | if (__r == (size_t)-1) |
| 121 | return __r; | 120 | return __r; |
| 122 | if (__r > __b) | 121 | if (__r > __builtin_object_size(__s, 0)) |
| 123 | __builtin_trap(); | 122 | __builtin_trap(); |
| 124 | __builtin_memcpy(__s, __buf, __r); | 123 | __builtin_memcpy(__s, __buf, __r); |
| 125 | return __r; | 124 | return __r; |
| @@ -218,7 +217,7 @@ _FORTIFY_FN(wctomb) int wctomb(char *__s, wchar_t __w) | |||
| 218 | { | 217 | { |
| 219 | size_t __b = __builtin_object_size(__s, 0); | 218 | size_t __b = __builtin_object_size(__s, 0); |
| 220 | 219 | ||
| 221 | if (__s && MB_CUR_MAX > __b) | 220 | if (__s && MB_LEN_MAX > __b && MB_CUR_MAX > __b) |
| 222 | __builtin_trap(); | 221 | __builtin_trap(); |
| 223 | return __orig_wctomb(__s, __w); | 222 | return __orig_wctomb(__s, __w); |
| 224 | } | 223 | } |
