From 7c8322243bf4fe57a7f5d042182c1b5c541bdaeb Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 2 Jul 2007 00:56:18 +0000 Subject: Avoid address wraparound inside system functions. --- lib/vsprintf.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index a9d840d9c8..88e528db37 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "vasnprintf.h" @@ -46,9 +47,17 @@ vsprintf (char *str, const char *format, va_list args) { char *output; size_t len; + size_t lenbuf; + /* vasnprintf fails with EOVERFLOW when the buffer size argument is larger - than INT_MAX (if that fits into a 'size_t' at all). */ - size_t lenbuf = (SIZE_MAX < INT_MAX ? SIZE_MAX : INT_MAX); + than INT_MAX (if that fits into a 'size_t' at all). + Also note that glibc's iconv fails with E2BIG when we pass a length that + is so large that str + lenbuf wraps around, i.e. + (uintptr_t) (str + lenbuf) < (uintptr_t) str. + Therefore set lenbuf = min (SIZE_MAX, INT_MAX, - (uintptr_t) str - 1). */ + lenbuf = (SIZE_MAX < INT_MAX ? SIZE_MAX : INT_MAX); + if (lenbuf > ~ (uintptr_t) str) + lenbuf = ~ (uintptr_t) str; output = vasnprintf (str, &lenbuf, format, args); len = lenbuf; -- cgit v1.2.1