Performing the unit tests on NetBSD 3.0 uncovered this: When the "size of given buffer" argument passed to vasnprintf() was > INT_MAX, the function could loop endlessly instead of failing with EOVERFLOW.
Note: NetBSD also has a bug here: snprintf() returns -1 with errno = EINVAL, where POSIX says that it should return -1 with errno = EOVERFLOW. 2007-03-17 Bruno Haible <[EMAIL PROTECTED]> Fix endless loop when the given allocated size was > INT_MAX. * lib/vasnprintf.c (EOVERFLOW): New fallback definition. (VASNPRINTF): Fail with EOVERFLOW when the given allocated size is larger than INT_MAX, or when it grow to a value larger than INT_MAX. * lib/vsprintf.c (vsprintf): Don't pass a size > INT_MAX to vasnprintf. * lib/sprintf.c (sprintf): Likewise. *** lib/vasnprintf.c 17 Mar 2007 20:07:01 -0000 1.29 --- lib/vasnprintf.c 18 Mar 2007 00:26:47 -0000 *************** *** 59,64 **** --- 62,72 ---- # endif #endif + /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ + #ifndef EOVERFLOW + # define EOVERFLOW E2BIG + #endif + #if HAVE_WCHAR_T # if HAVE_WCSLEN # define local_wcslen wcslen *************** *** 179,184 **** --- 187,196 ---- { result = resultbuf; allocated = *lengthp; + /* POSIX says that snprintf() fails with EOVERFLOW when the specified + buffer size is larger than INT_MAX. Let's do the same here. */ + if (allocated > INT_MAX) + goto overflow; } else { *************** *** 1107,1112 **** --- 1133,1141 ---- retcount = 0; #if USE_SNPRINTF + /* SNPRINTF can fail if maxlen > INT_MAX. */ + if (maxlen > INT_MAX) + goto overflow; # define SNPRINTF_BUF(arg) \ switch (prefix_count) \ { \ *************** *** 1382,1387 **** --- 1411,1425 ---- not have this limitation. */ return result; + overflow: + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EOVERFLOW; + return NULL; + out_of_memory: if (!(result == resultbuf || result == NULL)) free (result); *** lib/vsprintf.c 8 Mar 2007 03:24:38 -0000 1.2 --- lib/vsprintf.c 18 Mar 2007 00:26:47 -0000 *************** *** 46,52 **** { char *output; size_t len; ! size_t lenbuf = SIZE_MAX; output = vasnprintf (str, &lenbuf, format, args); len = lenbuf; --- 46,54 ---- { char *output; size_t len; ! /* 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); output = vasnprintf (str, &lenbuf, format, args); len = lenbuf; *** lib/sprintf.c 8 Mar 2007 03:24:38 -0000 1.2 --- lib/sprintf.c 18 Mar 2007 00:26:47 -0000 *************** *** 46,52 **** { char *output; size_t len; ! size_t lenbuf = SIZE_MAX; va_list args; va_start (args, format); --- 46,54 ---- { char *output; size_t len; ! /* 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); va_list args; va_start (args, format);