+2007-03-17 Bruno Haible <bruno@clisp.org>
+
+ 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.
+
2007-03-17 Bruno Haible <bruno@clisp.org>
* tests/test-argp-2.sh (func_compare): Output a context diff.
{
char *output;
size_t len;
- size_t lenbuf = SIZE_MAX;
+ /* 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);
# 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
{
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
{
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) \
{ \
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);
{
char *output;
size_t len;
- size_t lenbuf = SIZE_MAX;
+ /* 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;