bug-gnulib
[Top][All Lists]
Advanced

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

vasnprintf: fix buffer overrun


From: Bruno Haible
Subject: vasnprintf: fix buffer overrun
Date: Sun, 30 Mar 2008 17:29:29 +0100
User-agent: KMail/1.5.4

This fixes a buffer overrun on OSF/1 4.0 and Solaris 2.5. Nothing to worry
about for the majority of the platforms.


2008-03-30  Bruno Haible  <address@hidden>

        Fix buffer overrun.
        * lib/vasnprintf.c (VASNPRINTF): If !USE_SNPRINTF && pad_ourselves:
        Don't consider the width for tmp_length. Check count against tmp_length
        before doing the padding. Ensure enough allocation during padding.

*** lib/vasnprintf.c.orig       2008-03-30 17:47:26.000000000 +0200
--- lib/vasnprintf.c    2008-03-30 17:43:05.000000000 +0200
***************
*** 3656,3661 ****
--- 3656,3699 ----
                  }
  #endif
  
+               /* Decide whether to handle the precision ourselves.  */
+ #if NEED_PRINTF_UNBOUNDED_PRECISION
+               switch (dp->conversion)
+                 {
+                 case 'd': case 'i': case 'u':
+                 case 'o':
+                 case 'x': case 'X': case 'p':
+                   prec_ourselves = has_precision && (precision > 0);
+                   break;
+                 default:
+                   prec_ourselves = 0;
+                   break;
+                 }
+ #endif
+ 
+               /* Decide whether to perform the padding ourselves.  */
+ #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || 
NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
+               switch (dp->conversion)
+                 {
+ # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
+                 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
+                    to perform the padding after this conversion.  Functions
+                    with unistdio extensions perform the padding based on
+                    character count rather than element count.  */
+                 case 'c': case 's':
+ # endif
+ # if NEED_PRINTF_FLAG_ZERO
+                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
+                 case 'a': case 'A':
+ # endif
+                   pad_ourselves = 1;
+                   break;
+                 default:
+                   pad_ourselves = prec_ourselves;
+                   break;
+                 }
+ #endif
+ 
  #if !USE_SNPRINTF
                /* Allocate a temporary buffer of sufficient size for calling
                   sprintf.  */
***************
*** 3832,3849 ****
                      abort ();
                    }
  
  # if ENABLE_UNISTDIO
!                 /* Padding considers the number of characters, therefore the
!                    number of elements after padding may be
!                      > max (tmp_length, width)
!                    but is certainly
!                      <= tmp_length + width.  */
!                 tmp_length = xsum (tmp_length, width);
  # else
!                 /* Padding considers the number of elements, says POSIX.  */
!                 if (tmp_length < width)
!                   tmp_length = width;
  # endif
  
                  tmp_length = xsum (tmp_length, 1); /* account for trailing 
NUL */
                }
--- 3870,3891 ----
                      abort ();
                    }
  
+                 if (!pad_ourselves)
+                   {
  # if ENABLE_UNISTDIO
!                     /* Padding considers the number of characters, therefore
!                        the number of elements after padding may be
!                          > max (tmp_length, width)
!                        but is certainly
!                          <= tmp_length + width.  */
!                     tmp_length = xsum (tmp_length, width);
  # else
!                     /* Padding considers the number of elements,
!                        says POSIX.  */
!                     if (tmp_length < width)
!                       tmp_length = width;
  # endif
+                   }
  
                  tmp_length = xsum (tmp_length, 1); /* account for trailing 
NUL */
                }
***************
*** 3864,3907 ****
                  }
  #endif
  
-               /* Decide whether to handle the precision ourselves.  */
- #if NEED_PRINTF_UNBOUNDED_PRECISION
-               switch (dp->conversion)
-                 {
-                 case 'd': case 'i': case 'u':
-                 case 'o':
-                 case 'x': case 'X': case 'p':
-                   prec_ourselves = has_precision && (precision > 0);
-                   break;
-                 default:
-                   prec_ourselves = 0;
-                   break;
-                 }
- #endif
- 
-               /* Decide whether to perform the padding ourselves.  */
- #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || 
NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
-               switch (dp->conversion)
-                 {
- # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
-                 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
-                    to perform the padding after this conversion.  Functions
-                    with unistdio extensions perform the padding based on
-                    character count rather than element count.  */
-                 case 'c': case 's':
- # endif
- # if NEED_PRINTF_FLAG_ZERO
-                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
-                 case 'a': case 'A':
- # endif
-                   pad_ourselves = 1;
-                   break;
-                 default:
-                   pad_ourselves = prec_ourselves;
-                   break;
-                 }
- #endif
- 
                /* Construct the format string for calling snprintf or
                   sprintf.  */
                fbp = buf;
--- 3906,3911 ----
***************
*** 4398,4411 ****
                      }
  #endif
  
! #if !DCHAR_IS_TCHAR
! # if !USE_SNPRINTF
                    if (count >= tmp_length)
                      /* tmp_length was incorrectly calculated - fix the
                         code above!  */
                      abort ();
! # endif
  
                    /* Convert from TCHAR_T[] to DCHAR_T[].  */
                    if (dp->conversion == 'c' || dp->conversion == 's')
                      {
--- 4402,4415 ----
                      }
  #endif
  
! #if !USE_SNPRINTF
                    if (count >= tmp_length)
                      /* tmp_length was incorrectly calculated - fix the
                         code above!  */
                      abort ();
! #endif
  
+ #if !DCHAR_IS_TCHAR
                    /* Convert from TCHAR_T[] to DCHAR_T[].  */
                    if (dp->conversion == 'c' || dp->conversion == 's')
                      {
***************
*** 4523,4529 ****
                        if (w < width)
                          {
                            size_t pad = width - w;
! # if USE_SNPRINTF
                            /* Make room for the result.  */
                            if (xsum (count, pad) > allocated - length)
                              {
--- 4527,4533 ----
                        if (w < width)
                          {
                            size_t pad = width - w;
! 
                            /* Make room for the result.  */
                            if (xsum (count, pad) > allocated - length)
                              {
***************
*** 4533,4544 ****
                                  xmax (xsum3 (length, count, pad),
                                        xtimes (allocated, 2));
  
                                length += count;
                                ENSURE_ALLOCATION (n);
                                length -= count;
                              }
                            /* Here count + pad <= allocated - length.  */
! # endif
                            {
  # if !DCHAR_IS_TCHAR || USE_SNPRINTF
                              DCHAR_T * const rp = result + length;
--- 4537,4552 ----
                                  xmax (xsum3 (length, count, pad),
                                        xtimes (allocated, 2));
  
+ # if USE_SNPRINTF
                                length += count;
                                ENSURE_ALLOCATION (n);
                                length -= count;
+ # else
+                               ENSURE_ALLOCATION (n);
+ # endif
                              }
                            /* Here count + pad <= allocated - length.  */
! 
                            {
  # if !DCHAR_IS_TCHAR || USE_SNPRINTF
                              DCHAR_T * const rp = result + length;
***************
*** 4599,4611 ****
                      }
  #endif
  
- #if DCHAR_IS_TCHAR && !USE_SNPRINTF
-                   if (count >= tmp_length)
-                     /* tmp_length was incorrectly calculated - fix the
-                        code above!  */
-                     abort ();
- #endif
- 
                    /* Here still count <= allocated - length.  */
  
  #if !DCHAR_IS_TCHAR || USE_SNPRINTF
--- 4607,4612 ----





reply via email to

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