bug-gnulib
[Top][All Lists]
Advanced

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

fix in vasnprintf.c


From: Bruno Haible
Subject: fix in vasnprintf.c
Date: Mon, 23 Jan 2006 15:57:54 +0100
User-agent: KMail/1.5

Hi,

I committed this patch in lib/vasnprintf.c. Fixes a too low estimate of
the size of an sprintf result, leading to a buffer overflow. Fortunately
most platforms have either a snprintf() or _snprintf() function, and
lib/vasnprintf.c uses this if available. Otherwise it would have been
a security problem...

Bruno


2006-01-22  Bruno Haible  <address@hidden>

        * vasnprintf.c (VASNPRINTF): In the computation of the size of the
        temporary buffer for sprintf, take into account the precision also
        for 'd', 'i', 'u', 'o', 'x', 'X'.

*** lib/vasnprintf.c    Sat May 21 00:18:37 2005
--- lib/vasnprintf.c    Sun Jan 22 21:03:07 2006
***************
*** 1,5 ****
  /* vsprintf with automatic memory allocation.
!    Copyright (C) 1999, 2002-2005 Free Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU Library General Public License as published
--- 1,5 ----
  /* vsprintf with automatic memory allocation.
!    Copyright (C) 1999, 2002-2006 Free Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU Library General Public License as published
***************
*** 335,362 ****
                        tmp_length =
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
                                          * 0.30103 /* binary -> decimal */
-                                         * 2 /* estimate for FLAG_GROUP */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 1; /* account for leading sign */
                      else
  # endif
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
                        tmp_length =
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
                                          * 0.30103 /* binary -> decimal */
-                                         * 2 /* estimate for FLAG_GROUP */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 1; /* account for leading sign */
                      else
                        tmp_length =
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
                                          * 0.30103 /* binary -> decimal */
-                                         * 2 /* estimate for FLAG_GROUP */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 1; /* account for leading sign */
                      break;
  
                    case 'o':
--- 335,362 ----
                        tmp_length =
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
                                          * 0.30103 /* binary -> decimal */
                                         )
!                         + 1; /* turn floor into ceil */
                      else
  # endif
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
                        tmp_length =
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
                                          * 0.30103 /* binary -> decimal */
                                         )
!                         + 1; /* turn floor into ceil */
                      else
                        tmp_length =
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
                                          * 0.30103 /* binary -> decimal */
                                         )
!                         + 1; /* turn floor into ceil */
!                     if (tmp_length < precision)
!                       tmp_length = precision;
!                     /* Multiply by 2, as an estimate for FLAG_GROUP.  */
!                     tmp_length = xsum (tmp_length, tmp_length);
!                     /* Add 1, to account for a leading sign.  */
!                     tmp_length = xsum (tmp_length, 1);
                      break;
  
                    case 'o':
***************
*** 366,373 ****
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
                                          * 0.333334 /* binary -> octal */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 1; /* account for leading sign */
                      else
  # endif
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
--- 366,372 ----
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
                                          * 0.333334 /* binary -> octal */
                                         )
!                         + 1; /* turn floor into ceil */
                      else
  # endif
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
***************
*** 375,389 ****
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
                                          * 0.333334 /* binary -> octal */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 1; /* account for leading sign */
                      else
                        tmp_length =
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
                                          * 0.333334 /* binary -> octal */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 1; /* account for leading sign */
                      break;
  
                    case 'x': case 'X':
--- 374,390 ----
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
                                          * 0.333334 /* binary -> octal */
                                         )
!                         + 1; /* turn floor into ceil */
                      else
                        tmp_length =
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
                                          * 0.333334 /* binary -> octal */
                                         )
!                         + 1; /* turn floor into ceil */
!                     if (tmp_length < precision)
!                       tmp_length = precision;
!                     /* Add 1, to account for a leading sign.  */
!                     tmp_length = xsum (tmp_length, 1);
                      break;
  
                    case 'x': case 'X':
***************
*** 393,400 ****
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
                                          * 0.25 /* binary -> hexadecimal */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 2; /* account for leading sign or alternate form */
                      else
  # endif
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
--- 394,400 ----
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
                                          * 0.25 /* binary -> hexadecimal */
                                         )
!                         + 1; /* turn floor into ceil */
                      else
  # endif
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
***************
*** 402,416 ****
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
                                          * 0.25 /* binary -> hexadecimal */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 2; /* account for leading sign or alternate form */
                      else
                        tmp_length =
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
                                          * 0.25 /* binary -> hexadecimal */
                                         )
!                         + 1 /* turn floor into ceil */
!                         + 2; /* account for leading sign or alternate form */
                      break;
  
                    case 'f': case 'F':
--- 402,418 ----
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
                                          * 0.25 /* binary -> hexadecimal */
                                         )
!                         + 1; /* turn floor into ceil */
                      else
                        tmp_length =
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
                                          * 0.25 /* binary -> hexadecimal */
                                         )
!                         + 1; /* turn floor into ceil */
!                     if (tmp_length < precision)
!                       tmp_length = precision;
!                     /* Add 2, to account for a leading sign or alternate 
form.  */
!                     tmp_length = xsum (tmp_length, 2);
                      break;
  
                    case 'f': case 'F':





reply via email to

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