changeset 6583:eb8d54cb67a4

Fix an incorrect estimation of the sprintf result size.
author Bruno Haible <bruno@clisp.org>
date Mon, 23 Jan 2006 15:01:57 +0000
parents 29fdf7a22b20
children b79b3ca35615
files lib/ChangeLog lib/vasnprintf.c
diffstat 2 files changed, 30 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,9 @@
+2006-01-22  Bruno Haible  <bruno@clisp.org>
+
+	* 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'.
+
 2006-01-22  Paul Eggert  <eggert@cs.ucla.edu>
 
 	* quotearg.c (quotearg_buffer_restyled): Add "default: break;"
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -1,5 +1,5 @@
 /* vsprintf with automatic memory allocation.
-   Copyright (C) 1999, 2002-2005 Free Software Foundation, Inc.
+   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
@@ -334,28 +334,28 @@
 			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 */
+			  + 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 */
-					  * 2 /* estimate for FLAG_GROUP */
 					 )
-			  + 1 /* turn floor into ceil */
-			  + 1; /* account for leading sign */
+			  + 1; /* turn floor into ceil */
 		      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 */
+			  + 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':
@@ -365,8 +365,7 @@
 			  (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
 					  * 0.333334 /* binary -> octal */
 					 )
-			  + 1 /* turn floor into ceil */
-			  + 1; /* account for leading sign */
+			  + 1; /* turn floor into ceil */
 		      else
 # endif
 		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
@@ -374,15 +373,17 @@
 			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT
 					  * 0.333334 /* binary -> octal */
 					 )
-			  + 1 /* turn floor into ceil */
-			  + 1; /* account for leading sign */
+			  + 1; /* turn floor into ceil */
 		      else
 			tmp_length =
 			  (unsigned int) (sizeof (unsigned int) * CHAR_BIT
 					  * 0.333334 /* binary -> octal */
 					 )
-			  + 1 /* turn floor into ceil */
-			  + 1; /* account for leading sign */
+			  + 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':
@@ -392,8 +393,7 @@
 			  (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 */
+			  + 1; /* turn floor into ceil */
 		      else
 # endif
 		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
@@ -401,15 +401,17 @@
 			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT
 					  * 0.25 /* binary -> hexadecimal */
 					 )
-			  + 1 /* turn floor into ceil */
-			  + 2; /* account for leading sign or alternate form */
+			  + 1; /* turn floor into ceil */
 		      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 */
+			  + 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':