bug-gnulib
[Top][All Lists]
Advanced

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

Re: [bug-gnulib] snprintf fixes in gnulib


From: Bruno Haible
Subject: Re: [bug-gnulib] snprintf fixes in gnulib
Date: Mon, 28 Aug 2006 14:54:40 +0200
User-agent: KMail/1.9.1

Hi,

Paul Eggert noted that vasnprintf should be able to return strings of length
> INT_MAX. Here's a patch to that effect.

Yoann, is the vsnprintf.c patch OK with you? It corresponds to Paul's fixes
to snprintf.c a week ago.


2006-08-26  Bruno Haible  <address@hidden>

        * vasnprintf.c (EOVERFLOW): Remove definition.
        (VASNPRINTF): Return a string of length > INT_MAX without failing.
        * vasprintf.c: Include errno.h, limits.h.
        (EOVERFLOW): New fallback definition.
        (vasprintf): Test here whether the string length is > INT_MAX.
        * vsnprintf.c: Include errno.h, limits.h.
        (EOVERFLOW): New fallback definition.
        (vsnprintf): Fix bug when generated string was too long for the buffer.
        Test here whether the string length is > INT_MAX.

*** gnulib-20060823/lib/vasnprintf.c    2006-01-23 16:01:57.000000000 +0100
--- gnulib-20060823-modified/lib/vasnprintf.c   2006-08-26 22:43:23.000000000 
+0200
***************
*** 40,46 ****
  #include <stdlib.h>   /* abort(), malloc(), realloc(), free() */
  #include <string.h>   /* memcpy(), strlen() */
  #include <errno.h>    /* errno */
! #include <limits.h>   /* CHAR_BIT, INT_MAX */
  #include <float.h>    /* DBL_MAX_EXP, LDBL_MAX_EXP */
  #if WIDE_CHAR_VERSION
  # include "wprintf-parse.h"
--- 40,46 ----
  #include <stdlib.h>   /* abort(), malloc(), realloc(), free() */
  #include <string.h>   /* memcpy(), strlen() */
  #include <errno.h>    /* errno */
! #include <limits.h>   /* CHAR_BIT */
  #include <float.h>    /* DBL_MAX_EXP, LDBL_MAX_EXP */
  #if WIDE_CHAR_VERSION
  # include "wprintf-parse.h"
***************
*** 51,61 ****
  /* Checked size_t computations.  */
  #include "xsize.h"
  
- /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
- #ifndef EOVERFLOW
- # define EOVERFLOW E2BIG
- #endif
- 
  #ifdef HAVE_WCHAR_T
  # ifdef HAVE_WCSLEN
  #  define local_wcslen wcslen
--- 51,56 ----
***************
*** 869,887 ****
        free (buf_malloced);
      CLEANUP ();
      *lengthp = length;
!     if (length > INT_MAX)
!       goto length_overflow;
      return result;
  
-   length_overflow:
-     /* We could produce such a big string, but its length doesn't fit into
-        an 'int'.  POSIX says that snprintf() fails with errno = EOVERFLOW in
-        this case.  */
-     if (result != resultbuf)
-       free (result);
-     errno = EOVERFLOW;
-     return NULL;
- 
    out_of_memory:
      if (!(result == resultbuf || result == NULL))
        free (result);
--- 864,875 ----
        free (buf_malloced);
      CLEANUP ();
      *lengthp = length;
!     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
!        says that snprintf() fails with errno = EOVERFLOW in this case, but
!        that's only because snprintf() returns an 'int'.  This function does
!        not have this limitation.  */
      return result;
  
    out_of_memory:
      if (!(result == resultbuf || result == NULL))
        free (result);
*** gnulib-20060823/lib/vasprintf.c     2005-05-14 08:03:58.000000000 +0200
--- gnulib-20060823-modified/lib/vasprintf.c    2006-08-26 22:41:56.000000000 
+0200
***************
*** 1,5 ****
  /* Formatted output to strings.
!    Copyright (C) 1999, 2002 Free Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
--- 1,5 ----
  /* Formatted output to strings.
!    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 General Public License as published by
***************
*** 22,31 ****
--- 22,38 ----
  /* Specification.  */
  #include "vasprintf.h"
  
+ #include <errno.h>
+ #include <limits.h>
  #include <stdlib.h>
  
  #include "vasnprintf.h"
  
+ /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
+ #ifndef EOVERFLOW
+ # define EOVERFLOW E2BIG
+ #endif
+ 
  int
  vasprintf (char **resultp, const char *format, va_list args)
  {
***************
*** 34,42 ****
    if (result == NULL)
      return -1;
  
    *resultp = result;
!   /* Return the number of resulting bytes, excluding the trailing NUL.
!      If it wouldn't fit in an 'int', vasnprintf() would have returned NULL
!      and set errno to EOVERFLOW.  */
    return length;
  }
--- 41,54 ----
    if (result == NULL)
      return -1;
  
+   if (length > INT_MAX)
+     {
+       free (result);
+       errno = EOVERFLOW;
+       return -1;
+     }
+ 
    *resultp = result;
!   /* Return the number of resulting bytes, excluding the trailing NUL.  */
    return length;
  }
*** gnulib-20060823/lib/vsnprintf.c     2005-05-14 08:03:58.000000000 +0200
--- gnulib-20060823-modified/lib/vsnprintf.c    2006-08-26 22:36:24.000000000 
+0200
***************
*** 1,5 ****
  /* Formatted output to strings.
!    Copyright (C) 2004 Free Software Foundation, Inc.
     Written by Simon Josefsson and Yoann Vandoorselaere <address@hidden>.
  
     This program is free software; you can redistribute it and/or modify
--- 1,5 ----
  /* Formatted output to strings.
!    Copyright (C) 2004, 2006 Free Software Foundation, Inc.
     Written by Simon Josefsson and Yoann Vandoorselaere <address@hidden>.
  
     This program is free software; you can redistribute it and/or modify
***************
*** 23,28 ****
--- 23,30 ----
  /* Specification.  */
  #include "vsnprintf.h"
  
+ #include <errno.h>
+ #include <limits.h>
  #include <stdarg.h>
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 30,35 ****
--- 32,42 ----
  
  #include "vasnprintf.h"
  
+ /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
+ #ifndef EOVERFLOW
+ # define EOVERFLOW E2BIG
+ #endif
+ 
  /* Print formatted output to string STR.  Similar to vsprintf, but
     additional length SIZE limit how much is written into STR.  Returns
     string length of formatted string (which may be larger than SIZE).
***************
*** 40,58 ****
  {
    char *output;
    size_t len;
  
!   len = size;
!   output = vasnprintf (str, &len, format, args);
  
    if (!output)
      return -1;
  
-   if (str != NULL)
-     if (len > size - 1) /* equivalent to: (size > 0 && len >= size) */
-       str[size - 1] = '\0';
- 
    if (output != str)
!     free (output);
  
    return len;
  }
--- 47,77 ----
  {
    char *output;
    size_t len;
+   size_t lenbuf = size;
  
!   output = vasnprintf (str, &lenbuf, format, args);
!   len = lenbuf;
  
    if (!output)
      return -1;
  
    if (output != str)
!     {
!       if (size)
!       {
!         size_t pruned_len = (len < size ? len : size - 1);
!         memcpy (str, output, pruned_len);
!         str[pruned_len] = '\0';
!       }
! 
!       free (output);
!     }
! 
!   if (len > INT_MAX)
!     {
!       errno = EOVERFLOW;
!       return -1;
!     }
  
    return len;
  }




reply via email to

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