summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinfo@mobile-stream.com2019-03-06 16:28:48 +0300
committersin2019-03-07 00:05:34 +0000
commit9b796691eb794e9f5279886e917c028a09f8a728 (patch)
tree74bba58483d903c2aa83b8c920784d7bb5e2f6ba
parentff82ffbc74d82091527449e31fe351d15830f716 (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).
-rw-r--r--include/wchar.h11
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}