bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

another vasnprintf fix


From: Bruno Haible
Subject: another vasnprintf fix
Date: Tue, 20 Mar 2007 01:46:04 +0100
User-agent: KMail/1.5.4

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  <address@hidden>

        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);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]