commit 9b796691eb794e9f5279886e917c028a09f8a728
parent ff82ffbc74d82091527449e31fe351d15830f716
Author: info@mobile-stream.com <info@mobile-stream.com>
Date: Wed, 6 Mar 2019 16:28:48 +0300
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:
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git 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
_FORTIFY_FN(wcrtomb) size_t wcrtomb(char *__s, wchar_t __w, mbstate_t *__st)
{
- char __buf[MB_LEN_MAX];
- size_t __b = __builtin_object_size(__s, 0);
- size_t __r;
+ if (__s && MB_LEN_MAX > __builtin_object_size(__s, 2)) {
+ char __buf[MB_LEN_MAX];
+ size_t __r;
- if (__s) {
__r = __orig_wcrtomb(__buf, __w, __st);
if (__r == (size_t)-1)
return __r;
- if (__r > __b)
+ if (__r > __builtin_object_size(__s, 0))
__builtin_trap();
__builtin_memcpy(__s, __buf, __r);
return __r;
@@ -218,7 +217,7 @@ _FORTIFY_FN(wctomb) int wctomb(char *__s, wchar_t __w)
{
size_t __b = __builtin_object_size(__s, 0);
- if (__s && MB_CUR_MAX > __b)
+ if (__s && MB_LEN_MAX > __b && MB_CUR_MAX > __b)
__builtin_trap();
return __orig_wctomb(__s, __w);
}