changeset 9371:8b3c48038257

Don't report an unjustified overflow error.
author Bruno Haible <bruno@clisp.org>
date Sat, 20 Oct 2007 14:56:19 +0200
parents 4e720cd88140
children 091bbc680bf8
files ChangeLog lib/vasnprintf.c
diffstat 2 files changed, 26 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-10-20  Bruno Haible  <bruno@clisp.org>
+
+	* lib/vasnprintf.c (VASNPRINTF): Don't report overflow if the available
+	length is INT_MAX and sizeof (DCHAR_T) > sizeof (TCHAR_T).
+	Reported by Ralf Wildenhues <Ralf.Wildenhues@gmx.de>.
+
 2007-10-20  Bruno Haible  <bruno@clisp.org>
 
 	* tests/test-floorf2.c (correct_result_p): Don't rely on excess
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -3442,7 +3442,7 @@
 		    /* SNPRINTF can fail if its second argument is
 		       > INT_MAX.  */
 		    if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
-		      goto overflow;
+		      maxlen = INT_MAX / TCHARS_PER_DCHAR;
 		    maxlen = maxlen * TCHARS_PER_DCHAR;
 # define SNPRINTF_BUF(arg) \
 		    switch (prefix_count)				    \
@@ -3663,17 +3663,26 @@
 		    /* Handle overflow of the allocated buffer.  */
 		    if (count >= maxlen)
 		      {
-			/* Need at least count * sizeof (TCHAR_T) bytes.  But
-			   allocate proportionally, to avoid looping eternally
-			   if snprintf() reports a too small count.  */
-			size_t n =
-			  xmax (xsum (length,
-				      (count + TCHARS_PER_DCHAR - 1)
-				      / TCHARS_PER_DCHAR),
-				xtimes (allocated, 2));
+			/* If maxlen already has attained its allowed maximum,
+			   allocating more memory will not increase maxlen.
+			   Instead of looping, bail out.  */
+			if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
+			  goto overflow;
+			else
+			  {
+			    /* Need at least count * sizeof (TCHAR_T) bytes.
+			       But allocate proportionally, to avoid looping
+			       eternally if snprintf() reports a too small
+			       count.  */
+			    size_t n =
+			      xmax (xsum (length,
+					  (count + TCHARS_PER_DCHAR - 1)
+					  / TCHARS_PER_DCHAR),
+				    xtimes (allocated, 2));
 
-			ENSURE_ALLOCATION (n);
-			continue;
+			    ENSURE_ALLOCATION (n);
+			    continue;
+			  }
 		      }
 #endif